Skip to content

Commit

Permalink
fbx import - properly handle empty meshes
Browse files Browse the repository at this point in the history
  • Loading branch information
nem0 committed Dec 18, 2024
1 parent 90f6b5e commit 2702509
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
17 changes: 12 additions & 5 deletions external/openfbx/ofbx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@ struct GeometryPartitionImpl {
};

struct GeometryDataImpl : GeometryData {
bool has_vertices = false;
Vec3AttributesImpl positions;
Vec3AttributesImpl normals;
Vec3AttributesImpl tangents;
Expand All @@ -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<Vec3Attributes>(normals); }
Vec2Attributes getUVs(int index) const override { return patchAttributes<Vec2Attributes>(uvs[index]); }
Expand Down Expand Up @@ -3126,16 +3129,22 @@ static OptionalError<Object*> parseAnimationCurve(const Scene& scene, const Elem
return curve;
}

static OptionalError<Object*> parseGeometry(const Element& element, GeometryImpl& geom, std::vector<ParseDataJob> &jobs, bool ignore_geometry, Allocator& allocator) {
static OptionalError<Object*> parseGeometry(const Element& element, GeometryImpl& geom, std::vector<ParseDataJob> &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");

Expand Down Expand Up @@ -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<GeometryImpl>(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);
}
Expand Down
11 changes: 9 additions & 2 deletions external/openfbx/ofbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand All @@ -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;
};


Expand Down
2 changes: 2 additions & 0 deletions src/renderer/editor/fbx_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,8 @@ struct FBXImporter : ModelImporter {
// mark used materials/partitions
StackArray<bool, 16> used_materials(m_allocator);
used_materials.resize(mat_count);
if (!geom.hasVertices()) continue;

if (mat_count == 1) {
used_materials[0] = true;
}
Expand Down

0 comments on commit 2702509

Please sign in to comment.