Example #1
0
Vector<Vector3> ConcavePolygonShape::_gen_debug_mesh_lines() {

	Set<DrawEdge> edges;

	PoolVector<Vector3> data=get_faces();
	int datalen=data.size();
	ERR_FAIL_COND_V( (datalen%3)!=0,Vector<Vector3>() );

	PoolVector<Vector3>::Read r=data.read();

	for(int i=0;i<datalen;i+=3) {

		for(int j=0;j<3;j++) {

			DrawEdge de(r[i+j],r[i+((j+1)%3)]);
			edges.insert(de);
		}

	}

	Vector<Vector3> points;
	points.resize(edges.size()*2);
	int idx=0;
	for (Set<DrawEdge>::Element*E=edges.front();E;E=E->next()) {

		points[idx+0]=E->get().a;
		points[idx+1]=E->get().b;
		idx+=2;
	}

	return points;

}
void VisualScriptPropertySelector::get_visual_node_names(const String &root_filter, const Set<String> &filter, bool &found, TreeItem *const root, LineEdit *const search_box) {
	Map<String, TreeItem *> path_cache;

	List<String> fnodes;
	VisualScriptLanguage::singleton->get_registered_node_names(&fnodes);

	for (List<String>::Element *E = fnodes.front(); E; E = E->next()) {
		if (!E->get().begins_with(root_filter)) {
			continue;
		}
		Vector<String> path = E->get().split("/");
		bool is_filter = false;
		for (Set<String>::Element *F = filter.front(); F; F = F->next()) {
			if (path.size() >= 2 && path[1].findn(F->get()) != -1) {
				is_filter = true;
				break;
			}
		}
		if (is_filter) {
			continue;
		}

		if (search_box->get_text() != String() && E->get().findn(search_box->get_text()) == -1) {
			continue;
		}
		TreeItem *item = search_options->create_item(root);
		VisualScriptOperator *vnode_operator = Object::cast_to<VisualScriptOperator>(*VisualScriptLanguage::singleton->create_node_from_name(E->get()));
		String type_name;
		if (vnode_operator != NULL) {
			String type;
			if (path.size() >= 2) {
				type = path[1];
			}
			type_name = type.capitalize() + " ";
		}
		VisualScriptFunctionCall *vnode_function_call = Object::cast_to<VisualScriptFunctionCall>(*VisualScriptLanguage::singleton->create_node_from_name(E->get()));
		if (vnode_function_call != NULL) {
			String basic_type = Variant::get_type_name(vnode_function_call->get_basic_type());
			type_name = basic_type.capitalize() + " ";
		}

		Vector<String> desc = path[path.size() - 1].replace("(", "( ").replace(")", " )").replace(",", ", ").split(" ");
		for (int i = 0; i < desc.size(); i++) {
			desc.write[i] = desc[i].capitalize();
			if (desc[i].ends_with(",")) {
				desc.write[i] = desc[i].replace(",", ", ");
			}
		}

		item->set_text(0, type_name + String("").join(desc));
		item->set_icon(0, get_icon("VisualScript", "EditorIcons"));
		item->set_selectable(0, true);
		item->set_metadata(0, E->get());
		item->set_selectable(0, true);
		item->set_metadata(1, "visualscript");
		item->set_selectable(1, false);
		item->set_selectable(2, false);
		item->set_metadata(2, connecting);
	}
}
Example #3
0
static Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) {

	Set<String> file_paths;

	// check children

	for (int i = 0; i < p_dir->get_file_count(); i++) {
		String file_name = p_dir->get_file(i);
		String file_type = p_dir->get_file_type(i);

		if (file_type != "GDNativeLibrary") {
			continue;
		}

		Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i));
		if (lib.is_valid() && lib->is_singleton()) {
			file_paths.insert(p_dir->get_file_path(i));
		}
	}

	// check subdirectories
	for (int i = 0; i < p_dir->get_subdir_count(); i++) {
		Set<String> paths = get_gdnative_singletons(p_dir->get_subdir(i));

		for (Set<String>::Element *E = paths.front(); E; E = E->next()) {
			file_paths.insert(E->get());
		}
	}

	return file_paths;
}
Example #4
0
void RotatedFileLogger::clear_old_backups() {
	int max_backups = max_files - 1; // -1 for the current file

	String basename = base_path.get_file().get_basename();
	String extension = "." + base_path.get_extension();

	DirAccess *da = DirAccess::open(base_path.get_base_dir());
	if (!da) {
		return;
	}

	da->list_dir_begin();
	String f = da->get_next();
	Set<String> backups;
	while (f != String()) {
		if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path.get_file()) {
			backups.insert(f);
		}
		f = da->get_next();
	}
	da->list_dir_end();

	if (backups.size() > max_backups) {
		// since backups are appended with timestamp and Set iterates them in sorted order,
		// first backups are the oldest
		int to_delete = backups.size() - max_backups;
		for (Set<String>::Element *E = backups.front(); E && to_delete > 0; E = E->next(), --to_delete) {
			da->remove(E->get());
		}
	}

	memdelete(da);
}
Example #5
0
void ProjectExportDialog::_update_feature_list() {

	Ref<EditorExportPreset> current = EditorExport::get_singleton()->get_export_preset(presets->get_current());
	ERR_FAIL_COND(current.is_null());

	Set<String> fset;
	List<String> features;

	current->get_platform()->get_platform_features(&features);
	current->get_platform()->get_preset_features(current, &features);

	String custom = current->get_custom_features();
	Vector<String> custom_list = custom.split(",");
	for (int i = 0; i < custom_list.size(); i++) {
		String f = custom_list[i].strip_edges();
		if (f != String()) {
			features.push_back(f);
		}
	}

	for (List<String>::Element *E = features.front(); E; E = E->next()) {
		fset.insert(E->get());
	}

	custom_feature_display->clear();
	for (Set<String>::Element *E = fset.front(); E; E = E->next()) {
		String f = E->get();
		if (E->next()) {
			f += ", ";
		}
		custom_feature_display->add_text(f);
	}
}
void DependencyRemoveDialog::_fill_owners(EditorFileSystemDirectory *efsd) {

	if (!efsd)
		return;

	for(int i=0;i<efsd->get_subdir_count();i++) {
		_fill_owners(efsd->get_subdir(i));
	}

	for(int i=0;i<efsd->get_file_count();i++) {

		Vector<String> deps = efsd->get_file_deps(i);
		//print_line(":::"+efsd->get_file_path(i));
		Set<String> met;
		for(int j=0;j<deps.size();j++) {
			if (files.has(deps[j])) {
				met.insert(deps[j]);
			}
		}
		if (!met.size())
			continue;

		exist=true;

		Ref<Texture> icon;
		String type=efsd->get_file_type(i);
		if (!has_icon(type,TTR("EditorIcons"))) {
			icon=get_icon("Object","EditorIcons");
		} else {
			icon=get_icon(type,"EditorIcons");
		}


		for(Set<String>::Element *E=met.front();E;E=E->next()) {

			String which = E->get();
			if (!files[which]) {
				TreeItem *ti=owners->create_item(owners->get_root());
				ti->set_text(0,which.get_file());
				files[which]=ti;

			}
			TreeItem *ti=owners->create_item(files[which]);
			ti->set_text(0,efsd->get_file_path(i));
			ti->set_icon(0,icon);
		}

	}

}
Example #7
0
void Theme::get_type_list(List<StringName> *p_list) const {

    Set<StringName> types;

    const StringName *key=NULL;

    while((key=icon_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=style_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=font_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=color_map.next(key))) {

        types.insert(*key);
    }

    key=NULL;

    while((key=constant_map.next(key))) {

        types.insert(*key);
    }


    for(Set<StringName>::Element *E=types.front(); E; E=E->next()) {

        p_list->push_back(E->get());
    }
}
Example #8
0
void NativeScript::get_script_method_list(List<MethodInfo> *p_list) const {
	NativeScriptDesc *script_data = get_script_desc();

	if (!script_data)
		return;

	Set<MethodInfo> methods;

	while (script_data) {

		for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
			methods.insert(E->get().info);
		}

		script_data = script_data->base_data;
	}

	for (Set<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
		p_list->push_back(E->get());
	}
}
void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) {

	if (!bool(EditorSettings::get_singleton()->get("external_editor/use_external_editor")))
		return;

	Set<Ref<Script> > scripts;

	Node *base = get_tree()->get_edited_scene_root();
	if (base) {
		_find_changed_scripts_for_external_editor(base,base,scripts);
	}

	for (Set<Ref<Script> >::Element *E=scripts.front();E;E=E->next()) {

		Ref<Script> script = E->get();

		if (p_for_script.is_valid() && p_for_script!=script)
			continue;

		if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) {

			continue; //internal script, who cares, though weird
		}

		uint64_t last_date = script->get_last_modified_time();
		uint64_t date = FileAccess::get_modified_time(script->get_path());

		if (last_date!=date) {

			Ref<Script> rel_script = ResourceLoader::load(script->get_path(),script->get_type(),true);
			ERR_CONTINUE(!rel_script.is_valid());
			script->set_source_code( rel_script->get_source_code() );
			script->set_last_modified_time( rel_script->get_last_modified_time() );
			script->update_exports();
		}

	}
}
Example #10
0
void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags) {

	// TODO right now there is no way to stop the export process with an error

	ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized());
	ERR_FAIL_NULL(TOOLS_DOMAIN);
	ERR_FAIL_NULL(GDMono::get_singleton()->get_editor_tools_assembly());

	if (FileAccess::exists(GodotSharpDirs::get_project_sln_path())) {
		String build_config = p_debug ? "Debug" : "Release";

		String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata." + String(p_debug ? "debug" : "release"));
		Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path);
		ERR_FAIL_COND(metadata_err != OK);

		ERR_FAIL_COND(!_add_file(scripts_metadata_path, scripts_metadata_path));

		// Turn export features into defines
		Vector<String> godot_defines;
		for (Set<String>::Element *E = p_features.front(); E; E = E->next()) {
			godot_defines.push_back(E->get());
		}
		ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config, godot_defines));

		// Add dependency assemblies

		Map<String, String> dependencies;

		String project_dll_name = ProjectSettings::get_singleton()->get("application/config/name");
		if (project_dll_name.empty()) {
			project_dll_name = "UnnamedProject";
		}

		String project_dll_src_dir = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config);
		String project_dll_src_path = project_dll_src_dir.plus_file(project_dll_name + ".dll");
		dependencies.insert(project_dll_name, project_dll_src_path);

		{
			MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain");
			ERR_FAIL_NULL(export_domain);
			_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);

			_GDMONO_SCOPE_DOMAIN_(export_domain);

			GDMonoAssembly *scripts_assembly = NULL;
			bool load_success = GDMono::get_singleton()->load_assembly_from(project_dll_name,
					project_dll_src_path, &scripts_assembly, /* refonly: */ true);

			ERR_EXPLAIN("Cannot load refonly assembly: " + project_dll_name);
			ERR_FAIL_COND(!load_success);

			Vector<String> search_dirs;
			GDMonoAssembly::fill_search_dirs(search_dirs, build_config);
			Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies);
			ERR_FAIL_COND(depend_error != OK);
		}

		for (Map<String, String>::Element *E = dependencies.front(); E; E = E->next()) {
			String depend_src_path = E->value();
			String depend_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(depend_src_path.get_file());
			ERR_FAIL_COND(!_add_file(depend_src_path, depend_dst_path));
		}
	}

	// Mono specific export template extras (data dir)

	GDMonoClass *export_class = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Editor", "GodotSharpExport");
	ERR_FAIL_NULL(export_class);
	GDMonoMethod *export_begin_method = export_class->get_method("_ExportBegin", 4);
	ERR_FAIL_NULL(export_begin_method);

	MonoArray *features = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_features.size());
	int i = 0;
	for (const Set<String>::Element *E = p_features.front(); E; E = E->next()) {
		MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get());
		mono_array_set(features, MonoString *, i, boxed);
		i++;
	}

	MonoBoolean debug = p_debug;
	MonoString *path = GDMonoMarshal::mono_string_from_godot(p_path);
	uint32_t flags = p_flags;
	void *args[4] = { features, &debug, path, &flags };
	MonoException *exc = NULL;
	export_begin_method->invoke_raw(NULL, args, &exc);

	if (exc) {
		GDMonoUtils::debug_print_unhandled_exception(exc);
		ERR_FAIL();
	}
}
Example #11
0
MainLoop * test() {


	/*
	HashMap<int,int> int_map;

	for (int i=0;i<68000;i++) {

		int num=(int)Math::random(0,1024);
		int_map[i]=num;
	}
	*/


	{

//		static const int size = 16;
		Image img;
		img.create(default_mouse_cursor_xpm);

		{
			for (int i=0; i<8; i++) {

				Image mipmap;
				//img.make_mipmap(mipmap);
				img = mipmap;
				if (img.get_width() <= 4) break;
			};
		};

	};

#if 0
	Set<int> set;

	print_line("Begin Insert");
	for (int i=0;i<1100;i++) {

		int num=i;//(int)Math::random(0,1024);
	//	print_line("inserting "+itos(num));
		set.insert( num );
	}

	/*
	for (int i=0;i<400;i++) {

		int num=(int)Math::random(0,1024);
		set.erase(num);
	}
	*/
	//set.print_tree();

	for(Set<int>::Element *I=set.front();I;I=I->next()) {

		print_line("inserted "+itos(I->get())+" prev is "+itos(I->prev()?I->prev()->get():-100));

	}

	print_line("depth is "+itos(set.calculate_depth()));
	print_line("Insert Success");
#endif

	return NULL;
}
Example #12
0
Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const {


	Set<StringName> exported;

	if (FileAccess::exists("res://engine.cfg"))
		exported.insert("res://engine.cfg");

	if (EditorImportExport::get_singleton()->get_export_filter()!=EditorImportExport::EXPORT_SELECTED) {

		String filter;
		if (EditorImportExport::get_singleton()->get_export_filter()==EditorImportExport::EXPORT_ALL) {
			_add_filter_to_list(exported,"*");
		} else {
			_add_to_list(EditorFileSystem::get_singleton()->get_filesystem(),exported);
			_add_filter_to_list(exported,EditorImportExport::get_singleton()->get_export_custom_filter());

		}


	} else {


		Map<String,Map<String,String> > remapped_paths;

		Set<String> scene_extensions;
		Set<String> resource_extensions;

		{

			List<String> l;
	//		SceneLoader::get_recognized_extensions(&l);
	//		for(List<String>::Element *E=l.front();E;E=E->next()) {
	//
	//			scene_extensions.insert(E->get());
	//		}
			ResourceLoader::get_recognized_extensions_for_type("",&l);
			for(List<String>::Element *E=l.front();E;E=E->next()) {

				resource_extensions.insert(E->get());
			}
		}


		List<StringName> toexport;

		EditorImportExport::get_singleton()->get_export_file_list(&toexport);

		print_line("TO EXPORT: "+itos(toexport.size()));


		for (List<StringName>::Element *E=toexport.front();E;E=E->next()) {

			print_line("DEP: "+String(E->get()));
			exported.insert(E->get());
			if (p_bundles && EditorImportExport::get_singleton()->get_export_file_action(E->get())==EditorImportExport::ACTION_BUNDLE) {
				print_line("NO BECAUSE OF BUNDLE!");
				continue; //no dependencies needed to be copied
			}

			List<String> testsubs;
			testsubs.push_back(E->get());

			while(testsubs.size()) {
				//recursive subdep search!
				List<String> deplist;
				ResourceLoader::get_dependencies(testsubs.front()->get(),&deplist);
				testsubs.pop_front();

				List<String> subdeps;

				for (List<String>::Element *F=deplist.front();F;F=F->next()) {

					StringName dep = F->get();

					if (exported.has(dep) || EditorImportExport::get_singleton()->get_export_file_action(dep)!=EditorImportExport::ACTION_NONE)
						continue; //dependency added or to be added
					print_line(" SUBDEP: "+String(dep));

					exported.insert(dep);
					testsubs.push_back(dep);
				}
			}
		}

		_add_filter_to_list(exported,EditorImportExport::get_singleton()->get_export_custom_filter());

	}

	Vector<StringName> ret;
	ret.resize(exported.size());


	int idx=0;
	for(Set<StringName>::Element *E=exported.front();E;E=E->next()) {

		ret[idx++]=E->get();

	}

	SortArray<StringName,__EESortDepCmp> sort; //some platforms work better if this is sorted
	sort.sort(ret.ptr(),ret.size());

	return ret;

}
Example #13
0
void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {

	Object *obj = ObjectDB::get_instance(p_id);
	if (!obj)
		return;

	typedef Pair<PropertyInfo, Variant> PropertyDesc;
	List<PropertyDesc> properties;

	if (ScriptInstance *si = obj->get_script_instance()) {
		if (!si->get_script().is_null()) {

			Set<StringName> members;
			si->get_script()->get_members(&members);
			for (Set<StringName>::Element *E = members.front(); E; E = E->next()) {

				Variant m;
				if (si->get(E->get(), m)) {
					PropertyInfo pi(m.get_type(), String("Members/") + E->get());
					properties.push_back(PropertyDesc(pi, m));
				}
			}

			Map<StringName, Variant> constants;
			si->get_script()->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				PropertyInfo pi(E->value().get_type(), (String("Constants/") + E->key()));
				properties.push_back(PropertyDesc(pi, E->value()));
			}
		}
	}
	if (Node *node = Object::cast_to<Node>(obj)) {
		PropertyInfo pi(Variant::NODE_PATH, String("Node/path"));
		properties.push_front(PropertyDesc(pi, node->get_path()));
	} else if (Resource *res = Object::cast_to<Resource>(obj)) {
		if (Script *s = Object::cast_to<Script>(res)) {
			Map<StringName, Variant> constants;
			s->get_constants(&constants);
			for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
				PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key());
				properties.push_front(PropertyDesc(pi, E->value()));
			}
		}
	}

	List<PropertyInfo> pinfo;
	obj->get_property_list(&pinfo, true);
	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
		if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) {
			properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name)));
		}
	}

	Array send_props;
	for (int i = 0; i < properties.size(); i++) {
		const PropertyInfo &pi = properties[i].first;
		Variant &var = properties[i].second;

		WeakRef *ref = Object::cast_to<WeakRef>(var);
		if (ref) {
			var = ref->get_ref();
		}

		RES res = var;

		Array prop;
		prop.push_back(pi.name);
		prop.push_back(pi.type);

		//only send information that can be sent..
		int len = 0; //test how big is this to encode
		encode_variant(var, NULL, len);
		if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size
			prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG);
			prop.push_back("");
			prop.push_back(pi.usage);
			prop.push_back(Variant());
		} else {
			prop.push_back(pi.hint);
			if (res.is_null())
				prop.push_back(pi.hint_string);
			else
				prop.push_back(String("RES:") + res->get_path());
			prop.push_back(pi.usage);
			prop.push_back(var);
		}
		send_props.push_back(prop);
	}

	packet_peer_stream->put_var("message:inspect_object");
	packet_peer_stream->put_var(3);
	packet_peer_stream->put_var(p_id);
	packet_peer_stream->put_var(obj->get_class());
	packet_peer_stream->put_var(send_props);
}
void EditorPropertyRootMotion::_node_assign() {

	NodePath current = get_edited_object()->get(get_edited_property());

	AnimationTree *atree = Object::cast_to<AnimationTree>(get_edited_object());
	if (!atree->has_node(atree->get_animation_player())) {
		EditorNode::get_singleton()->show_warning(TTR("AnimationTree has no path set to an AnimationPlayer"));
		return;
	}
	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(atree->get_node(atree->get_animation_player()));
	if (!player) {
		EditorNode::get_singleton()->show_warning(TTR("Path to AnimationPlayer is invalid"));
		return;
	}

	Node *base = player->get_node(player->get_root());

	if (!base) {
		EditorNode::get_singleton()->show_warning(TTR("Animation player has no valid root node path, so unable to retrieve track names."));
		return;
	}

	Set<String> paths;
	{
		List<StringName> animations;
		player->get_animation_list(&animations);

		for (List<StringName>::Element *E = animations.front(); E; E = E->next()) {

			Ref<Animation> anim = player->get_animation(E->get());
			for (int i = 0; i < anim->get_track_count(); i++) {
				paths.insert(anim->track_get_path(i));
			}
		}
	}

	filters->clear();
	TreeItem *root = filters->create_item();

	Map<String, TreeItem *> parenthood;

	for (Set<String>::Element *E = paths.front(); E; E = E->next()) {

		NodePath path = E->get();
		TreeItem *ti = NULL;
		String accum;
		for (int i = 0; i < path.get_name_count(); i++) {
			String name = path.get_name(i);
			if (accum != String()) {
				accum += "/";
			}
			accum += name;
			if (!parenthood.has(accum)) {
				if (ti) {
					ti = filters->create_item(ti);
				} else {
					ti = filters->create_item(root);
				}
				parenthood[accum] = ti;
				ti->set_text(0, name);
				ti->set_selectable(0, false);
				ti->set_editable(0, false);

				if (base->has_node(accum)) {
					Node *node = base->get_node(accum);
					if (has_icon(node->get_class(), "EditorIcons")) {
						ti->set_icon(0, get_icon(node->get_class(), "EditorIcons"));
					} else {
						ti->set_icon(0, get_icon("Node", "EditorIcons"));
					}
				}

			} else {
				ti = parenthood[accum];
			}
		}

		Node *node = NULL;
		if (base->has_node(accum)) {
			node = base->get_node(accum);
		}
		if (!node)
			continue; //no node, cant edit

		if (path.get_subname_count()) {

			String concat = path.get_concatenated_subnames();

			Skeleton *skeleton = Object::cast_to<Skeleton>(node);
			if (skeleton && skeleton->find_bone(concat) != -1) {
				//path in skeleton
				String bone = concat;
				int idx = skeleton->find_bone(bone);
				List<String> bone_path;
				while (idx != -1) {
					bone_path.push_front(skeleton->get_bone_name(idx));
					idx = skeleton->get_bone_parent(idx);
				}

				accum += ":";
				for (List<String>::Element *F = bone_path.front(); F; F = F->next()) {
					if (F != bone_path.front()) {
						accum += "/";
					}

					accum += F->get();
					if (!parenthood.has(accum)) {
						ti = filters->create_item(ti);
						parenthood[accum] = ti;
						ti->set_text(0, F->get());
						ti->set_selectable(0, true);
						ti->set_editable(0, false);
						ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons"));
						ti->set_metadata(0, accum);
					} else {
						ti = parenthood[accum];
					}
				}

				ti->set_selectable(0, true);
				ti->set_text(0, concat);
				ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons"));
				ti->set_metadata(0, path);
				if (path == current) {
					ti->select(0);
				}

			} else {
				//just a property
				ti = filters->create_item(ti);
				ti->set_text(0, concat);
				ti->set_selectable(0, true);
				ti->set_metadata(0, path);
				if (path == current) {
					ti->select(0);
				}
			}
		} else {
			if (ti) {
				//just a node, likely call or animation track
				ti->set_selectable(0, true);
				ti->set_metadata(0, path);
				if (path == current) {
					ti->select(0);
				}
			}
		}
	}

	filters->ensure_cursor_is_visible();
	filter_dialog->popup_centered_ratio();
}
void AnimationTreeEditor::_edit_filters() {

	filter_dialog->popup_centered_ratio();
	filter->clear();

	Set<String> npb;
	_find_paths_for_filter(edited_node,npb);

	TreeItem *root = filter->create_item();
	filter->set_hide_root(true);
	Map<String,TreeItem*> pm;

	Node *base = anim_tree->get_node( anim_tree->get_base_path() );

	for(Set<String>::Element *E=npb.front();E;E=E->next()) {

		TreeItem *parent=root;
		String descr=E->get();
		if (base) {
			NodePath np = E->get();

			if (np.get_property()!=StringName()) {
				Node *n = base->get_node(np);
				Skeleton *s = n->cast_to<Skeleton>();
				if (s) {

					String skelbase = E->get().substr(0,E->get().find(":"));


					int bidx = s->find_bone(np.get_property());

					if (bidx!=-1) {
						int bparent = s->get_bone_parent(bidx);
						//
						if (bparent!=-1) {


							String bpn = skelbase+":"+s->get_bone_name(bparent);
							if (pm.has(bpn)) {
								parent=pm[bpn];
								descr=np.get_property();
							}
						} else {

							if (pm.has(skelbase)) {
								parent=pm[skelbase];

							}
						}
					}
				}
			}
		}

		TreeItem *it = filter->create_item(parent);
		it->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
		it->set_text(0,descr);
		it->set_metadata(0,NodePath(E->get()));
		it->set_editable(0,true);
		if (anim_tree->node_get_type(edited_node)==AnimationTreePlayer::NODE_ONESHOT) {
			it->set_checked(0, anim_tree->oneshot_node_is_path_filtered(edited_node,E->get()));
		} else if (anim_tree->node_get_type(edited_node)==AnimationTreePlayer::NODE_BLEND2) {
			it->set_checked(0, anim_tree->blend2_node_is_path_filtered(edited_node,E->get()));
		}
		pm[E->get()]=it;
	}


}
Example #16
0
void FileSystemDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) {

	Vector<String> filenames;

	bool all_scenes=true;
	bool all_can_reimport=true;
	Set<String> types;

	for(int i=0;i<files->get_item_count();i++) {

		if (!files->is_selected(i))
			continue;

		String path = files->get_item_metadata(i);

		if (files->get_item_text(i)=="..") {
			// no operate on ..
			 return;
		}

		if (path.ends_with("/")) {
			//no operate on dirs
			return;
		}


		EditorFileSystemDirectory *efsd=NULL;
		int pos;

		efsd = EditorFileSystem::get_singleton()->find_file(path,&pos);

		if (efsd) {


			if (!efsd->get_file_meta(pos)) {
				all_can_reimport=false;


			} else {
				Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(path);
				if (rimd.is_valid()) {

					String editor=rimd->get_editor();
					if (editor.begins_with("texture_")) { //compatibility fix for old texture format
						editor="texture";
					}
					types.insert(editor);

				} else {
					all_can_reimport=false;

				}
			}
		} else {
			all_can_reimport=false;

		}

		filenames.push_back(path);
		if (EditorFileSystem::get_singleton()->get_file_type(path)!="PackedScene")
			all_scenes=false;
	}


	if (filenames.size()==0)
		return;

	file_options->clear();
	file_options->set_size(Size2(1,1));

	file_options->add_item(TTR("Open"),FILE_OPEN);
	if (all_scenes) {
		file_options->add_item(TTR("Instance"),FILE_INSTANCE);
	}

	file_options->add_separator();

	if (filenames.size()==1) {
		file_options->add_item(TTR("Edit Dependencies.."),FILE_DEPENDENCIES);
		file_options->add_item(TTR("View Owners.."),FILE_OWNERS);
		file_options->add_separator();
	}

	if (filenames.size()==1) {
		file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH);
		file_options->add_item(TTR("Rename or Move.."),FILE_MOVE);
	} else {
		file_options->add_item(TTR("Move To.."),FILE_MOVE);
	}


	file_options->add_item(TTR("Delete"),FILE_REMOVE);

	//file_options->add_item(TTR("Info"),FILE_INFO);

	file_options->add_separator();
	file_options->add_item(TTR("Show In File Manager"),FILE_SHOW_IN_EXPLORER);

	if (all_can_reimport && types.size()==1) { //all can reimport and are of the same type


		bool valid=true;
		Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(types.front()->get());
		if (rimp.is_valid()) {

			if (filenames.size()>1 && !rimp->can_reimport_multiple_files())	{
				valid=false;
			}
		} else {
			valid=false;
		}

		if (valid) {
			file_options->add_separator();
			file_options->add_item(TTR("Re-Import.."),FILE_REIMPORT);
		}
	}

	file_options->set_pos(files->get_global_pos() + p_pos);
	file_options->popup();

}
Example #17
0
Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map) {

	// children first..
	for(int i=0;i<p_node->get_child_count();i++) {


		Node *r = _fix_node(p_node->get_child(i),p_root,collision_map,p_flags,image_map);
		if (!r) {
			print_line("was erased..");
			i--; //was erased
		}
	}

	String name = p_node->get_name();

	bool isroot = p_node==p_root;


	if (!isroot && p_flags&SCENE_FLAG_REMOVE_NOIMP && _teststr(name,"noimp")) {

		memdelete(p_node);
		return NULL;
	}

	{

		List<PropertyInfo> pl;
		p_node->get_property_list(&pl);
		for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {

			if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
				_find_resources(p_node->get(E->get().name),image_map);
			}
		}

	}




	if (p_flags&SCENE_FLAG_CREATE_BILLBOARDS && p_node->cast_to<MeshInstance>()) {

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		bool bb=false;

		if ((_teststr(name,"bb"))) {
			bb=true;
		} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"bb"))) {
			bb=true;

		}

		if (bb) {
			mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true);
			if (mi->get_mesh().is_valid()) {

				Ref<Mesh> m = mi->get_mesh();
				for(int i=0;i<m->get_surface_count();i++) {

					Ref<FixedMaterial> fm = m->surface_get_material(i);
					if (fm.is_valid()) {
						fm->set_flag(Material::FLAG_UNSHADED,true);
						fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
						fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
					}
				}
			}
		}
	}

	if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) {
		//remove animations referencing non-importable nodes
		AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();

		List<StringName> anims;
		ap->get_animation_list(&anims);
		for(List<StringName>::Element *E=anims.front();E;E=E->next()) {

			Ref<Animation> anim=ap->get_animation(E->get());
			ERR_CONTINUE(anim.is_null());
			for(int i=0;i<anim->get_track_count();i++) {
				NodePath path = anim->track_get_path(i);

				for(int j=0;j<path.get_name_count();j++) {
					String node = path.get_name(j);
					if (_teststr(node,"noimp")) {
						anim->remove_track(i);
						i--;
						break;
					}
				}
			}

		}
	}


	if (p_flags&SCENE_FLAG_CREATE_IMPOSTORS && p_node->cast_to<MeshInstance>()) {

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		String str;

		if ((_teststr(name,"imp"))) {
			str=name;
		} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"imp"))) {
			str=mi->get_mesh()->get_name();

		}


		if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
			MeshInstance *mi = p_node->cast_to<MeshInstance>();
			MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
			String d=str.substr(str.find("imp")+3,str.length());
			if (d!="") {
				if ((d[0]<'0' || d[0]>'9'))
					d=d.substr(1,d.length());
				if (d.length() && d[0]>='0' && d[0]<='9') {
					float dist = d.to_double();
					mi->set_flag(GeometryInstance::FLAG_BILLBOARD,true);
					mi->set_flag(GeometryInstance::FLAG_BILLBOARD_FIX_Y,true);
					mi->set_draw_range_begin(dist);
					mi->set_draw_range_end(100000);

					mip->set_draw_range_begin(0);
					mip->set_draw_range_end(dist);

					if (mi->get_mesh().is_valid()) {

						Ref<Mesh> m = mi->get_mesh();
						for(int i=0;i<m->get_surface_count();i++) {

							Ref<FixedMaterial> fm = m->surface_get_material(i);
							if (fm.is_valid()) {
								fm->set_flag(Material::FLAG_UNSHADED,true);
								fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
								fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
								fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
							}
						}
					}
				}
			}
		}
	}

    if (p_flags&SCENE_FLAG_CREATE_LODS && p_node->cast_to<MeshInstance>()) {

	MeshInstance *mi = p_node->cast_to<MeshInstance>();

	String str;

	if ((_teststr(name,"lod"))) {
	    str=name;
	} else if (mi->get_mesh().is_valid() && (_teststr(mi->get_mesh()->get_name(),"lod"))) {
	    str=mi->get_mesh()->get_name();

	}


	if (p_node->get_parent() && p_node->get_parent()->cast_to<MeshInstance>()) {
	    MeshInstance *mi = p_node->cast_to<MeshInstance>();
	    MeshInstance *mip = p_node->get_parent()->cast_to<MeshInstance>();
	    String d=str.substr(str.find("lod")+3,str.length());
	    if (d!="") {
		if ((d[0]<'0' || d[0]>'9'))
		    d=d.substr(1,d.length());
		if (d.length() && d[0]>='0' && d[0]<='9') {
		    float dist = d.to_double();
		    mi->set_draw_range_begin(dist);
		    mi->set_draw_range_end(100000);

		    mip->set_draw_range_begin(0);
		    mip->set_draw_range_end(dist);

		    /*if (mi->get_mesh().is_valid()) {

			Ref<Mesh> m = mi->get_mesh();
			for(int i=0;i<m->get_surface_count();i++) {

			    Ref<FixedMaterial> fm = m->surface_get_material(i);
			    if (fm.is_valid()) {
				fm->set_flag(Material::FLAG_UNSHADED,true);
				fm->set_flag(Material::FLAG_DOUBLE_SIDED,true);
				fm->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
				fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
			    }
			}
		    }*/
		}
	    }
	}
    }
	if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly") && p_node->cast_to<MeshInstance>()) {

		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		Node * col = mi->create_trimesh_collision_node();

		ERR_FAIL_COND_V(!col,NULL);
		col->set_name(_fixstr(name,"colonly"));
		col->cast_to<Spatial>()->set_transform(mi->get_transform());
		p_node->replace_by(col);
		memdelete(p_node);
		p_node=col;

	} else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) {


		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		mi->set_name(_fixstr(name,"col"));
		mi->create_trimesh_collision();
	} else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) {


		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);


		BSP_Tree bsptree(faces);

		Ref<RoomBounds> area = memnew( RoomBounds );
		area->set_bounds(faces);
		area->set_geometry_hint(faces);


		Room * room = memnew( Room );
		room->set_name(_fixstr(name,"room"));
		room->set_transform(mi->get_transform());
		room->set_room(area);

		p_node->replace_by(room);
		memdelete(p_node);
		p_node=room;

	} else if (p_flags&SCENE_FLAG_CREATE_ROOMS &&_teststr(name,"room")) {

		if (isroot)
			return p_node;

		Spatial *dummy = p_node->cast_to<Spatial>();
		ERR_FAIL_COND_V(!dummy,NULL);

		Room * room = memnew( Room );
		room->set_name(_fixstr(name,"room"));
		room->set_transform(dummy->get_transform());

		p_node->replace_by(room);
		memdelete(p_node);
		p_node=room;

		room->compute_room_from_subtree();

	} else if (p_flags&SCENE_FLAG_CREATE_PORTALS &&_teststr(name,"portal") && p_node->cast_to<MeshInstance>()) {

		if (isroot)
			return p_node;

		MeshInstance *mi = p_node->cast_to<MeshInstance>();
		DVector<Face3> faces = mi->get_faces(VisualInstance::FACES_SOLID);

		ERR_FAIL_COND_V(faces.size()==0,NULL);
		//step 1 compute the plane
		Set<Vector3> points;
		Plane plane;

		Vector3 center;

		for(int i=0;i<faces.size();i++) {

			Face3 f = faces.get(i);
			Plane p = f.get_plane();
			plane.normal+=p.normal;
			plane.d+=p.d;

			for(int i=0;i<3;i++) {

				Vector3 v = f.vertex[i].snapped(0.01);
				if (!points.has(v)) {
					points.insert(v);
					center+=v;
				}
			}
		}

		plane.normal.normalize();
		plane.d/=faces.size();
		center/=points.size();

		//step 2, create points

		Transform t;
		t.basis.from_z(plane.normal);
		t.basis.transpose();
		t.origin=center;

		Vector<Point2> portal_points;

		for(Set<Vector3>::Element *E=points.front();E;E=E->next()) {

			Vector3 local = t.xform_inv(E->get());
			portal_points.push_back(Point2(local.x,local.y));
		}
		// step 3 bubbly sort points

		int swaps=0;

		do {
			swaps=0;

			for(int i=0;i<portal_points.size()-1;i++) {

				float a = portal_points[i].atan2();
				float b = portal_points[i+1].atan2();

				if (a>b) {
					SWAP( portal_points[i], portal_points[i+1] );
					swaps++;
				}

			}

		} while(swaps);


		Portal *portal = memnew( Portal );

		portal->set_shape(portal_points);
		portal->set_transform( mi->get_transform() * t);

		p_node->replace_by(portal);
		memdelete(p_node);
		p_node=portal;

	} else if (p_node->cast_to<MeshInstance>()) {

		//last attempt, maybe collision insde the mesh data

		MeshInstance *mi = p_node->cast_to<MeshInstance>();

		Ref<Mesh> mesh = mi->get_mesh();
		if (!mesh.is_null()) {

			if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(mesh->get_name(),"col")) {

				mesh->set_name( _fixstr(mesh->get_name(),"col") );
				Ref<Shape> shape;

				if (collision_map.has(mesh)) {
					shape = collision_map[mesh];

				} else {

					shape = mesh->create_trimesh_shape();
					if (!shape.is_null())
						collision_map[mesh]=shape;


				}

				if (!shape.is_null()) {
#if 0
					StaticBody* static_body = memnew( StaticBody );
					ERR_FAIL_COND_V(!static_body,NULL);
					static_body->set_name( String(mesh->get_name()) + "_col" );
					shape->set_name(static_body->get_name());
					static_body->add_shape(shape);

					mi->add_child(static_body);
					if (mi->get_owner())
						static_body->set_owner( mi->get_owner() );
#endif
				}

			}

			for(int i=0;i<mesh->get_surface_count();i++) {

				Ref<FixedMaterial> fm = mesh->surface_get_material(i);
				if (fm.is_valid()) {
					String name = fm->get_name();
					if (_teststr(name,"alpha")) {
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
						name=_fixstr(name,"alpha");
					}

					if (_teststr(name,"vcol")) {
						fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
						name=_fixstr(name,"vcol");
					}
					fm->set_name(name);
				}
			}

		}

	}




	return p_node;
}
Example #18
0
Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) {

	Error err=OK;
	Ref<ResourceImportMetadata> from=p_from;
	String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0));
	int animation_flags=p_from->get_option("animation_flags");
	int scene_flags = from->get_option("flags");

	EditorProgress progress("import","Import Scene",104);
	progress.step("Importing Scene..",2);


	bool merge = !bool(from->get_option("reimport"));
	from->set_source_md5(0,FileAccess::get_md5(src_path));
	from->set_editor(get_name());

	from->set_option("reimport",false);
	String target_res_path=p_dest_path.get_base_dir();

	Map<Ref<Mesh>,Ref<Shape> > collision_map;

	Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata);

	Set< Ref<ImageTexture> > imagemap;

	scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);


	/// BEFORE ANYTHING, RUN SCRIPT

	progress.step("Running Custom Script..",2);

	String post_import_script_path = from->get_option("post_import_script");
	Ref<EditorScenePostImport>  post_import_script;

	if (post_import_script_path!="") {
		post_import_script_path = EditorImportPlugin::expand_source_path(post_import_script_path);
		Ref<Script> scr = ResourceLoader::load(post_import_script_path);
		if (!scr.is_valid()) {
			EditorNode::add_io_error("Couldn't load post-import script: '"+post_import_script_path);
		} else {

			post_import_script = Ref<EditorScenePostImport>( memnew( EditorScenePostImport ) );
			post_import_script->set_script(scr.get_ref_ptr());
			if (!post_import_script->get_script_instance()) {
				EditorNode::add_io_error("Invalid/Broken Script for Post-Import: '"+post_import_script_path);
				post_import_script.unref();
			}
		}
	}


	if (post_import_script.is_valid()) {
		err = post_import_script->post_import(scene);
		if (err) {
			EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path);
			return err;
		}
	}

	/// IMPORT IMAGES


	int idx=0;

	int image_format = from->get_option("texture_format");
	int image_flags =  from->get_option("texture_flags");
	float image_quality = from->get_option("texture_quality");

	for (Set< Ref<ImageTexture> >::Element *E=imagemap.front();E;E=E->next()) {

		//texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff
		//but not yet..

		Ref<ImageTexture> texture = E->get();

		ERR_CONTINUE(!texture.is_valid());

		String path = texture->get_path();
		String fname= path.get_file();
		String target_path = Globals::get_singleton()->localize_path(target_res_path.plus_file(fname));
		progress.step("Import Img: "+fname,3+(idx)*100/imagemap.size());

		idx++;

		if (path==target_path) {

			EditorNode::add_io_error("Can't import a file over itself: '"+target_path);
			continue;
		}

		if (!target_path.begins_with("res://")) {
			EditorNode::add_io_error("Couldn't localize path: '"+target_path+"' (already local)");
			continue;
		}


		{


			target_path=target_path.basename()+".tex";

			Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
			print_line("flags: "+itos(image_flags));
			imd->set_option("flags",image_flags);
			imd->set_option("format",image_format);
			imd->set_option("quality",image_quality);
			imd->set_option("atlas",false);
			imd->add_source(EditorImportPlugin::validate_source_path(path));


			if (FileAccess::exists(target_path)) {

				 Ref<ResourceImportMetadata> rimdex = ResourceLoader::load_import_metadata(target_path);
				 if (rimdex.is_valid()) {
					//make sure the options are the same, otherwise re-import
					List<String> opts;
					imd->get_options(&opts);
					bool differ=false;
					for (List<String>::Element *E=opts.front();E;E=E->next()) {
						if (!(rimdex->get_option(E->get())==imd->get_option(E->get()))) {
							differ=true;
							break;
						}
					}

					if (!differ) {
						texture->set_path(target_path);
						continue; //already imported
					}
				}
			}

			Error err = EditorTextureImportPlugin::get_singleton(EditorTextureImportPlugin::MODE_TEXTURE_3D)->import(target_path,imd);

		}
	}


	/// BEFORE SAVING - MERGE


	if (merge) {

		progress.step("Merging..",103);

		FileAccess *fa = FileAccess::create(FileAccess::ACCESS_FILESYSTEM);
		if (fa->file_exists(p_dest_path)) {

			//try to merge

			Ref<PackedScene> s = ResourceLoader::load(p_dest_path);
			if (s.is_valid()) {

				Node *existing = s->instance(true);

				if (existing) {

					_merge_scenes(scene,existing);

					memdelete(scene);
					scene=existing;
				}
			}

		}

		memdelete(fa);
	}


	progress.step("Saving..",104);

	Ref<PackedScene> packer = memnew( PackedScene );
	packer->pack(scene);
	packer->set_path(p_dest_path);
	packer->set_import_metadata(from);

	print_line("SAVING TO: "+p_dest_path);
	err = ResourceSaver::save(p_dest_path,packer);

	//EditorFileSystem::get_singleton()->update_resource(packer);

	memdelete(scene);
	/*
	scene->set_filename(p_dest_path);
	if (r_scene) {
		*r_scene=scene;
	} else {
		memdelete(scene);
	}

	String sp;
	if (p_post_import.is_valid() && !p_post_import->get_script().is_null()) {
		Ref<Script> scr = p_post_import->get_script();
		if (scr.is_valid())
			sp=scr->get_path();
	}

	String op=_getrelpath(p_path,p_dest_path);

	*/


	return err;

}
bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &anode) {

	if (updating || _filter_edit != anode)
		return false;

	NodePath player_path = anode->get_tree()->get_animation_player();

	if (!anode->get_tree()->has_node(player_path)) {
		EditorNode::get_singleton()->show_warning(TTR("No animation player set, so unable to retrieve track names."));
		return false;
	}

	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(anode->get_tree()->get_node(player_path));
	if (!player) {
		EditorNode::get_singleton()->show_warning(TTR("Player path set is invalid, so unable to retrieve track names."));
		return false;
	}

	Node *base = player->get_node(player->get_root());

	if (!base) {
		EditorNode::get_singleton()->show_warning(TTR("Animation player has no valid root node path, so unable to retrieve track names."));
		return false;
	}

	updating = true;

	Set<String> paths;
	{
		List<StringName> animations;
		player->get_animation_list(&animations);

		for (List<StringName>::Element *E = animations.front(); E; E = E->next()) {

			Ref<Animation> anim = player->get_animation(E->get());
			for (int i = 0; i < anim->get_track_count(); i++) {
				paths.insert(anim->track_get_path(i));
			}
		}
	}

	filter_enabled->set_pressed(anode->is_filter_enabled());
	filters->clear();
	TreeItem *root = filters->create_item();

	Map<String, TreeItem *> parenthood;

	for (Set<String>::Element *E = paths.front(); E; E = E->next()) {

		NodePath path = E->get();
		TreeItem *ti = NULL;
		String accum;
		for (int i = 0; i < path.get_name_count(); i++) {
			String name = path.get_name(i);
			if (accum != String()) {
				accum += "/";
			}
			accum += name;
			if (!parenthood.has(accum)) {
				if (ti) {
					ti = filters->create_item(ti);
				} else {
					ti = filters->create_item(root);
				}
				parenthood[accum] = ti;
				ti->set_text(0, name);
				ti->set_selectable(0, false);
				ti->set_editable(0, false);

				if (base->has_node(accum)) {
					Node *node = base->get_node(accum);
					if (has_icon(node->get_class(), "EditorIcons")) {
						ti->set_icon(0, get_icon(node->get_class(), "EditorIcons"));
					} else {
						ti->set_icon(0, get_icon("Node", "EditorIcons"));
					}
				}

			} else {
				ti = parenthood[accum];
			}
		}

		Node *node = NULL;
		if (base->has_node(accum)) {
			node = base->get_node(accum);
		}
		if (!node)
			continue; //no node, cant edit

		if (path.get_subname_count()) {

			String concat = path.get_concatenated_subnames();

			Skeleton *skeleton = Object::cast_to<Skeleton>(node);
			if (skeleton && skeleton->find_bone(concat) != -1) {
				//path in skeleton
				String bone = concat;
				int idx = skeleton->find_bone(bone);
				List<String> bone_path;
				while (idx != -1) {
					bone_path.push_front(skeleton->get_bone_name(idx));
					idx = skeleton->get_bone_parent(idx);
				}

				accum += ":";
				for (List<String>::Element *F = bone_path.front(); F; F = F->next()) {
					if (F != bone_path.front()) {
						accum += "/";
					}

					accum += F->get();
					if (!parenthood.has(accum)) {
						ti = filters->create_item(ti);
						parenthood[accum] = ti;
						ti->set_text(0, F->get());
						ti->set_selectable(0, false);
						ti->set_editable(0, false);
						ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons"));
					} else {
						ti = parenthood[accum];
					}
				}

				ti->set_editable(0, true);
				ti->set_selectable(0, true);
				ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
				ti->set_text(0, concat);
				ti->set_checked(0, anode->is_path_filtered(path));
				ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons"));
				ti->set_metadata(0, path);

			} else {
				//just a property
				ti = filters->create_item(ti);
				ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
				ti->set_text(0, concat);
				ti->set_editable(0, true);
				ti->set_selectable(0, true);
				ti->set_checked(0, anode->is_path_filtered(path));
				ti->set_metadata(0, path);
			}
		} else {
			if (ti) {
				//just a node, likely call or animation track
				ti->set_editable(0, true);
				ti->set_selectable(0, true);
				ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
				ti->set_checked(0, anode->is_path_filtered(path));
				ti->set_metadata(0, path);
			}
		}
	}

	updating = false;

	return true;
}
Example #20
0
Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
	//figure out paths of files that will be exported
	Set<String> paths;
	Vector<String> path_remaps;

	if (p_preset->get_export_filter() == EditorExportPreset::EXPORT_ALL_RESOURCES) {
		//find stuff
		_export_find_resources(EditorFileSystem::get_singleton()->get_filesystem(), paths);
	} else {
		bool scenes_only = p_preset->get_export_filter() == EditorExportPreset::EXPORT_SELECTED_SCENES;

		Vector<String> files = p_preset->get_files_to_export();
		for (int i = 0; i < files.size(); i++) {
			if (scenes_only && ResourceLoader::get_resource_type(files[i]) != "PackedScene")
				continue;

			_export_find_dependencies(files[i], paths);
		}
	}

	_edit_filter_list(paths, p_preset->get_include_filter(), false);
	_edit_filter_list(paths, p_preset->get_exclude_filter(), true);

	Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins();
	for (int i = 0; i < export_plugins.size(); i++) {

		export_plugins.write[i]->set_export_preset(p_preset);

		if (p_so_func) {
			for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
				p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
			}
		}
		for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
			p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, 0, paths.size());
		}

		export_plugins.write[i]->_clear();
	}

	FeatureContainers feature_containers = get_feature_containers(p_preset);
	Set<String> &features = feature_containers.features;
	PoolVector<String> &features_pv = feature_containers.features_pv;

	//store everything in the export medium
	int idx = 0;
	int total = paths.size();

	for (Set<String>::Element *E = paths.front(); E; E = E->next()) {

		String path = E->get();
		String type = ResourceLoader::get_resource_type(path);

		if (FileAccess::exists(path + ".import")) {
			//file is imported, replace by what it imports
			Ref<ConfigFile> config;
			config.instance();
			Error err = config->load(path + ".import");
			if (err != OK) {
				ERR_PRINTS("Could not parse: '" + path + "', not exported.");
				continue;
			}

			List<String> remaps;
			config->get_section_keys("remap", &remaps);

			Set<String> remap_features;

			for (List<String>::Element *F = remaps.front(); F; F = F->next()) {

				String remap = F->get();
				String feature = remap.get_slice(".", 1);
				if (features.has(feature)) {
					remap_features.insert(feature);
				}
			}

			if (remap_features.size() > 1) {
				this->resolve_platform_feature_priorities(p_preset, remap_features);
			}

			err = OK;

			for (List<String>::Element *F = remaps.front(); F; F = F->next()) {

				String remap = F->get();
				if (remap == "path") {
					String remapped_path = config->get_value("remap", remap);
					Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path);
					err = p_func(p_udata, remapped_path, array, idx, total);
				} else if (remap.begins_with("path.")) {
					String feature = remap.get_slice(".", 1);

					if (remap_features.has(feature)) {
						String remapped_path = config->get_value("remap", remap);
						Vector<uint8_t> array = FileAccess::get_file_as_array(remapped_path);
						err = p_func(p_udata, remapped_path, array, idx, total);
					}
				}
			}

			if (err != OK) {
				return err;
			}

			//also save the .import file
			Vector<uint8_t> array = FileAccess::get_file_as_array(path + ".import");
			err = p_func(p_udata, path + ".import", array, idx, total);

			if (err != OK) {
				return err;
			}

		} else {

			bool do_export = true;
			for (int i = 0; i < export_plugins.size(); i++) {
				if (export_plugins[i]->get_script_instance()) { //script based
					export_plugins.write[i]->_export_file_script(path, type, features_pv);
				} else {
					export_plugins.write[i]->_export_file(path, type, features);
				}
				if (p_so_func) {
					for (int j = 0; j < export_plugins[i]->shared_objects.size(); j++) {
						p_so_func(p_udata, export_plugins[i]->shared_objects[j]);
					}
				}

				for (int j = 0; j < export_plugins[i]->extra_files.size(); j++) {
					p_func(p_udata, export_plugins[i]->extra_files[j].path, export_plugins[i]->extra_files[j].data, idx, total);
					if (export_plugins[i]->extra_files[j].remap) {
						do_export = false; //if remap, do not
						path_remaps.push_back(path);
						path_remaps.push_back(export_plugins[i]->extra_files[j].path);
					}
				}

				if (export_plugins[i]->skipped) {
					do_export = false;
				}
				export_plugins.write[i]->_clear();

				if (!do_export)
					break; //apologies, not exporting
			}
			//just store it as it comes
			if (do_export) {
				Vector<uint8_t> array = FileAccess::get_file_as_array(path);
				p_func(p_udata, path, array, idx, total);
			}
		}

		idx++;
	}

	//save config!

	Vector<String> custom_list;

	if (p_preset->get_custom_features() != String()) {

		Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");

		for (int i = 0; i < tmp_custom_list.size(); i++) {
			String f = tmp_custom_list[i].strip_edges();
			if (f != String()) {
				custom_list.push_back(f);
			}
		}
	}

	ProjectSettings::CustomMap custom_map;
	if (path_remaps.size()) {
		if (1) { //new remap mode, use always as it's friendlier with multiple .pck exports
			for (int i = 0; i < path_remaps.size(); i += 2) {
				String from = path_remaps[i];
				String to = path_remaps[i + 1];
				String remap_file = "[remap]\n\npath=\"" + to.c_escape() + "\"\n";
				CharString utf8 = remap_file.utf8();
				Vector<uint8_t> new_file;
				new_file.resize(utf8.length());
				for (int j = 0; j < utf8.length(); j++) {
					new_file.write[j] = utf8[j];
				}

				p_func(p_udata, from + ".remap", new_file, idx, total);
			}
		} else {
			//old remap mode, will still work, but it's unused because it's not multiple pck export friendly
			custom_map["path_remap/remapped_paths"] = path_remaps;
		}
	}

	// Store icon and splash images directly, they need to bypass the import system and be loaded as images
	String icon = ProjectSettings::get_singleton()->get("application/config/icon");
	String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image");
	if (icon != String() && FileAccess::exists(icon)) {
		Vector<uint8_t> array = FileAccess::get_file_as_array(icon);
		p_func(p_udata, icon, array, idx, total);
	}
	if (splash != String() && FileAccess::exists(splash) && icon != splash) {
		Vector<uint8_t> array = FileAccess::get_file_as_array(splash);
		p_func(p_udata, splash, array, idx, total);
	}

	String config_file = "project.binary";
	String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file);
	ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list);
	Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb);

	p_func(p_udata, "res://" + config_file, data, idx, total);

	return OK;
}
Example #21
0
Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base_path, Object*p_owner, List<String>* r_options, String &r_call_hint) {
/* bugs:
  a[0].<complete> does not work
  functions should end in (
  when completing virtuals, ask for full back

 */
	//print_line( p_code.replace(String::chr(0xFFFF),"<cursor>"));

	GDParser p;
	Error err = p.parse(p_code,p_base_path);
	bool isfunction=false;
	Set<String> options;

	GDCompletionContext context;
	context._class=p.get_completion_class();
	context.block=p.get_completion_block();
	context.function=p.get_completion_function();
	context.base=p_owner;
	context.base_path=p_base_path;

	switch(p.get_completion_type()) {

		case GDParser::COMPLETION_NONE: {
			print_line("No completion");
		} break;
		case GDParser::COMPLETION_BUILT_IN_TYPE_CONSTANT: {
			print_line("Built in type constant");
			List<StringName> constants;
			Variant::get_numeric_constants_for_type(p.get_completion_built_in_constant(),&constants);
			for(List<StringName>::Element *E=constants.front();E;E=E->next()) {
				options.insert(E->get().operator String());
			}


		} break;
		case GDParser::COMPLETION_FUNCTION:
			isfunction=true;
		case GDParser::COMPLETION_IDENTIFIER: {

			_find_identifiers(context,p.get_completion_line(),isfunction,options);
		} break;
		case GDParser::COMPLETION_PARENT_FUNCTION: {
			print_line("parent function");

		} break;
		case GDParser::COMPLETION_METHOD:
			isfunction=true;
		case GDParser::COMPLETION_INDEX: {

			const GDParser::Node *node = p.get_completion_node();
			if (node->type!=GDParser::Node::TYPE_OPERATOR)
				break;




			GDCompletionIdentifier t;
			if (_guess_expression_type(context,static_cast<const GDParser::OperatorNode *>(node)->arguments[0],p.get_completion_line(),t)) {

				if (t.type==Variant::OBJECT && t.obj_type!=StringName()) {


					if (t.value.get_type()) {
						Object *obj=t.value;
						if (obj) {
							GDScript *scr = obj->cast_to<GDScript>();
							while (scr) {

								if (!isfunction) {
									for (const Map<StringName,Variant>::Element *E=scr->get_constants().front();E;E=E->next()) {
										options.insert(E->key());
									}
								}
								for (const Map<StringName,GDFunction>::Element *E=scr->get_member_functions().front();E;E=E->next()) {
									options.insert(E->key());
								}

								if (scr->get_base().is_valid())
									scr=scr->get_base().ptr();
								else
									scr=NULL;
							}
						}
					}


					if (!isfunction) {
						ObjectTypeDB::get_integer_constant_list(t.obj_type,r_options);
					}
					List<MethodInfo> mi;
					ObjectTypeDB::get_method_list(t.obj_type,&mi);
					for (List<MethodInfo>::Element *E=mi.front();E;E=E->next()) {

						if (E->get().name.begins_with("_"))
							continue;

						if (E->get().arguments.size())
							options.insert(E->get().name+"(");
						else
							options.insert(E->get().name+"()");

					}
				} else {

					if (t.value.get_type()==Variant::NIL) {
						Variant::CallError ce;
						t.value=Variant::construct(t.type,NULL,0,ce);
					}

					if (!isfunction) {
						List<PropertyInfo> pl;
						t.value.get_property_list(&pl);
						for (List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {

							if (E->get().name.find("/")==-1)
								options.insert(E->get().name);
						}
					}

					List<MethodInfo> mi;
					t.value.get_method_list(&mi);
					for (List<MethodInfo>::Element *E=mi.front();E;E=E->next()) {
						if (E->get().arguments.size())
							options.insert(E->get().name+"(");
						else
							options.insert(E->get().name+"()");

					}
				}
			}


		} break;
		case GDParser::COMPLETION_CALL_ARGUMENTS: {

			_find_call_arguments(context,p.get_completion_node(),p.get_completion_line(),p.get_completion_argument_index(),options,r_call_hint);
		} break;


	}


	for(Set<String>::Element *E=options.front();E;E=E->next()) {
		r_options->push_back(E->get());
	}

	return OK;
}