mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 13:41:03 +00:00 
			
		
		
		
	-Ability to set default import presets for type
-More presets for scene importer -Option in scene importer to export root nodes as separate scenes -Fixed MeshInstance preview
This commit is contained in:
		
							parent
							
								
									380eae2cc0
								
							
						
					
					
						commit
						66009706c9
					
				
					 12 changed files with 348 additions and 223 deletions
				
			
		|  | @ -1239,7 +1239,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { | |||
| 	String importer_name; | ||||
| 
 | ||||
| 	if (FileAccess::exists(p_file + ".import")) { | ||||
| 
 | ||||
| 		//use existing
 | ||||
| 		Ref<ConfigFile> cf; | ||||
| 		cf.instance(); | ||||
| 		Error err = cf->load(p_file + ".import"); | ||||
|  | @ -1254,6 +1254,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { | |||
| 	} | ||||
| 
 | ||||
| 	Ref<ResourceImporter> importer; | ||||
| 	bool load_default = false; | ||||
| 	//find the importer
 | ||||
| 	if (importer_name != "") { | ||||
| 		importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name); | ||||
|  | @ -1262,6 +1263,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) { | |||
| 	if (importer.is_null()) { | ||||
| 		//not found by name, find by extension
 | ||||
| 		importer = ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_file.get_extension()); | ||||
| 		load_default = true; | ||||
| 		if (importer.is_null()) { | ||||
| 			ERR_PRINT("BUG: File queued for import, but can't be imported!"); | ||||
| 			ERR_FAIL(); | ||||
|  | @ -1278,6 +1280,17 @@ void EditorFileSystem::_reimport_file(const String &p_file) { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) { | ||||
| 		//use defaults if exist
 | ||||
| 		Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); | ||||
| 		List<Variant> v; | ||||
| 		d.get_key_list(&v); | ||||
| 
 | ||||
| 		for (List<Variant>::Element *E = v.front(); E; E = E->next()) { | ||||
| 			params[E->get()] = d[E->get()]; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	//finally, perform import!!
 | ||||
| 	String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file); | ||||
| 
 | ||||
|  |  | |||
|  | @ -6079,7 +6079,7 @@ EditorNode::EditorNode() { | |||
| 	add_editor_plugin(memnew(TextureEditorPlugin(this))); | ||||
| 	add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor))); | ||||
| 	//add_editor_plugin( memnew( MaterialEditorPlugin(this) ) );
 | ||||
| 	//add_editor_plugin( memnew( MeshEditorPlugin(this) ) );
 | ||||
| 	add_editor_plugin(memnew(MeshEditorPlugin(this))); | ||||
| 
 | ||||
| 	for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) | ||||
| 		add_editor_plugin(EditorPlugins::create(i, this)); | ||||
|  |  | |||
|  | @ -104,14 +104,27 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (p_option == "materials/keep_files" && int(p_options["materials/storage"]) == 0) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| int ResourceImporterScene::get_preset_count() const { | ||||
| 	return 0; | ||||
| 	return 6; | ||||
| } | ||||
| String ResourceImporterScene::get_preset_name(int p_idx) const { | ||||
| 
 | ||||
| 	switch (p_idx) { | ||||
| 		case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene"); | ||||
| 		case PRESET_SEPARATE_MATERIALS: return TTR("Import as Separate Materials"); | ||||
| 		case PRESET_SEPARATE_MESHES: return TTR("Import as Separate Objects"); | ||||
| 		case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import as Separate Objects+Materials"); | ||||
| 		case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes"); | ||||
| 		case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials"); | ||||
| 	} | ||||
| 
 | ||||
| 	return ""; | ||||
| } | ||||
| 
 | ||||
|  | @ -969,7 +982,7 @@ static String _make_extname(const String &p_str) { | |||
| 	return ext_name; | ||||
| } | ||||
| 
 | ||||
| void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { | ||||
| void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { | ||||
| 
 | ||||
| 	List<PropertyInfo> pi; | ||||
| 
 | ||||
|  | @ -984,8 +997,8 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String | |||
| 
 | ||||
| 				if (!p_materials.has(mat)) { | ||||
| 
 | ||||
| 					String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".material"; | ||||
| 					if (FileAccess::exists(ext_name)) { | ||||
| 					String ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material"); | ||||
| 					if (p_keep_materials && FileAccess::exists(ext_name)) { | ||||
| 						//if exists, use it
 | ||||
| 						Ref<Material> existing = ResourceLoader::load(ext_name); | ||||
| 						p_materials[mat] = existing; | ||||
|  | @ -1012,19 +1025,14 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String | |||
| 
 | ||||
| 						if (!p_meshes.has(mesh)) { | ||||
| 
 | ||||
| 							String ext_name = p_base_path + "." + _make_extname(mesh->get_name()) + ".mesh"; | ||||
| 							if (FileAccess::exists(ext_name)) { | ||||
| 								//if exists, use it
 | ||||
| 								Ref<ArrayMesh> existing = ResourceLoader::load(ext_name); | ||||
| 								p_meshes[mesh] = existing; | ||||
| 							} else { | ||||
| 							//meshes are always overwritten, keeping them is not practical
 | ||||
| 							String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh"); | ||||
| 
 | ||||
| 							ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH); | ||||
| 							p_meshes[mesh] = mesh; | ||||
| 							mesh_just_added = true; | ||||
| 						} | ||||
| 					} | ||||
| 					} | ||||
| 
 | ||||
| 					if (p_make_materials) { | ||||
| 
 | ||||
|  | @ -1067,7 +1075,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String | |||
| 
 | ||||
| 	for (int i = 0; i < p_node->get_child_count(); i++) { | ||||
| 
 | ||||
| 		_make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_make_meshes, p_materials, p_meshes); | ||||
| 		_make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_keep_materials, p_make_meshes, p_materials, p_meshes); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -1087,12 +1095,19 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in | |||
| 		script_ext_hint += "*." + E->get(); | ||||
| 	} | ||||
| 
 | ||||
| 	bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; | ||||
| 	bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS; | ||||
| 	bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; | ||||
| 
 | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), "")); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), 0)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Bult-In,Files"), 0)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), meshes_out ? 1 : 0)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Bult-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_files"), materials_out ? true : false)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "geometry/compress"), true)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "geometry/ensure_tangents"), true)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "geometry/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), 0)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "geometry/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? true : false)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), true)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); | ||||
