mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 04:06:14 +00:00
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.
This commit is contained in:
parent
463123a661
commit
6df53e0401
@ -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>
|
||||
|
@ -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">
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user