diff options
author | Daniel Rakos <daniel.rakos@rastergrid.com> | 2019-01-31 18:04:36 +0100 |
---|---|---|
committer | Daniel Rakos <daniel.rakos@rastergrid.com> | 2019-02-03 22:48:35 +0100 |
commit | 6df53e0401fd7c2f8e81cd7d8189584706d3d7d8 (patch) | |
tree | 8f2e5bcd00871fad3fd8a108e7dae51d9390f6c9 | |
parent | 463123a661151f119132f2ee9af78925a58a068a (diff) |
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.
-rw-r--r-- | doc/classes/ArrayMesh.xml | 11 | ||||
-rw-r--r-- | doc/classes/Mesh.xml | 11 | ||||
-rw-r--r-- | editor/editor_plugin.cpp | 43 | ||||
-rw-r--r-- | editor/editor_plugin.h | 2 | ||||
-rw-r--r-- | editor/plugins/mesh_library_editor_plugin.cpp | 30 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 2 | ||||
-rw-r--r-- | scene/resources/mesh.h | 5 | ||||
-rw-r--r-- | scene/resources/primitive_meshes.cpp | 6 | ||||
-rw-r--r-- | 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 bcb9b4f6da..42457b2da6 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. </description> </method> - <method name="surface_set_material"> - <return type="void"> - </return> - <argument index="0" name="surf_idx" type="int"> - </argument> - <argument index="1" name="material" type="Material"> - </argument> - <description> - Set a [Material] for a given surface. Surface will be rendered using this material. - </description> - </method> <method name="surface_set_name"> <return type="void"> </return> diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index 4852d4701d..d2a0849cc5 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. </description> </method> + <method name="surface_set_material"> + <return type="void"> + </return> + <argument index="0" name="surf_idx" type="int"> + </argument> + <argument index="1" name="material" type="Material"> + </argument> + <description> + Set a [Material] for a given surface. Surface will be rendered using this material. + </description> + </method> </methods> <members> <member name="lightmap_size_hint" type="Vector2" setter="set_lightmap_size_hint" getter="get_lightmap_size_hint"> diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index c2493729a3..ce7d07117c 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<Ref<Texture> > textures = make_mesh_previews(meshes, p_preview_size); + Vector<Ref<Texture> > 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<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, int p_preview_size) { +Vector<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, Vector<Transform> *p_transforms, int p_preview_size) { int size = p_preview_size; @@ -74,25 +74,14 @@ Vector<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> 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<Ref<Texture> > textures; @@ -104,25 +93,38 @@ Vector<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> textures.push_back(Ref<Texture>()); 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<Texture>()); 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<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> 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 3e41bb5612..52fe849eab 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<Ref<Texture> > make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, int p_preview_size); + Vector<Ref<Texture> > make_mesh_previews(const Vector<Ref<Mesh> > &p_meshes, Vector<Transform> *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 aedac7b45d..2622d14ade 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<MeshLibrary> p_library, if (!p_merge) p_library->clear(); + Map<int, MeshInstance *> 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<MeshLibrary> p_library, if (mesh.is_null()) continue; + mesh = mesh->duplicate(); + for (int j = 0; j < mesh->get_surface_count(); ++j) { + Ref<Material> 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<MeshLibrary> p_library, } p_library->set_item_mesh(id, mesh); + mesh_instances[id] = mi; Vector<MeshLibrary::ShapeData> collisions; @@ -155,14 +167,26 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, if (1) { Vector<Ref<Mesh> > meshes; + Vector<Transform> transforms; Vector<int> 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<Ref<Texture> > textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, EditorSettings::get_singleton()->get("editors/grid_map/preview_size")); + Vector<Ref<Texture> > 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 805d30245a..e8ac79bdff 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 2d0aef8ab0..193276da35 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<Material> &p_material) = 0; virtual Ref<Material> 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<Material> &p_material); - Ref<Material> surface_get_material(int p_idx) const; + virtual void surface_set_material(int p_idx, const Ref<Material> &p_material); + virtual Ref<Material> 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 9ef12aa4e6..48baab5f5e 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<Material> &p_material) { + ERR_FAIL_INDEX(p_idx, 1); + + set_material(p_material); +} + Ref<Material> 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 88a26801b7..0045a48736 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<Material> &p_material); virtual Ref<Material> surface_get_material(int p_idx) const; virtual int get_blend_shape_count() const; virtual StringName get_blend_shape_name(int p_index) const; |