From 27025092c0ad7d7b3f500d4ae1dabb7570daf813 Mon Sep 17 00:00:00 2001 From: Mikulas Florek Date: Wed, 18 Dec 2024 11:40:15 +0100 Subject: [PATCH] fbx import - properly handle empty meshes --- external/openfbx/ofbx.cpp | 17 ++++++++++++----- external/openfbx/ofbx.h | 11 +++++++++-- src/renderer/editor/fbx_importer.cpp | 2 ++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/external/openfbx/ofbx.cpp b/external/openfbx/ofbx.cpp index 83ba9e2afe..b2551b8b5f 100644 --- a/external/openfbx/ofbx.cpp +++ b/external/openfbx/ofbx.cpp @@ -1157,6 +1157,7 @@ struct GeometryPartitionImpl { }; struct GeometryDataImpl : GeometryData { + bool has_vertices = false; Vec3AttributesImpl positions; Vec3AttributesImpl normals; Vec3AttributesImpl tangents; @@ -1176,6 +1177,8 @@ struct GeometryDataImpl : GeometryData { return res; } + bool hasVertices() const override { return has_vertices; } + Vec3Attributes getPositions() const override { return positions; } Vec3Attributes getNormals() const override { return patchAttributes(normals); } Vec2Attributes getUVs(int index) const override { return patchAttributes(uvs[index]); } @@ -3126,16 +3129,22 @@ static OptionalError parseAnimationCurve(const Scene& scene, const Elem return curve; } -static OptionalError parseGeometry(const Element& element, GeometryImpl& geom, std::vector &jobs, bool ignore_geometry, Allocator& allocator) { +static OptionalError parseGeometry(const Element& element, GeometryImpl& geom, std::vector &jobs, u16 flags, Allocator& allocator) { assert(element.first_property); - if (!parseGeometryMaterials(geom, element, jobs)) return Error("Invalid materials"); + const bool ignore_geometry = (flags & (u16)LoadFlags::IGNORE_GEOMETRY) != 0; + const bool keep_matertial_map = (flags & (u16)LoadFlags::KEEP_MATERIAL_MAP) != 0; + + if (keep_matertial_map || !ignore_geometry) { + if (!parseGeometryMaterials(geom, element, jobs)) return Error("Invalid materials"); + } const Element* vertices_element = findChild(element, "Vertices"); if (!vertices_element || !vertices_element->first_property) { return &geom; } + geom.has_vertices = true; const Element* polys_element = findChild(element, "PolygonVertexIndex"); if (!polys_element || !polys_element->first_property) return Error("Indices missing"); @@ -3451,9 +3460,7 @@ static bool parseObjects(const Element& root, Scene& scene, u16 flags, Allocator if (last_prop && last_prop->value == "Mesh") { GeometryImpl* geom = allocator.allocate(scene, *iter.second.element); - if (!ignore_geometry || keep_matertial_map) { - parseGeometry(*iter.second.element, *geom, jobs, ignore_geometry, allocator); - } + parseGeometry(*iter.second.element, *geom, jobs, flags, allocator); obj = geom; scene.m_geometries.push_back(geom); } diff --git a/external/openfbx/ofbx.h b/external/openfbx/ofbx.h index 28154572c7..4717fc30af 100644 --- a/external/openfbx/ofbx.h +++ b/external/openfbx/ofbx.h @@ -536,6 +536,7 @@ struct GeometryPartition { const int triangles_count; // number of triangles after polygon triangulation, can be used for preallocation }; +// if we use LoadFlags::IGNORE_GEOMETRY, values here are empty/invalid, with a few exceptions struct GeometryData { virtual ~GeometryData() {} @@ -544,10 +545,16 @@ struct GeometryData { virtual Vec2Attributes getUVs(int index = 0) const = 0; virtual Vec4Attributes getColors() const = 0; virtual Vec3Attributes getTangents() const = 0; - virtual const int getMaterialMapSize() const = 0; - virtual const int* getMaterialMap() const = 0; virtual int getPartitionCount() const = 0; virtual GeometryPartition getPartition(int partition_index) const = 0; + + // if we use LoadFlags::KEEP_MATERIAL_MAP, following is valid even if we use IGNORE_GEOMETRY + virtual const int getMaterialMapSize() const = 0; + virtual const int* getMaterialMap() const = 0; + + // returns true if there are vertices in the geometry + // this has valid value even if we use LoadFlags::IGNORE_GEOMETRY + virtual bool hasVertices() const = 0; }; diff --git a/src/renderer/editor/fbx_importer.cpp b/src/renderer/editor/fbx_importer.cpp index 60016ee84c..8b95b245a3 100644 --- a/src/renderer/editor/fbx_importer.cpp +++ b/src/renderer/editor/fbx_importer.cpp @@ -1114,6 +1114,8 @@ struct FBXImporter : ModelImporter { // mark used materials/partitions StackArray used_materials(m_allocator); used_materials.resize(mat_count); + if (!geom.hasVertices()) continue; + if (mat_count == 1) { used_materials[0] = true; }