Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Mesh handling on scene importing. #44319

Merged
merged 1 commit into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3654,6 +3654,9 @@ void EditorNode::register_editor_types() {
ClassDB::register_class<ScriptCreateDialog>();
ClassDB::register_class<EditorFeatureProfile>();
ClassDB::register_class<EditorSpinSlider>();
ClassDB::register_class<EditorSceneImporterMesh>();
ClassDB::register_class<EditorSceneImporterMeshNode>();

ClassDB::register_virtual_class<FileSystemDock>();

// FIXME: Is this stuff obsolete, or should it be ported to new APIs?
Expand Down
39 changes: 20 additions & 19 deletions editor/import/editor_import_collada.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}

/*****************/
Expand Down Expand Up @@ -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);

Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -1109,15 +1110,15 @@ 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 {
if (collada.state.mesh_data_map.has(meshid)) {
//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);
Expand Down
37 changes: 21 additions & 16 deletions editor/import/editor_scene_importer_gltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,15 +970,14 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
return OK;
}

uint32_t mesh_flags = 0;

Array meshes = state.json["meshes"];
for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
print_verbose("glTF: Parsing mesh: " + itos(i));
Dictionary d = meshes[i];

GLTFMesh mesh;
mesh.mesh.instance();
bool has_vertex_color = false;

ERR_FAIL_COND_V(!d.has("primitives"), ERR_PARSE_ERROR);

Expand Down Expand Up @@ -1034,6 +1033,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
}
if (a.has("COLOR_0")) {
array[Mesh::ARRAY_COLOR] = _decode_accessor_as_color(state, a["COLOR_0"], true);
has_vertex_color = true;
}
if (a.has("JOINTS_0")) {
array[Mesh::ARRAY_BONES] = _decode_accessor_as_ints(state, a["JOINTS_0"], true);
Expand Down Expand Up @@ -1112,7 +1112,7 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {

//ideally BLEND_SHAPE_MODE_RELATIVE since gltf2 stores in displacement
//but it could require a larger refactor?
mesh.mesh->set_blend_shape_mode(ArrayMesh::BLEND_SHAPE_MODE_NORMALIZED);
mesh.mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);

if (j == 0) {
const Array &target_names = extras.has("targetNames") ? (Array)extras["targetNames"] : Array();
Expand Down Expand Up @@ -1226,21 +1226,25 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
}

//just add it
mesh.mesh->add_surface_from_arrays(primitive, array, morphs, Dictionary(), mesh_flags);

Ref<Material> mat;
if (p.has("material")) {
const int material = p["material"];
ERR_FAIL_INDEX_V(material, state.materials.size(), ERR_FILE_CORRUPT);
const Ref<Material> &mat = state.materials[material];

mesh.mesh->surface_set_material(mesh.mesh->get_surface_count() - 1, mat);
} else {
Ref<StandardMaterial3D> mat;
mat.instance();
mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
Ref<StandardMaterial3D> mat3d = state.materials[material];
if (has_vertex_color) {
mat3d->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
}
mat = mat3d;

mesh.mesh->surface_set_material(mesh.mesh->get_surface_count() - 1, mat);
} else if (has_vertex_color) {
Ref<StandardMaterial3D> mat3d;
mat3d.instance();
mat3d->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
mat = mat3d;
}

mesh.mesh->add_surface(primitive, array, morphs, Dictionary(), mat);
}

mesh.blend_weights.resize(mesh.mesh->get_blend_shape_count());
Expand Down Expand Up @@ -1440,7 +1444,8 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
if (d.has("name")) {
material->set_name(d["name"]);
}
material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
//don't do this here only if vertex color exists
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the albedo code was touched i have to reverify that the test cases don't regress #21087 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag is less optimal if turned on, so I only make it on when needed

//material->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);

