From 6df53e0401fd7c2f8e81cd7d8189584706d3d7d8 Mon Sep 17 00:00:00 2001 From: Daniel Rakos Date: Thu, 31 Jan 2019 18:04:36 +0100 Subject: [PATCH] MeshLibrary export improvements - From now materials assigned to the MeshInstance (not the Mesh) get exported into the MeshLibrary when such materials exist. This enables workflows where the MeshLibrary is exported from an imported scene (e.g. GLTF) where the materials assigned to the Mesh (not the MeshInstance) get overwritten on re-import, thus can't use editor set materials in the exported MeshLibrary unless they are assigned to the MeshInstance whose materials get saved with the inherited scene thus persist across re-imports. - When appending to an existing MeshLibrary only generate previews for newly added or modified meshes. - During preview generation transform camera and lights instead of the mesh and use the source MeshInstance's transform for the mesh to avoid weird previews being generated for meshes with a position dependent material (e.g. when using triplanar mapping). - Adjust the camera angle and light directions used in mesh preview generation for better results. --- doc/classes/ArrayMesh.xml | 11 ----- doc/classes/Mesh.xml | 11 +++++ editor/editor_plugin.cpp | 43 ++++++++++--------- editor/editor_plugin.h | 2 +- editor/plugins/mesh_library_editor_plugin.cpp | 30 +++++++++++-- scene/resources/mesh.cpp | 2 +- scene/resources/mesh.h | 5 ++- scene/resources/primitive_meshes.cpp | 6 +++ scene/resources/primitive_meshes.h | 1 + 9 files changed, 72 insertions(+), 39 deletions(-) diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index bcb9b4f6dae..42457b2da64 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -164,17 +164,6 @@ Remove a surface at position surf_idx, shifting greater surfaces one surf_idx slot down. - - - - - - - - - Set a [Material] for a given surface. Surface will be rendered using this material. - - diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index 4852d4701d0..d2a0849cc51 100644 --- a/doc/classes/Mesh.xml +++ b/doc/classes/Mesh.xml @@ -82,6 +82,17 @@ Return a [Material] in a given surface. Surface is rendered using this material. + + + + + + + + + Set a [Material] for a given surface. Surface will be rendered using this material. + + diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index c2493729a3c..ce7d07117c8 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -48,7 +48,7 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_ meshes.push_back(p_meshes[i]); } - Vector > textures = make_mesh_previews(meshes, p_preview_size); + Vector > textures = make_mesh_previews(meshes, NULL, p_preview_size); Array ret; for (int i = 0; i < textures.size(); i++) { ret.push_back(textures[i]); @@ -57,7 +57,7 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_ return ret; } -Vector > EditorInterface::make_mesh_previews(const Vector > &p_meshes, int p_preview_size) { +Vector > EditorInterface::make_mesh_previews(const Vector > &p_meshes, Vector *p_transforms, int p_preview_size) { int size = p_preview_size; @@ -74,25 +74,14 @@ Vector > EditorInterface::make_mesh_previews(const Vector RID camera = VS::get_singleton()->camera_create(); VS::get_singleton()->viewport_attach_camera(viewport, camera); - VS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3))); - //VS::get_singleton()->camera_set_perspective(camera,45,0.1,10); - VS::get_singleton()->camera_set_orthogonal(camera, 1.0, 0.01, 1000.0); RID light = VS::get_singleton()->directional_light_create(); RID light_instance = VS::get_singleton()->instance_create2(light, scenario); - VS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0))); RID light2 = VS::get_singleton()->directional_light_create(); VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7)); - //VS::get_singleton()->light_set_color(light2, VS::LIGHT_COLOR_SPECULAR, Color(0.0, 0.0, 0.0)); RID light_instance2 = VS::get_singleton()->instance_create2(light2, scenario); - VS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1))); - - //sphere = VS::get_singleton()->mesh_create(); - RID mesh_instance = VS::get_singleton()->instance_create(); - VS::get_singleton()->instance_set_scenario(mesh_instance, scenario); - EditorProgress ep("mlib", TTR("Creating Mesh Previews"), p_meshes.size()); Vector > textures; @@ -104,25 +93,38 @@ Vector > EditorInterface::make_mesh_previews(const Vector textures.push_back(Ref()); continue; } + + Transform mesh_xform; + if (p_transforms != NULL) { + mesh_xform = (*p_transforms)[i]; + } + + RID inst = VS::get_singleton()->instance_create2(mesh->get_rid(), scenario); + VS::get_singleton()->instance_set_transform(inst, mesh_xform); + AABB aabb = mesh->get_aabb(); Vector3 ofs = aabb.position + aabb.size * 0.5; aabb.position -= ofs; Transform xform; - xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.25); - xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.25) * xform.basis; + xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI / 6); + xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI / 6) * xform.basis; AABB rot_aabb = xform.xform(aabb); float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5; if (m == 0) { textures.push_back(Ref()); continue; } - m = 1.0 / m; - m *= 0.5; - xform.basis.scale(Vector3(m, m, m)); xform.origin = -xform.basis.xform(ofs); //-ofs*m; xform.origin.z -= rot_aabb.size.z * 2; - RID inst = VS::get_singleton()->instance_create2(mesh->get_rid(), scenario); - VS::get_singleton()->instance_set_transform(inst, xform); + xform.invert(); + xform = mesh_xform * xform; + + VS::get_singleton()->camera_set_transform(camera, xform * Transform(Basis(), Vector3(0, 0, 3))); + VS::get_singleton()->camera_set_orthogonal(camera, m * 2, 0.01, 1000.0); + + VS::get_singleton()->instance_set_transform(light_instance, xform * Transform().looking_at(Vector3(-2, -1, -1), Vector3(0, 1, 0))); + VS::get_singleton()->instance_set_transform(light_instance2, xform * Transform().looking_at(Vector3(+1, -1, -2), Vector3(0, 1, 0))); + ep.step(TTR("Thumbnail..."), i); Main::iteration(); Main::iteration(); @@ -136,7 +138,6 @@ Vector > EditorInterface::make_mesh_previews(const Vector textures.push_back(it); } - VS::get_singleton()->free(mesh_instance); VS::get_singleton()->free(viewport); VS::get_singleton()->free(light); VS::get_singleton()->free(light_instance); diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index 3e41bb56128..52fe849eab2 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -98,7 +98,7 @@ public: Error save_scene(); void save_scene_as(const String &p_scene, bool p_with_preview = true); - Vector > make_mesh_previews(const Vector > &p_meshes, int p_preview_size); + Vector > make_mesh_previews(const Vector > &p_meshes, Vector *p_trnasforms, int p_preview_size); EditorInterface(); }; diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp index aedac7b45d4..2622d14ade7 100644 --- a/editor/plugins/mesh_library_editor_plugin.cpp +++ b/editor/plugins/mesh_library_editor_plugin.cpp @@ -70,6 +70,8 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref p_library, if (!p_merge) p_library->clear(); + Map mesh_instances; + for (int i = 0; i < p_scene->get_child_count(); i++) { Node *child = p_scene->get_child(i); @@ -90,6 +92,15 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref p_library, if (mesh.is_null()) continue; + mesh = mesh->duplicate(); + for (int j = 0; j < mesh->get_surface_count(); ++j) { + Ref mat = mi->get_surface_material(j); + + if (mat.is_valid()) { + mesh->surface_set_material(j, mat); + } + } + int id = p_library->find_item_by_name(mi->get_name()); if (id < 0) { @@ -99,6 +110,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref p_library, } p_library->set_item_mesh(id, mesh); + mesh_instances[id] = mi; Vector collisions; @@ -155,14 +167,26 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref p_library, if (1) { Vector > meshes; + Vector transforms; Vector ids = p_library->get_item_list(); for (int i = 0; i < ids.size(); i++) { - meshes.push_back(p_library->get_item_mesh(ids[i])); + + if (mesh_instances.find(ids[i])) { + + meshes.push_back(p_library->get_item_mesh(ids[i])); + transforms.push_back(mesh_instances[ids[i]]->get_transform()); + } } - Vector > textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, EditorSettings::get_singleton()->get("editors/grid_map/preview_size")); + Vector > textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, &transforms, EditorSettings::get_singleton()->get("editors/grid_map/preview_size")); + int j = 0; for (int i = 0; i < ids.size(); i++) { - p_library->set_item_preview(ids[i], textures[i]); + + if (mesh_instances.find(ids[i])) { + + p_library->set_item_preview(ids[i], textures[j]); + j++; + } } } } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 805d30245a6..e8ac79bdff7 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -487,6 +487,7 @@ void Mesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count); ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays); ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &Mesh::surface_get_blend_shape_arrays); + ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &Mesh::surface_set_material); ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &Mesh::surface_get_material); BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); @@ -1288,7 +1289,6 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len); ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format); ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type); - ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &ArrayMesh::surface_set_material); ClassDB::bind_method(D_METHOD("surface_find_by_name", "name"), &ArrayMesh::surface_find_by_name); ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name); ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 2d0aef8ab05..193276da35b 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -127,6 +127,7 @@ public: virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0; virtual uint32_t surface_get_format(int p_idx) const = 0; virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0; + virtual void surface_set_material(int p_idx, const Ref &p_material) = 0; virtual Ref surface_get_material(int p_idx) const = 0; virtual int get_blend_shape_count() const = 0; virtual StringName get_blend_shape_name(int p_index) const = 0; @@ -208,8 +209,8 @@ public: PrimitiveType surface_get_primitive_type(int p_idx) const; bool surface_is_alpha_sorting_enabled(int p_idx) const; - void surface_set_material(int p_idx, const Ref &p_material); - Ref surface_get_material(int p_idx) const; + virtual void surface_set_material(int p_idx, const Ref &p_material); + virtual Ref surface_get_material(int p_idx) const; int surface_find_by_name(const String &p_name) const; void surface_set_name(int p_idx, const String &p_name); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 9ef12aa4e6f..48baab5f5e1 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -157,6 +157,12 @@ Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { return primitive_type; } +void PrimitiveMesh::surface_set_material(int p_idx, const Ref &p_material) { + ERR_FAIL_INDEX(p_idx, 1); + + set_material(p_material); +} + Ref PrimitiveMesh::surface_get_material(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, NULL); diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 88a26801b74..0045a487368 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -72,6 +72,7 @@ public: virtual Array surface_get_blend_shape_arrays(int p_surface) const; virtual uint32_t surface_get_format(int p_idx) const; virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const; + virtual void surface_set_material(int p_idx, const Ref &p_material); virtual Ref surface_get_material(int p_idx) const; virtual int get_blend_shape_count() const; virtual StringName get_blend_shape_name(int p_index) const;