| 	r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), "")); | ||||
|  | @ -1110,6 +1125,18 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) { | ||||
| 
 | ||||
| 	if (p_node != p_new_owner && p_node->get_owner() == p_scene) { | ||||
| 		p_node->set_owner(p_new_owner); | ||||
| 	} | ||||
| 
 | ||||
| 	for (int i = 0; i < p_node->get_child_count(); i++) { | ||||
| 		Node *n = p_node->get_child(i); | ||||
| 		_replace_owner(n, p_scene, p_new_owner); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { | ||||
| 
 | ||||
| 	String src_path = p_source_file; | ||||
|  | @ -1224,11 +1251,30 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p | |||
| 
 | ||||
| 	bool external_materials = p_options["materials/storage"]; | ||||
| 	bool external_meshes = p_options["geometry/storage"]; | ||||
| 	bool external_scenes = int(p_options["nodes/storage"]) == 1; | ||||
| 
 | ||||
| 	String base_path = p_source_file.get_base_dir(); | ||||
| 
 | ||||
| 	if (external_materials || external_meshes || external_scenes) { | ||||
| 
 | ||||
| 		if (bool(p_options["external_files/store_in_subdir"])) { | ||||
| 			String subdir_name = p_source_file.get_file().get_basename(); | ||||
| 			DirAccess *da = DirAccess::open(base_path); | ||||
| 			print_line("at path " + da->get_current_dir() + " making " + subdir_name); | ||||
| 			Error err = da->make_dir(subdir_name); | ||||
| 			memdelete(da); | ||||
| 			ERR_FAIL_COND_V(err != OK && err != ERR_ALREADY_EXISTS, err); | ||||
| 			base_path = base_path.plus_file(subdir_name); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (external_materials || external_meshes) { | ||||
| 		Map<Ref<Material>, Ref<Material> > mat_map; | ||||
| 		Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map; | ||||
| 		_make_external_resources(scene, p_source_file.get_basename(), external_materials, external_meshes, mat_map, mesh_map); | ||||
| 
 | ||||
| 		bool keep_materials = bool(p_options["materials/keep_files"]); | ||||
| 
 | ||||
| 		_make_external_resources(scene, base_path, external_materials, keep_materials, external_meshes, mat_map, mesh_map); | ||||
| 	} | ||||
| 
 | ||||
| 	progress.step(TTR("Running Custom Script.."), 2); | ||||
|  | @ -1263,10 +1309,33 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p | |||
| 
 | ||||
| 	progress.step(TTR("Saving.."), 104); | ||||
| 
 | ||||
| 	if (external_scenes) { | ||||
| 		//save sub-scenes as instances!
 | ||||
| 		for (int i = 0; i < scene->get_child_count(); i++) { | ||||
| 			Node *child = scene->get_child(i); | ||||
| 			if (child->get_owner() != scene) | ||||
| 				continue; //not a real child probably created by scene type (ig, a scrollbar)
 | ||||
| 			_replace_owner(child, scene, child); | ||||
| 
 | ||||
| 			String cn = String(child->get_name()).strip_edges().replace(".", "_").replace(":", "_"); | ||||
| 			if (cn == String()) { | ||||
| 				cn = "ChildNode" + itos(i); | ||||
| 			} | ||||
| 			String path = base_path.plus_file(cn + ".scn"); | ||||
| 			child->set_filename(path); | ||||
| 
 | ||||
| 			Ref<PackedScene> packer = memnew(PackedScene); | ||||
| 			packer->pack(child); | ||||
| 			err = ResourceSaver::save(path, packer); //do not take over, let the changed files reload themselves
 | ||||
| 			ERR_FAIL_COND_V(err != OK, err); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	Ref<PackedScene> packer = memnew(PackedScene); | ||||
| 	packer->pack(scene); | ||||
| 	print_line("SAVING TO: " + p_save_path + ".scn"); | ||||
| 	err = ResourceSaver::save(p_save_path + ".scn", packer); //do not take over, let the changed files reload themselves
 | ||||
| 	ERR_FAIL_COND_V(err != OK, err); | ||||
| 
 | ||||
| 	memdelete(scene); | ||||
| 
 | ||||
|  |  | |||
|  | @ -82,6 +82,17 @@ class ResourceImporterScene : public ResourceImporter { | |||
| 
 | ||||
| 	static ResourceImporterScene *singleton; | ||||
| 
 | ||||
| 	enum Presets { | ||||
| 		PRESET_SINGLE_SCENE, | ||||
| 		PRESET_SEPARATE_MATERIALS, | ||||
| 		PRESET_SEPARATE_MESHES, | ||||
| 		PRESET_SEPARATE_MESHES_AND_MATERIALS, | ||||
| 		PRESET_MULTIPLE_SCENES, | ||||
| 		PRESET_MULTIPLE_SCENES_AND_MATERIALS, | ||||
| 	}; | ||||
| 
 | ||||
| 	void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner); | ||||
| 
 | ||||
| public: | ||||
| 	static ResourceImporterScene *get_singleton() { return singleton; } | ||||
| 
 | ||||
|  | @ -101,7 +112,7 @@ public: | |||
| 	virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; | ||||
| 	virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; | ||||
| 
 | ||||
| 	void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); | ||||
| 	void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); | ||||
| 
 | ||||
| 	Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map); | ||||
| 
 | ||||
|  |  | |||
|  | @ -134,6 +134,14 @@ void ImportDock::set_edit_path(const String &p_path) { | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	preset->get_popup()->add_separator(); | ||||
| 	preset->get_popup()->add_item(vformat(TTR("Set as Default for '%s'"), params->importer->get_visible_name()), ITEM_SET_AS_DEFAULT); | ||||
| 	if (ProjectSettings::get_singleton()->has("importer_defaults/" + params->importer->get_importer_name())) { | ||||
| 		preset->get_popup()->add_item(TTR("Load Default"), ITEM_LOAD_DEFAULT); | ||||
| 		preset->get_popup()->add_separator(); | ||||
| 		preset->get_popup()->add_item(vformat(TTR("Clear Default for '%s'"), params->importer->get_visible_name()), ITEM_CLEAR_DEFAULT); | ||||
| 	} | ||||
| 
 | ||||
| 	params->paths.clear(); | ||||
| 	params->paths.push_back(p_path); | ||||
| 	import->set_disabled(false); | ||||
|  | @ -256,7 +264,44 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) { | |||
| 
 | ||||
| void ImportDock::_preset_selected(int p_idx) { | ||||
| 
 | ||||
| 	print_line("preset selected? " + p_idx); | ||||
| 	switch (p_idx) { | ||||
| 		case ITEM_SET_AS_DEFAULT: { | ||||
| 			List<ResourceImporter::ImportOption> options; | ||||
| 
 | ||||
| 			params->importer->get_import_options(&options, p_idx); | ||||
| 
 | ||||
| 			Dictionary d; | ||||
| 			for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { | ||||
| 
 | ||||
| 				d[E->get().option.name] = E->get().default_value; | ||||
| 			} | ||||
| 
 | ||||
| 			ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d); | ||||
| 			ProjectSettings::get_singleton()->save(); | ||||
| 
 | ||||
| 		} break; | ||||
| 		case ITEM_LOAD_DEFAULT: { | ||||
| 
 | ||||
| 			ERR_FAIL_COND(!ProjectSettings::get_singleton()->has("importer_defaults/" + params->importer->get_importer_name())); | ||||
| 
 | ||||
| 			Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + params->importer->get_importer_name()); | ||||
| 			List<Variant> v; | ||||
| 			d.get_key_list(&v); | ||||
| 
 | ||||
| 			for (List<Variant>::Element *E = v.front(); E; E = E->next()) { | ||||
| 				params->values[E->get()] = d[E->get()]; | ||||
| 			} | ||||
| 			params->update(); | ||||
| 
 | ||||
| 		} break; | ||||
| 		case ITEM_CLEAR_DEFAULT: { | ||||
| 
 | ||||
| 			ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), Variant()); | ||||
| 			ProjectSettings::get_singleton()->save(); | ||||
| 
 | ||||
| 		} break; | ||||
| 		default: { | ||||
| 
 | ||||
| 			List<ResourceImporter::ImportOption> options; | ||||
| 
 | ||||
| 			params->importer->get_import_options(&options, p_idx); | ||||
|  | @ -267,6 +312,8 @@ void ImportDock::_preset_selected(int p_idx) { | |||
| 			} | ||||
| 
 | ||||
| 			params->update(); | ||||
| 		} break; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void ImportDock::clear() { | ||||
|  |  | |||
|  | @ -57,6 +57,12 @@ class ImportDock : public VBoxContainer { | |||
| 
 | ||||
| 	void _reimport(); | ||||
| 
 | ||||
| 	enum { | ||||
| 		ITEM_SET_AS_DEFAULT = 100, | ||||
| 		ITEM_LOAD_DEFAULT, | ||||
| 		ITEM_CLEAR_DEFAULT, | ||||
| 	}; | ||||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,18 +29,17 @@ | |||
| /*************************************************************************/ | ||||
| #include "mesh_editor_plugin.h" | ||||
| 
 | ||||
| #if 0 | ||||
| void MeshEditor::_gui_input(InputEvent p_event) { | ||||
| void MeshEditor::_gui_input(Ref<InputEvent> p_event) { | ||||
| 
 | ||||
| 	Ref<InputEventMouseMotion> mm = p_event; | ||||
| 	if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) { | ||||
| 
 | ||||
| 	if (p_event.type==InputEvent::MOUSE_MOTION && p_event->get_button_mask()&BUTTON_MASK_LEFT) { | ||||
| 
 | ||||
| 		rot_x-=p_event->get_relative().y*0.01; | ||||
| 		rot_y-=p_event->get_relative().x*0.01; | ||||
| 		if (rot_x<-Math_PI/2) | ||||
| 			rot_x=-Math_PI/2; | ||||
| 		else if (rot_x>Math_PI/2) { | ||||
| 			rot_x=Math_PI/2; | ||||
| 		rot_x -= mm->get_relative().y * 0.01; | ||||
| 		rot_y -= mm->get_relative().x * 0.01; | ||||
| 		if (rot_x < -Math_PI / 2) | ||||
| 			rot_x = -Math_PI / 2; | ||||
| 		else if (rot_x > Math_PI / 2) { | ||||
| 			rot_x = Math_PI / 2; | ||||
| 		} | ||||
| 		_update_rotation(); | ||||
| 	} | ||||
|  | @ -48,35 +47,30 @@ void MeshEditor::_gui_input(InputEvent p_event) { | |||
| 
 | ||||
| void MeshEditor::_notification(int p_what) { | ||||
| 
 | ||||
| 	if (p_what==NOTIFICATION_FIXED_PROCESS) { | ||||
| 
 | ||||
| 	if (p_what == NOTIFICATION_FIXED_PROCESS) { | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	if (p_what==NOTIFICATION_READY) { | ||||
| 	if (p_what == NOTIFICATION_READY) { | ||||
| 
 | ||||
| 		//get_scene()->connect("node_removed",this,"_node_removed");
 | ||||
| 
 | ||||
| 		if (first_enter) { | ||||
| 			//it's in propertyeditor so.. could be moved around
 | ||||
| 			//it's in propertyeditor so. could be moved around
 | ||||
| 
 | ||||
| 			light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons")); | ||||
| 			light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons")); | ||||
| 			light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons")); | ||||
| 			light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons")); | ||||
| 			first_enter=false; | ||||
| 			light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1", "EditorIcons")); | ||||
| 			light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off", "EditorIcons")); | ||||
| 			light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2", "EditorIcons")); | ||||
| 			light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off", "EditorIcons")); | ||||
| 			first_enter = false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	} | ||||
| 	if (p_what == NOTIFICATION_DRAW) { | ||||
| 
 | ||||
| 	if (p_what==NOTIFICATION_DRAW) { | ||||
| 
 | ||||
| 
 | ||||
| 		Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons"); | ||||
| 		Ref<Texture> checkerboard = get_icon("Checkerboard", "EditorIcons"); | ||||
| 		Size2 size = get_size(); | ||||
| 
 | ||||
| 		draw_texture_rect(checkerboard,Rect2(Point2(),size),true); | ||||
| 
 | ||||
| 		//draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -85,125 +79,115 @@ void MeshEditor::_update_rotation() { | |||
| 	Transform t; | ||||
| 	t.basis.rotate(Vector3(0, 1, 0), -rot_y); | ||||
| 	t.basis.rotate(Vector3(1, 0, 0), -rot_x); | ||||
| 	mesh_instance->set_transform(t); | ||||
| 
 | ||||
| 	rotation->set_transform(t); | ||||
| } | ||||
| 
 | ||||
| void MeshEditor::edit(Ref<Mesh> p_mesh) { | ||||
| 
 | ||||
| 	mesh=p_mesh; | ||||
| 	mesh = p_mesh; | ||||
| 	mesh_instance->set_mesh(mesh); | ||||
| 
 | ||||
| 	if (mesh.is_null()) { | ||||
| 
 | ||||
| 		hide(); | ||||
| 	} else { | ||||
| 		rot_x=0; | ||||
| 		rot_y=0; | ||||
| 		rot_x = 0; | ||||
| 		rot_y = 0; | ||||
| 		_update_rotation(); | ||||
| 
 | ||||
| 		AABB aabb= mesh->get_aabb(); | ||||
| 		Vector3 ofs = aabb.pos + aabb.size*0.5; | ||||
| 		aabb.pos-=ofs; | ||||
| 		float m = MAX(aabb.size.x,aabb.size.y)*0.5; | ||||
| 		if (m!=0) { | ||||
| 			m=1.0/m; | ||||
| 			m*=0.5; | ||||
| 		Rect3 aabb = mesh->get_aabb(); | ||||
| 		print_line("aabb: " + aabb); | ||||
| 		Vector3 ofs = aabb.position + aabb.size * 0.5; | ||||
| 		float m = aabb.get_longest_axis_size(); | ||||
| 		if (m != 0) { | ||||
| 			m = 1.0 / m; | ||||
| 			m *= 0.5; | ||||
| 			//print_line("scale: "+rtos(m));
 | ||||
| 			Transform xform; | ||||
| 			xform.basis.scale(Vector3(m,m,m)); | ||||
| 			xform.origin=-xform.basis.xform(ofs); //-ofs*m;
 | ||||
| 			xform.origin.z-=aabb.size.z*2; | ||||
| 			xform.basis.scale(Vector3(m, m, m)); | ||||
| 			xform.origin = -xform.basis.xform(ofs); //-ofs*m;
 | ||||
| 			//xform.origin.z -= aabb.get_longest_axis_size() * 2;
 | ||||
| 			mesh_instance->set_transform(xform); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void MeshEditor::_button_pressed(Node *p_button) { | ||||
| 
 | ||||
| void MeshEditor::_button_pressed(Node* p_button) { | ||||
| 
 | ||||
| 	if (p_button==light_1_switch) { | ||||
| 		light1->set_enabled(!light_1_switch->is_pressed()); | ||||
| 	if (p_button == light_1_switch) { | ||||
| 		light1->set_visible(!light_1_switch->is_pressed()); | ||||
| 	} | ||||
| 
 | ||||
| 	if (p_button==light_2_switch) { | ||||
| 		light2->set_enabled(!light_2_switch->is_pressed()); | ||||
| 	if (p_button == light_2_switch) { | ||||
| 		light2->set_visible(!light_2_switch->is_pressed()); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void MeshEditor::_bind_methods() { | ||||
| 
 | ||||
| 	ClassDB::bind_method(D_METHOD("_gui_input"),&MeshEditor::_gui_input); | ||||
| 	ClassDB::bind_method(D_METHOD("_button_pressed"),&MeshEditor::_button_pressed); | ||||
| 
 | ||||
| 	ClassDB::bind_method(D_METHOD("_gui_input"), &MeshEditor::_gui_input); | ||||
| 	ClassDB::bind_method(D_METHOD("_button_pressed"), &MeshEditor::_button_pressed); | ||||
| } | ||||
| 
 | ||||
| MeshEditor::MeshEditor() { | ||||
| 
 | ||||
| 	viewport = memnew( Viewport ); | ||||
| 	viewport = memnew(Viewport); | ||||
| 	Ref<World> world; | ||||
| 	world.instance(); | ||||
| 	viewport->set_world(world); //use own world
 | ||||
| 	add_child(viewport); | ||||
| 	viewport->set_disable_input(true); | ||||
| 	set_stretch(true); | ||||
| 
 | ||||
| 	camera = memnew( Camera ); | ||||
| 	camera->set_transform(Transform(Matrix3(),Vector3(0,0,3))); | ||||
| 	camera->set_perspective(45,0.1,10); | ||||
| 	camera = memnew(Camera); | ||||
| 	camera->set_transform(Transform(Basis(), Vector3(0, 0, 1.1))); | ||||
| 	camera->set_perspective(45, 0.1, 10); | ||||
| 	viewport->add_child(camera); | ||||
| 
 | ||||
| 	light1 = memnew( DirectionalLight ); | ||||
| 	light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0))); | ||||
| 	light1 = memnew(DirectionalLight); | ||||
| 	light1->set_transform(Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); | ||||
| 	viewport->add_child(light1); | ||||
| 
 | ||||
| 	light2 = memnew( DirectionalLight ); | ||||
| 	light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1))); | ||||
| 	light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7)); | ||||
| 	light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7)); | ||||
| 	light2 = memnew(DirectionalLight); | ||||
| 	light2->set_transform(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); | ||||
| 	light2->set_color(Color(0.7, 0.7, 0.7)); | ||||
| 	viewport->add_child(light2); | ||||
| 
 | ||||
| 	mesh_instance = memnew( MeshInstance ); | ||||
| 	viewport->add_child(mesh_instance); | ||||
| 	rotation = memnew(Spatial); | ||||
| 	viewport->add_child(rotation); | ||||
| 	mesh_instance = memnew(MeshInstance); | ||||
| 	rotation->add_child(mesh_instance); | ||||
| 
 | ||||
| 	set_custom_minimum_size(Size2(1, 150) * EDSCALE); | ||||
| 
 | ||||
| 
 | ||||
| 	set_custom_minimum_size(Size2(1,150)*EDSCALE); | ||||
| 
 | ||||
| 	HBoxContainer *hb = memnew( HBoxContainer ); | ||||
| 	HBoxContainer *hb = memnew(HBoxContainer); | ||||
| 	add_child(hb); | ||||
| 	hb->set_area_as_parent_rect(2); | ||||
| 
 | ||||
| 	hb->add_spacer(); | ||||
| 
 | ||||
| 	VBoxContainer *vb_light = memnew( VBoxContainer ); | ||||
| 	VBoxContainer *vb_light = memnew(VBoxContainer); | ||||
| 	hb->add_child(vb_light); | ||||
| 
 | ||||
| 	light_1_switch = memnew( TextureButton ); | ||||
| 	light_1_switch = memnew(TextureButton); | ||||
| 	light_1_switch->set_toggle_mode(true); | ||||
| 	vb_light->add_child(light_1_switch); | ||||
| 	light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch)); | ||||
| 	light_1_switch->connect("pressed", this, "_button_pressed", varray(light_1_switch)); | ||||
| 
 | ||||
| 	light_2_switch = memnew( TextureButton ); | ||||
| 	light_2_switch = memnew(TextureButton); | ||||
| 	light_2_switch->set_toggle_mode(true); | ||||
| 	vb_light->add_child(light_2_switch); | ||||
| 	light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch)); | ||||
| 
 | ||||
| 	first_enter=true; | ||||
| 
 | ||||
| 	rot_x=0; | ||||
| 	rot_y=0; | ||||
| 	light_2_switch->connect("pressed", this, "_button_pressed", varray(light_2_switch)); | ||||
| 
 | ||||
| 	first_enter = true; | ||||
| 
 | ||||
| 	rot_x = 0; | ||||
| 	rot_y = 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void MeshEditorPlugin::edit(Object *p_object) { | ||||
| 
 | ||||
| 	Mesh * s = p_object->cast_to<Mesh>(); | ||||
| 	Mesh *s = p_object->cast_to<Mesh>(); | ||||
| 	if (!s) | ||||
| 		return; | ||||
| 
 | ||||
|  | @ -212,7 +196,7 @@ void MeshEditorPlugin::edit(Object *p_object) { | |||
| 
 | ||||
| bool MeshEditorPlugin::handles(Object *p_object) const { | ||||
| 
 | ||||
| 	return p_object->is_type("Mesh"); | ||||
| 	return p_object->is_class("Mesh"); | ||||
| } | ||||
| 
 | ||||
| void MeshEditorPlugin::make_visible(bool p_visible) { | ||||
|  | @ -225,22 +209,15 @@ void MeshEditorPlugin::make_visible(bool p_visible) { | |||
| 		mesh_editor->hide(); | ||||
| 		//mesh_editor->set_process(false);
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| MeshEditorPlugin::MeshEditorPlugin(EditorNode *p_node) { | ||||
| 
 | ||||
| 	editor=p_node; | ||||
| 	mesh_editor = memnew( MeshEditor ); | ||||
| 	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,mesh_editor); | ||||
| 	editor = p_node; | ||||
| 	mesh_editor = memnew(MeshEditor); | ||||
| 	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, mesh_editor); | ||||
| 	mesh_editor->hide(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| MeshEditorPlugin::~MeshEditorPlugin() | ||||
| { | ||||
| MeshEditorPlugin::~MeshEditorPlugin() { | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -30,8 +30,6 @@ | |||
| #ifndef MESH_EDITOR_PLUGIN_H | ||||
| #define MESH_EDITOR_PLUGIN_H | ||||
| 
 | ||||
| #if 0 | ||||
| 
 | ||||
| #include "editor/editor_node.h" | ||||
| #include "editor/editor_plugin.h" | ||||
| #include "scene/3d/camera.h" | ||||
|  | @ -39,51 +37,48 @@ | |||
| #include "scene/3d/mesh_instance.h" | ||||
| #include "scene/resources/material.h" | ||||
| 
 | ||||
| class MeshEditor : public Control { | ||||
| 
 | ||||
| 	GDCLASS(MeshEditor, Control); | ||||
| 
 | ||||
| class MeshEditor : public ViewportContainer { | ||||
| 
 | ||||
| 	GDCLASS(MeshEditor, ViewportContainer); | ||||
| 
 | ||||
| 	float rot_x; | ||||
| 	float rot_y; | ||||
| 
 | ||||
| 	Viewport *viewport; | ||||
| 	MeshInstance *mesh_instance; | ||||
| 	Spatial *rotation; | ||||
| 	DirectionalLight *light1; | ||||
| 	DirectionalLight *light2; | ||||
| 	Camera *camera; | ||||
| 
 | ||||
| 	Ref<Mesh> mesh; | ||||
| 
 | ||||
| 
 | ||||
| 	TextureButton *light_1_switch; | ||||
| 	TextureButton *light_2_switch; | ||||
| 
 | ||||
| 	void _button_pressed(Node* p_button); | ||||
| 	void _button_pressed(Node *p_button); | ||||
| 	bool first_enter; | ||||
| 
 | ||||
| 	void _update_rotation(); | ||||
| 
 | ||||
| protected: | ||||
| 	void _notification(int p_what); | ||||
| 	void _gui_input(InputEvent p_event); | ||||
| 	void _gui_input(Ref<InputEvent> p_event); | ||||
| 	static void _bind_methods(); | ||||
| public: | ||||
| 
 | ||||
| public: | ||||
| 	void edit(Ref<Mesh> p_mesh); | ||||
| 	MeshEditor(); | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| class MeshEditorPlugin : public EditorPlugin { | ||||
| 
 | ||||
| 	GDCLASS( MeshEditorPlugin, EditorPlugin ); | ||||
| 	GDCLASS(MeshEditorPlugin, EditorPlugin); | ||||
| 
 | ||||
| 	MeshEditor *mesh_editor; | ||||
| 	EditorNode *editor; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
| 	virtual String get_name() const { return "Mesh"; } | ||||
| 	bool has_main_screen() const { return false; } | ||||
| 	virtual void edit(Object *p_node); | ||||
|  | @ -92,8 +87,6 @@ public: | |||
| 
 | ||||
| 	MeshEditorPlugin(EditorNode *p_node); | ||||
| 	~MeshEditorPlugin(); | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #endif // MESH_EDITOR_PLUGIN_H
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ | |||
| #include "scene/resources/convex_polygon_shape.h" | ||||
| #include "surface_tool.h" | ||||
| 
 | ||||
| void Mesh::_clear_triangle_mesh() { | ||||
| void Mesh::_clear_triangle_mesh() const { | ||||
| 
 | ||||
| 	triangle_mesh.unref(); | ||||
| 	; | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ class Mesh : public Resource { | |||
| 
 | ||||
| 	mutable Ref<TriangleMesh> triangle_mesh; //cached
 | ||||
| protected: | ||||
| 	void _clear_triangle_mesh(); | ||||
| 	void _clear_triangle_mesh() const; | ||||
| 
 | ||||
| 	static void _bind_methods(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,42 +34,44 @@ | |||
| /**
 | ||||
|   PrimitiveMesh | ||||
| */ | ||||
| void PrimitiveMesh::_update() { | ||||
| 	if (!cache_is_dirty) | ||||
| 		return; | ||||
| void PrimitiveMesh::_update() const { | ||||
| 
 | ||||
| 	Array arr; | ||||
| 	arr.resize(VS::ARRAY_MAX); | ||||
| 	_create_mesh_array(arr); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points = arr[VS::ARRAY_VERTEX]; | ||||
| 
 | ||||
| 	aabb = Rect3(); | ||||
| 
 | ||||
| 	int pc = points.size(); | ||||
| 	ERR_FAIL_COND(pc == 0); | ||||
| 	{ | ||||
| 
 | ||||
| 		PoolVector<Vector3>::Read r = points.read(); | ||||
| 		for (int i = 0; i < pc; i++) { | ||||
| 			if (i == 0) | ||||
| 				aabb.position = r[i]; | ||||
| 			else | ||||
| 				aabb.expand_to(r[i]); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// in with the new
 | ||||
| 	VisualServer::get_singleton()->mesh_clear(mesh); | ||||
| 	VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr); | ||||
| 	VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); | ||||
| 
 | ||||
| 	cache_is_dirty = false; | ||||
| 	pending_request = false; | ||||
| 
 | ||||
| 	_clear_triangle_mesh(); | ||||
| 	emit_changed(); | ||||
| } | ||||
| 
 | ||||
| void PrimitiveMesh::_queue_update(bool p_first_mesh) { | ||||
| void PrimitiveMesh::_request_update() { | ||||
| 
 | ||||
| 	if (first_mesh && p_first_mesh) { | ||||
| 		first_mesh = false; | ||||
| 		cache_is_dirty = true; | ||||
| 		_update(); | ||||
| 	if (pending_request) | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!cache_is_dirty) { | ||||
| 		cache_is_dirty = true; | ||||
| 		call_deferred("_update"); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void PrimitiveMesh::set_aabb(Rect3 p_aabb) { | ||||
| 	aabb = p_aabb; | ||||
| 	_update(); | ||||
| } | ||||
| 
 | ||||
| int PrimitiveMesh::get_surface_count() const { | ||||
|  | @ -78,21 +80,37 @@ int PrimitiveMesh::get_surface_count() const { | |||
| 
 | ||||
| int PrimitiveMesh::surface_get_array_len(int p_idx) const { | ||||
| 	ERR_FAIL_INDEX_V(p_idx, 1, -1); | ||||
| 	if (pending_request) { | ||||
| 		_update(); | ||||
| 	} | ||||
| 
 | ||||
| 	return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0); | ||||
| } | ||||
| 
 | ||||
| int PrimitiveMesh::surface_get_array_index_len(int p_idx) const { | ||||
| 	ERR_FAIL_INDEX_V(p_idx, 1, -1); | ||||
| 	if (pending_request) { | ||||
| 		_update(); | ||||
| 	} | ||||
| 
 | ||||
| 	return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0); | ||||
| } | ||||
| 
 | ||||
| Array PrimitiveMesh::surface_get_arrays(int p_surface) const { | ||||
| 	ERR_FAIL_INDEX_V(p_surface, 1, Array()); | ||||
| 	if (pending_request) { | ||||
| 		_update(); | ||||
| 	} | ||||
| 
 | ||||
| 	return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0); | ||||
| } | ||||
| 
 | ||||
| uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { | ||||
| 	ERR_FAIL_INDEX_V(p_idx, 1, 0); | ||||
| 	if (pending_request) { | ||||
| 		_update(); | ||||
| 	} | ||||
| 
 | ||||
| 	return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0); | ||||
| } | ||||
| 
 | ||||
|  | @ -113,10 +131,17 @@ StringName PrimitiveMesh::get_blend_shape_name(int p_index) const { | |||
| } | ||||
| 
 | ||||
| Rect3 PrimitiveMesh::get_aabb() const { | ||||
| 	if (pending_request) { | ||||
| 		_update(); | ||||
| 	} | ||||
| 
 | ||||
| 	return aabb; | ||||
| } | ||||
| 
 | ||||
| RID PrimitiveMesh::get_rid() const { | ||||
| 	if (pending_request) { | ||||
| 		_update(); | ||||
| 	} | ||||
| 	return mesh; | ||||
| } | ||||
| 
 | ||||
|  | @ -131,10 +156,9 @@ void PrimitiveMesh::_bind_methods() { | |||
| 
 | ||||
| void PrimitiveMesh::set_material(const Ref<Material> &p_material) { | ||||
| 	material = p_material; | ||||
| 	if (!cache_is_dirty) { | ||||
| 	if (!pending_request) { | ||||
| 		// just apply it, else it'll happen when _update is called.
 | ||||
| 		VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid()); | ||||
| 
 | ||||
| 		_change_notify(); | ||||
| 		emit_changed(); | ||||
| 	}; | ||||
|  | @ -152,9 +176,7 @@ PrimitiveMesh::PrimitiveMesh() { | |||
| 	primitive_type = Mesh::PRIMITIVE_TRIANGLES; | ||||
| 
 | ||||
| 	// make sure we do an update after we've finished constructing our object
 | ||||
| 	cache_is_dirty = false; | ||||
| 	first_mesh = true; | ||||
| 	_queue_update(); | ||||
| 	pending_request = true; | ||||
| } | ||||
| 
 | ||||
| PrimitiveMesh::~PrimitiveMesh() { | ||||
|  | @ -165,7 +187,7 @@ PrimitiveMesh::~PrimitiveMesh() { | |||
| 	CapsuleMesh | ||||
| */ | ||||
| 
 | ||||
| void CapsuleMesh::_create_mesh_array(Array &p_arr) { | ||||
| void CapsuleMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	int i, j, prevrow, thisrow, point; | ||||
| 	float x, y, z, u, v, w; | ||||
| 	float onethird = 1.0 / 3.0; | ||||
|  | @ -173,8 +195,6 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) { | |||
| 
 | ||||
| 	// note, this has been aligned with our collision shape but I've left the descriptions as top/middle/bottom
 | ||||
| 
 | ||||
| 	set_aabb(Rect3(Vector3(-radius, -radius, (mid_height * -0.5) - radius), Vector3(radius * 2.0, radius * 2.0, mid_height + (2.0 * radius)))); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points; | ||||
| 	PoolVector<Vector3> normals; | ||||
| 	PoolVector<float> tangents; | ||||
|  | @ -334,7 +354,7 @@ void CapsuleMesh::_bind_methods() { | |||
| 
 | ||||
| void CapsuleMesh::set_radius(const float p_radius) { | ||||
| 	radius = p_radius; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float CapsuleMesh::get_radius() const { | ||||
|  | @ -343,7 +363,7 @@ float CapsuleMesh::get_radius() const { | |||
| 
 | ||||
| void CapsuleMesh::set_mid_height(const float p_mid_height) { | ||||
| 	mid_height = p_mid_height; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float CapsuleMesh::get_mid_height() const { | ||||
|  | @ -352,7 +372,7 @@ float CapsuleMesh::get_mid_height() const { | |||
| 
 | ||||
| void CapsuleMesh::set_radial_segments(const int p_segments) { | ||||
| 	radial_segments = p_segments > 4 ? p_segments : 4; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CapsuleMesh::get_radial_segments() const { | ||||
|  | @ -361,7 +381,7 @@ int CapsuleMesh::get_radial_segments() const { | |||
| 
 | ||||
| void CapsuleMesh::set_rings(const int p_rings) { | ||||
| 	rings = p_rings > 1 ? p_rings : 1; | ||||
| 	_queue_update(true); //last property set, force update mesh
 | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CapsuleMesh::get_rings() const { | ||||
|  | @ -380,7 +400,7 @@ CapsuleMesh::CapsuleMesh() { | |||
|   CubeMesh | ||||
| */ | ||||
| 
 | ||||
| void CubeMesh::_create_mesh_array(Array &p_arr) { | ||||
| void CubeMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	int i, j, prevrow, thisrow, point; | ||||
| 	float x, y, z; | ||||
| 	float onethird = 1.0 / 3.0; | ||||
|  | @ -389,7 +409,6 @@ void CubeMesh::_create_mesh_array(Array &p_arr) { | |||
| 	Vector3 start_pos = size * -0.5; | ||||
| 
 | ||||
| 	// set our bounding box
 | ||||
| 	set_aabb(Rect3(start_pos, size)); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points; | ||||
| 	PoolVector<Vector3> normals; | ||||
|  | @ -592,7 +611,7 @@ void CubeMesh::_bind_methods() { | |||
| 
 | ||||
| void CubeMesh::set_size(const Vector3 &p_size) { | ||||
| 	size = p_size; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| Vector3 CubeMesh::get_size() const { | ||||
|  | @ -601,7 +620,7 @@ Vector3 CubeMesh::get_size() const { | |||
| 
 | ||||
| void CubeMesh::set_subdivide_width(const int p_subdivide) { | ||||
| 	subdivide_w = p_subdivide > 0 ? p_subdivide : 0; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CubeMesh::get_subdivide_width() const { | ||||
|  | @ -610,7 +629,7 @@ int CubeMesh::get_subdivide_width() const { | |||
| 
 | ||||
| void CubeMesh::set_subdivide_height(const int p_subdivide) { | ||||
| 	subdivide_h = p_subdivide > 0 ? p_subdivide : 0; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CubeMesh::get_subdivide_height() const { | ||||
|  | @ -619,7 +638,7 @@ int CubeMesh::get_subdivide_height() const { | |||
| 
 | ||||
| void CubeMesh::set_subdivide_depth(const int p_subdivide) { | ||||
| 	subdivide_d = p_subdivide > 0 ? p_subdivide : 0; | ||||
| 	_queue_update(true); //last property set, force update mesh
 | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CubeMesh::get_subdivide_depth() const { | ||||
|  | @ -638,14 +657,12 @@ CubeMesh::CubeMesh() { | |||
|   CylinderMesh | ||||
| */ | ||||
| 
 | ||||
| void CylinderMesh::_create_mesh_array(Array &p_arr) { | ||||
| void CylinderMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	int i, j, prevrow, thisrow, point; | ||||
| 	float x, y, z, u, v, radius; | ||||
| 
 | ||||
| 	radius = bottom_radius > top_radius ? bottom_radius : top_radius; | ||||
| 
 | ||||
| 	set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points; | ||||
| 	PoolVector<Vector3> normals; | ||||
| 	PoolVector<float> tangents; | ||||
|  | @ -800,7 +817,7 @@ void CylinderMesh::_bind_methods() { | |||
| 
 | ||||
| void CylinderMesh::set_top_radius(const float p_radius) { | ||||
| 	top_radius = p_radius; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float CylinderMesh::get_top_radius() const { | ||||
|  | @ -809,7 +826,7 @@ float CylinderMesh::get_top_radius() const { | |||
| 
 | ||||
| void CylinderMesh::set_bottom_radius(const float p_radius) { | ||||
| 	bottom_radius = p_radius; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float CylinderMesh::get_bottom_radius() const { | ||||
|  | @ -818,7 +835,7 @@ float CylinderMesh::get_bottom_radius() const { | |||
| 
 | ||||
| void CylinderMesh::set_height(const float p_height) { | ||||
| 	height = p_height; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float CylinderMesh::get_height() const { | ||||
|  | @ -827,7 +844,7 @@ float CylinderMesh::get_height() const { | |||
| 
 | ||||
| void CylinderMesh::set_radial_segments(const int p_segments) { | ||||
| 	radial_segments = p_segments > 4 ? p_segments : 4; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CylinderMesh::get_radial_segments() const { | ||||
|  | @ -836,7 +853,7 @@ int CylinderMesh::get_radial_segments() const { | |||
| 
 | ||||
| void CylinderMesh::set_rings(const int p_rings) { | ||||
| 	rings = p_rings > 0 ? p_rings : 0; | ||||
| 	_queue_update(true); //last property set, force update mesh
 | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int CylinderMesh::get_rings() const { | ||||
|  | @ -856,14 +873,12 @@ CylinderMesh::CylinderMesh() { | |||
|   PlaneMesh | ||||
| */ | ||||
| 
 | ||||
| void PlaneMesh::_create_mesh_array(Array &p_arr) { | ||||
| void PlaneMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	int i, j, prevrow, thisrow, point; | ||||
| 	float x, z; | ||||
| 
 | ||||
| 	Size2 start_pos = size * -0.5; | ||||
| 
 | ||||
| 	set_aabb(Rect3(Vector3(start_pos.x, 0.0, start_pos.y), Vector3(size.x, 0.0, size.y))); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points; | ||||
| 	PoolVector<Vector3> normals; | ||||
| 	PoolVector<float> tangents; | ||||
|  | @ -935,7 +950,7 @@ void PlaneMesh::_bind_methods() { | |||
| 
 | ||||
| void PlaneMesh::set_size(const Size2 &p_size) { | ||||
| 	size = p_size; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| Size2 PlaneMesh::get_size() const { | ||||
|  | @ -944,7 +959,7 @@ Size2 PlaneMesh::get_size() const { | |||
| 
 | ||||
| void PlaneMesh::set_subdivide_width(const int p_subdivide) { | ||||
| 	subdivide_w = p_subdivide > 0 ? p_subdivide : 0; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int PlaneMesh::get_subdivide_width() const { | ||||
|  | @ -953,7 +968,7 @@ int PlaneMesh::get_subdivide_width() const { | |||
| 
 | ||||
| void PlaneMesh::set_subdivide_depth(const int p_subdivide) { | ||||
| 	subdivide_d = p_subdivide > 0 ? p_subdivide : 0; | ||||
| 	_queue_update(true); //last property set, force update mesh
 | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int PlaneMesh::get_subdivide_depth() const { | ||||
|  | @ -971,7 +986,7 @@ PlaneMesh::PlaneMesh() { | |||
|   PrismMesh | ||||
| */ | ||||
| 
 | ||||
| void PrismMesh::_create_mesh_array(Array &p_arr) { | ||||
| void PrismMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	int i, j, prevrow, thisrow, point; | ||||
| 	float x, y, z; | ||||
| 	float onethird = 1.0 / 3.0; | ||||
|  | @ -980,7 +995,6 @@ void PrismMesh::_create_mesh_array(Array &p_arr) { | |||
| 	Vector3 start_pos = size * -0.5; | ||||
| 
 | ||||
| 	// set our bounding box
 | ||||
| 	set_aabb(Rect3(start_pos, size)); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points; | ||||
| 	PoolVector<Vector3> normals; | ||||
|  | @ -1207,7 +1221,7 @@ void PrismMesh::_bind_methods() { | |||
| 
 | ||||
| void PrismMesh::set_left_to_right(const float p_left_to_right) { | ||||
| 	left_to_right = p_left_to_right; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float PrismMesh::get_left_to_right() const { | ||||
|  | @ -1216,7 +1230,7 @@ float PrismMesh::get_left_to_right() const { | |||
| 
 | ||||
| void PrismMesh::set_size(const Vector3 &p_size) { | ||||
| 	size = p_size; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| Vector3 PrismMesh::get_size() const { | ||||
|  | @ -1225,7 +1239,7 @@ Vector3 PrismMesh::get_size() const { | |||
| 
 | ||||
| void PrismMesh::set_subdivide_width(const int p_divisions) { | ||||
| 	subdivide_w = p_divisions > 0 ? p_divisions : 0; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int PrismMesh::get_subdivide_width() const { | ||||
|  | @ -1234,7 +1248,7 @@ int PrismMesh::get_subdivide_width() const { | |||
| 
 | ||||
| void PrismMesh::set_subdivide_height(const int p_divisions) { | ||||
| 	subdivide_h = p_divisions > 0 ? p_divisions : 0; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int PrismMesh::get_subdivide_height() const { | ||||
|  | @ -1243,7 +1257,7 @@ int PrismMesh::get_subdivide_height() const { | |||
| 
 | ||||
| void PrismMesh::set_subdivide_depth(const int p_divisions) { | ||||
| 	subdivide_d = p_divisions > 0 ? p_divisions : 0; | ||||
| 	_queue_update(true); //last property set, force update mesh
 | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int PrismMesh::get_subdivide_depth() const { | ||||
|  | @ -1263,7 +1277,7 @@ PrismMesh::PrismMesh() { | |||
|   QuadMesh | ||||
| */ | ||||
| 
 | ||||
| void QuadMesh::_create_mesh_array(Array &p_arr) { | ||||
| void QuadMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	PoolVector<Vector3> faces; | ||||
| 	PoolVector<Vector3> normals; | ||||
| 	PoolVector<float> tangents; | ||||
|  | @ -1312,19 +1326,17 @@ void QuadMesh::_bind_methods() { | |||
| 
 | ||||
| QuadMesh::QuadMesh() { | ||||
| 	primitive_type = PRIMITIVE_TRIANGLE_FAN; | ||||
| 	_queue_update(true); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|   SphereMesh | ||||
| */ | ||||
| 
 | ||||
| void SphereMesh::_create_mesh_array(Array &p_arr) { | ||||
| void SphereMesh::_create_mesh_array(Array &p_arr) const { | ||||
| 	int i, j, prevrow, thisrow, point; | ||||
| 	float x, y, z; | ||||
| 
 | ||||
| 	// set our bounding box
 | ||||
| 	set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0))); | ||||
| 
 | ||||
| 	PoolVector<Vector3> points; | ||||
| 	PoolVector<Vector3> normals; | ||||
|  | @ -1413,7 +1425,7 @@ void SphereMesh::_bind_methods() { | |||
| 
 | ||||
| void SphereMesh::set_radius(const float p_radius) { | ||||
| 	radius = p_radius; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float SphereMesh::get_radius() const { | ||||
|  | @ -1422,7 +1434,7 @@ float SphereMesh::get_radius() const { | |||
| 
 | ||||
| void SphereMesh::set_height(const float p_height) { | ||||
| 	height = p_height; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| float SphereMesh::get_height() const { | ||||
|  | @ -1431,7 +1443,7 @@ float SphereMesh::get_height() const { | |||
| 
 | ||||
| void SphereMesh::set_radial_segments(const int p_radial_segments) { | ||||
| 	radial_segments = p_radial_segments > 4 ? p_radial_segments : 4; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int SphereMesh::get_radial_segments() const { | ||||
|  | @ -1440,7 +1452,7 @@ int SphereMesh::get_radial_segments() const { | |||
| 
 | ||||
| void SphereMesh::set_rings(const int p_rings) { | ||||
| 	rings = p_rings > 1 ? p_rings : 1; | ||||
| 	_queue_update(); | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| int SphereMesh::get_rings() const { | ||||
|  | @ -1449,7 +1461,7 @@ int SphereMesh::get_rings() const { | |||
| 
 | ||||
| void SphereMesh::set_is_hemisphere(const bool p_is_hemisphere) { | ||||
| 	is_hemisphere = p_is_hemisphere; | ||||
| 	_queue_update(true); //last property set, force update mesh
 | ||||
| 	_request_update(); | ||||
| } | ||||
| 
 | ||||
| bool SphereMesh::get_is_hemisphere() const { | ||||
|  |  | |||
|  | @ -47,23 +47,20 @@ class PrimitiveMesh : public Mesh { | |||
| 
 | ||||
| private: | ||||
| 	RID mesh; | ||||
| 	Rect3 aabb; | ||||
| 	mutable Rect3 aabb; | ||||
| 
 | ||||
| 	Ref<Material> material; | ||||
| 
 | ||||
| 	bool first_mesh; | ||||
| 	bool cache_is_dirty; | ||||
| 	void _update(); | ||||
| 	mutable bool pending_request; | ||||
| 	void _update() const; | ||||
| 
 | ||||
| protected: | ||||
| 	Mesh::PrimitiveType primitive_type; | ||||
| 
 | ||||
| 	static void _bind_methods(); | ||||
| 
 | ||||
| 	virtual void _create_mesh_array(Array &p_arr) = 0; | ||||
| 	void _queue_update(bool p_first_mesh = false); //pretty bad hack to have the mesh built firt time parameters are set without delay
 | ||||
| 
 | ||||
| 	void set_aabb(Rect3 p_aabb); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const = 0; | ||||
| 	void _request_update(); | ||||
| 
 | ||||
| public: | ||||
| 	virtual int get_surface_count() const; | ||||
|  | @ -99,7 +96,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	void set_radius(const float p_radius); | ||||
|  | @ -132,7 +129,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	void set_size(const Vector3 &p_size); | ||||
|  | @ -167,7 +164,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	void set_top_radius(const float p_radius); | ||||
|  | @ -202,7 +199,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	void set_size(const Size2 &p_size); | ||||
|  | @ -233,7 +230,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	void set_left_to_right(const float p_left_to_right); | ||||
|  | @ -267,7 +264,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	QuadMesh(); | ||||
|  | @ -289,7 +286,7 @@ private: | |||
| 
 | ||||
| protected: | ||||
| 	static void _bind_methods(); | ||||
| 	virtual void _create_mesh_array(Array &p_arr); | ||||
| 	virtual void _create_mesh_array(Array &p_arr) const; | ||||
| 
 | ||||
| public: | ||||
| 	void set_radius(const float p_radius); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Juan Linietsky
						Juan Linietsky