if (d.has("pbrMetallicRoughness")) {
const Dictionary &mr = d["pbrMetallicRoughness"];
Expand Down Expand Up @@ -2586,12 +2591,12 @@ BoneAttachment3D *EditorSceneImporterGLTF::_generate_bone_attachment(GLTFState &
return bone_attachment;
}

MeshInstance3D *EditorSceneImporterGLTF::_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
EditorSceneImporterMeshNode *EditorSceneImporterGLTF::_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
const GLTFNode *gltf_node = state.nodes[node_index];

ERR_FAIL_INDEX_V(gltf_node->mesh, state.meshes.size(), nullptr);

MeshInstance3D *mi = memnew(MeshInstance3D);
EditorSceneImporterMeshNode *mi = memnew(EditorSceneImporterMeshNode);
print_verbose("glTF: Creating mesh for: " + gltf_node->name);

GLTFMesh &mesh = state.meshes.write[gltf_node->mesh];
Expand Down Expand Up @@ -3058,7 +3063,7 @@ void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Node3D *
const GLTFSkinIndex skin_i = node->skin;

Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get());
EditorSceneImporterMeshNode *mi = Object::cast_to<EditorSceneImporterMeshNode>(mi_element->get());
ERR_FAIL_COND(mi == nullptr);

const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton;
Expand Down
8 changes: 4 additions & 4 deletions editor/import/editor_scene_importer_gltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

class AnimationPlayer;
class BoneAttachment3D;
class MeshInstance3D;
class EditorSceneImporterMeshNode;

class EditorSceneImporterGLTF : public EditorSceneImporter {
GDCLASS(EditorSceneImporterGLTF, EditorSceneImporter);
Expand Down Expand Up @@ -199,7 +199,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
};

struct GLTFMesh {
Ref<ArrayMesh> mesh;
Ref<EditorSceneImporterMesh> mesh;
Vector<float> blend_weights;
};

Expand Down Expand Up @@ -262,7 +262,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<GLTFAccessor> accessors;

Vector<GLTFMesh> meshes; //meshes are loaded directly, no reason not to.
Vector<Ref<Material>> materials;
Vector<Ref<StandardMaterial3D>> materials;

String scene_name;
Vector<int> root_nodes;
Expand Down Expand Up @@ -355,7 +355,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Error _parse_animations(GLTFState &state);

BoneAttachment3D *_generate_bone_attachment(GLTFState &state, Skeleton3D *skeleton, const GLTFNodeIndex node_index);
MeshInstance3D *_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
EditorSceneImporterMeshNode *_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
Camera3D *_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
Light3D *_generate_light(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
Node3D *_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
Expand Down
26 changes: 22 additions & 4 deletions editor/import/resource_importer_obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
String current_material_library;
String current_material;
String current_group;
uint32_t smooth_group = 0;
bool smoothing = true;

while (true) {
String l = f->get_line().strip_edges();
Expand Down Expand Up @@ -315,17 +317,26 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
Vector3 vertex = vertices[vtx];
//if (weld_vertices)
// vertex.snap(Vector3(weld_tolerance, weld_tolerance, weld_tolerance));
if (!smoothing) {
smooth_group++;
}
surf_tool->set_smooth_group(smooth_group);
surf_tool->add_vertex(vertex);
}

face[1] = face[2];
}
} else if (l.begins_with("s ")) { //smoothing
String what = l.substr(2, l.length()).strip_edges();
bool do_smooth;
if (what == "off") {
surf_tool->add_smooth_group(false);
do_smooth = false;
} else {
surf_tool->add_smooth_group(true);
do_smooth = true;
}
if (do_smooth != smoothing) {
smooth_group++;
smoothing = do_smooth;
}
} else if (/*l.begins_with("g ") ||*/ l.begins_with("usemtl ") || (l.begins_with("o ") || f->eof_reached())) { //commit group to mesh
//groups are too annoying
Expand Down Expand Up @@ -426,8 +437,15 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
Node3D *scene = memnew(Node3D);

for (List<Ref<Mesh>>::Element *E = meshes.front(); E; E = E->next()) {
MeshInstance3D *mi = memnew(MeshInstance3D);
mi->set_mesh(E->get());
Ref<EditorSceneImporterMesh> mesh;
mesh.instance();
Ref<Mesh> m = E->get();
for (int i = 0; i < m->get_surface_count(); i++) {
mesh->add_surface(m->surface_get_primitive_type(i), m->surface_get_arrays(i), Array(), Dictionary(), m->surface_get_material(i));
}

EditorSceneImporterMeshNode *mi = memnew(EditorSceneImporterMeshNode);
mi->set_mesh(mesh);
mi->set_name(E->get()->get_name());
scene->add_child(mi);
mi->set_owner(scene);
Expand Down
Loading