1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-10 13:00:37 +00:00

Rework Mesh handling on scene importing.

-Reworked how meshes are treated by importer by using EditorSceneImporterMesh and EditorSceneImporterMeshNode. Instead of Mesh and MeshInstance, this allows more efficient processing of meshes before they are actually registered in the RenderingServer.
-Integrated MeshOptimizer
-Reworked internals of SurfaceTool to use arrays, making it more performant and easy to run optimizatons on.
This commit is contained in:
reduz
2020-12-12 09:06:59 -03:00
parent 06314c1b0e
commit 77a045e902
33 changed files with 8600 additions and 241 deletions

View File

@@ -67,7 +67,7 @@ struct ColladaImport {
Map<String, NodeMap> node_map; //map from collada node to engine node
Map<String, String> node_name_map; //map from collada node to engine node
Map<String, Ref<ArrayMesh>> mesh_cache;
Map<String, Ref<EditorSceneImporterMesh>> mesh_cache;
Map<String, Ref<Curve3D>> curve_cache;
Map<String, Ref<Material>> material_cache;
Map<Collada::Node *, Skeleton3D *> skeleton_map;
@@ -83,7 +83,7 @@ struct ColladaImport {
Error _create_scene(Collada::Node *p_node, Node3D *p_parent);
Error _create_resources(Collada::Node *p_node, bool p_use_compression);
Error _create_material(const String &p_target);
Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes = Vector<Ref<ArrayMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false);
Error _create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes = Vector<Ref<EditorSceneImporterMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false);
Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false, bool p_use_compression = false);
void _fix_param_animation_tracks();
void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
@@ -278,8 +278,8 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
node = memnew(Path3D);
} else {
//mesh since nothing else
node = memnew(MeshInstance3D);
//Object::cast_to<MeshInstance3D>(node)->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
node = memnew(EditorSceneImporterMeshNode);
//Object::cast_to<EditorSceneImporterMeshNode>(node)->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
}
} break;
case Collada::Node::TYPE_SKELETON: {
@@ -440,7 +440,7 @@ Error ColladaImport::_create_material(const String &p_target) {
return OK;
}
Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) {
Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImporterMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<EditorSceneImporterMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) {
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
if (p_morph_data) {
@@ -457,9 +457,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
p_mesh->add_blend_shape(name);
}
if (p_morph_data->mode == "RELATIVE") {
p_mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_RELATIVE);
p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_RELATIVE);
} else if (p_morph_data->mode == "NORMALIZED") {
p_mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED);
p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
}
}
@@ -897,7 +897,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
////////////////////////////
for (int mi = 0; mi < p_morph_meshes.size(); mi++) {
Array a = p_morph_meshes[mi]->surface_get_arrays(surface);
Array a = p_morph_meshes[mi]->get_surface_arrays(surface);
//add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not)
if (has_weights) {
@@ -910,14 +910,15 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
mr.push_back(a);
}
p_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), 0);
String surface_name;
Ref<Material> mat;
if (material.is_valid()) {
if (p_use_mesh_material) {
p_mesh->surface_set_material(surface, material);
mat = material;
}
p_mesh->surface_set_name(surface, material->get_name());
surface_name = material->get_name();
}
p_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES, d, mr, Dictionary(), mat, surface_name);
}
/*****************/
@@ -1002,10 +1003,10 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
}
if (Object::cast_to<MeshInstance3D>(node)) {
if (Object::cast_to<EditorSceneImporterMeshNode>(node)) {
Collada::NodeGeometry *ng2 = static_cast<Collada::NodeGeometry *>(p_node);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(node);
EditorSceneImporterMeshNode *mi = Object::cast_to<EditorSceneImporterMeshNode>(node);
ERR_FAIL_COND_V(!mi, ERR_BUG);
@@ -1014,7 +1015,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
String meshid;
Transform apply_xform;
Vector<int> bone_remap;
Vector<Ref<ArrayMesh>> morphs;
Vector<Ref<EditorSceneImporterMesh>> morphs;
if (ng2->controller) {
String ngsource = ng2->source;
@@ -1083,10 +1084,10 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
for (int i = 0; i < names.size(); i++) {
String meshid2 = names[i];
if (collada.state.mesh_data_map.has(meshid2)) {
Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<EditorSceneImporterMesh> mesh = Ref<EditorSceneImporterMesh>(memnew(EditorSceneImporterMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
mesh->set_name(meshdata.name);
Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, nullptr, Vector<Ref<ArrayMesh>>(), false);
Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, nullptr, Vector<Ref<EditorSceneImporterMesh>>(), false);
ERR_FAIL_COND_V(err, err);
morphs.push_back(mesh);
@@ -1109,7 +1110,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
meshid = ng2->source;
}
Ref<ArrayMesh> mesh;
Ref<EditorSceneImporterMesh> mesh;
if (mesh_cache.has(meshid)) {
mesh = mesh_cache[meshid];
} else {
@@ -1117,7 +1118,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
//bleh, must ignore invalid
ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid), ERR_INVALID_DATA);
mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
mesh = Ref<EditorSceneImporterMesh>(memnew(EditorSceneImporterMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
mesh->set_name(meshdata.name);
Error err = _create_mesh_surfaces(morphs.size() == 0, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, p_use_compression, use_mesh_builtin_materials);