diff --git a/src/ofbx.cpp b/src/ofbx.cpp index 93210fa..83ba9e2 100644 --- a/src/ofbx.cpp +++ b/src/ofbx.cpp @@ -1182,7 +1182,10 @@ struct GeometryDataImpl : GeometryData { Vec4Attributes getColors() const override { return patchAttributes(colors); } Vec3Attributes getTangents() const override { return patchAttributes(tangents); } int getPartitionCount() const override { return (int)partitions.size(); } - + + const int getMaterialMapSize() const override { return (int)materials.size(); } + const int* getMaterialMap() const override { return materials.empty() ? nullptr : &materials[0]; } + GeometryPartition getPartition(int index) const override { if (index >= partitions.size()) return {nullptr, 0, 0, 0}; return { @@ -3123,26 +3126,28 @@ static OptionalError parseAnimationCurve(const Scene& scene, const Elem return curve; } -static OptionalError parseGeometry(const Element& element, GeometryImpl& geom, std::vector &jobs, Allocator& allocator) { +static OptionalError parseGeometry(const Element& element, GeometryImpl& geom, std::vector &jobs, bool ignore_geometry, Allocator& allocator) { assert(element.first_property); + if (!parseGeometryMaterials(geom, element, jobs)) return Error("Invalid materials"); + const Element* vertices_element = findChild(element, "Vertices"); - if (!vertices_element || !vertices_element->first_property) - { + if (!vertices_element || !vertices_element->first_property) { return &geom; } const Element* polys_element = findChild(element, "PolygonVertexIndex"); if (!polys_element || !polys_element->first_property) return Error("Indices missing"); - if (!pushJob(jobs, *vertices_element->first_property, geom.positions.values)) return Error("Invalid vertices"); - if (!pushJob(jobs, *polys_element->first_property, geom.positions.indices)) return Error("Invalid vertices"); + if (!ignore_geometry) { + if (!pushJob(jobs, *vertices_element->first_property, geom.positions.values)) return Error("Invalid vertices"); + if (!pushJob(jobs, *polys_element->first_property, geom.positions.indices)) return Error("Invalid vertices"); - if (!parseGeometryMaterials(geom, element, jobs)) return Error("Invalid materials"); - if (!parseGeometryUVs(geom, element, jobs)) return Error("Invalid vertex attributes"); - if (!parseGeometryTangents(geom, element, jobs)) return Error("Invalid vertex attributes"); - if (!parseGeometryColors(geom, element, jobs)) return Error("Invalid vertex attributes"); - if (!parseGeometryNormals(geom, element, jobs)) return Error("Invalid vertex attributes"); + if (!parseGeometryUVs(geom, element, jobs)) return Error("Invalid vertex attributes"); + if (!parseGeometryTangents(geom, element, jobs)) return Error("Invalid vertex attributes"); + if (!parseGeometryColors(geom, element, jobs)) return Error("Invalid vertex attributes"); + if (!parseGeometryNormals(geom, element, jobs)) return Error("Invalid vertex attributes"); + } return &geom; } @@ -3406,6 +3411,7 @@ static bool parseObjects(const Element& root, Scene& scene, u16 flags, Allocator const bool ignore_limbs = (flags & (u16)LoadFlags::IGNORE_LIMBS) != 0; const bool ignore_meshes = (flags & (u16)LoadFlags::IGNORE_MESHES) != 0; const bool ignore_models = (flags & (u16)LoadFlags::IGNORE_MODELS) != 0; + const bool keep_matertial_map = (flags & (u16)LoadFlags::KEEP_MATERIAL_MAP) != 0; const Element* objs = findChild(root, "Objects"); if (!objs) return true; @@ -3438,18 +3444,20 @@ static bool parseObjects(const Element& root, Scene& scene, u16 flags, Allocator if (iter.second.object == scene.m_root) continue; - if (iter.second.element->id == "Geometry" && !ignore_geometry) + if (iter.second.element->id == "Geometry") { Property* last_prop = iter.second.element->first_property; while (last_prop->next) last_prop = last_prop->next; if (last_prop && last_prop->value == "Mesh") { GeometryImpl* geom = allocator.allocate(scene, *iter.second.element); - parseGeometry(*iter.second.element, *geom, jobs, allocator); + if (!ignore_geometry || keep_matertial_map) { + parseGeometry(*iter.second.element, *geom, jobs, ignore_geometry, allocator); + } obj = geom; scene.m_geometries.push_back(geom); } - else if (last_prop && last_prop->value == "Shape") + else if (last_prop && last_prop->value == "Shape" && !ignore_geometry) { obj = allocator.allocate(scene, *iter.second.element); } diff --git a/src/ofbx.h b/src/ofbx.h index 6c0edef..2815457 100644 --- a/src/ofbx.h +++ b/src/ofbx.h @@ -30,7 +30,7 @@ using JobProcessor = void (*)(JobFunction, void*, void*, u32, u32); enum class LoadFlags : u16 { NONE = 0, - UNUSED = 1 << 0, // can be reused + KEEP_MATERIAL_MAP = 1 << 0, // keep material map even if IGNORE_GEOMETRY is used IGNORE_GEOMETRY = 1 << 1, IGNORE_BLEND_SHAPES = 1 << 2, IGNORE_CAMERAS = 1 << 3, @@ -544,6 +544,8 @@ 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; };