From c4395b9b92285a3bd807f89f5e519219ed78d8cd Mon Sep 17 00:00:00 2001 From: hhalen Date: Thu, 18 Apr 2019 16:20:36 -0700 Subject: [PATCH] Change gltf structures representing weights and jointIds to single data structure to make code cleaner and simplify further generalization. Added array versions of AttributeDefinition and AddAttributeToPrimitive to facilitate this. --- src/FBX2glTF.cpp | 8 +-- src/gltf/GltfModel.hpp | 25 +++++++ src/gltf/Raw2Gltf.cpp | 86 ++++++------------------- src/gltf/Raw2Gltf.hpp | 38 +++++++++++ src/gltf/properties/PrimitiveData.hpp | 26 ++++++++ src/raw/RawModel.cpp | 93 ++++++--------------------- src/raw/RawModel.hpp | 50 +++++++++----- 7 files changed, 164 insertions(+), 162 deletions(-) diff --git a/src/FBX2glTF.cpp b/src/FBX2glTF.cpp index b5ae8b0..d31a62d 100644 --- a/src/FBX2glTF.cpp +++ b/src/FBX2glTF.cpp @@ -140,10 +140,11 @@ int main(int argc, char* argv[]) { gltfOptions.useBlendShapeTangents, "Include blend shape tangents, if reported present by the FBX SDK."); - app.add_flag( + app.add_option( "--normalize-weights", gltfOptions.normalizeSkinningWeights, - "Normalize skinning weights."); + "Normalize skinning weights.", + true); app.add_option( "--skinning-weights", @@ -156,8 +157,7 @@ int main(int argc, char* argv[]) { "-k,--keep-attribute", [&](std::vector attributes) -> bool { gltfOptions.keepAttribs = - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0 | RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1 | - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2 | RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3; + RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS; for (std::string attribute : attributes) { if (attribute == "position") { gltfOptions.keepAttribs |= RAW_VERTEX_ATTRIBUTE_POSITION; diff --git a/src/gltf/GltfModel.hpp b/src/gltf/GltfModel.hpp index f82b09f..502d37a 100644 --- a/src/gltf/GltfModel.hpp +++ b/src/gltf/GltfModel.hpp @@ -123,6 +123,31 @@ class GltfModel { return accessor; }; + template + std::shared_ptr AddAttributeArrayToPrimitive( + BufferData& buffer, + const RawModel& surfaceModel, + PrimitiveData& primitive, + const AttributeArrayDefinition& attrDef) { + // copy attribute data into vector + std::vector attribArr; + surfaceModel.GetArrayAttributeArray(attribArr, attrDef.rawAttributeIx, attrDef.arrayOffset); + + std::shared_ptr accessor; + if (attrDef.dracoComponentType != draco::DT_INVALID && primitive.dracoMesh != nullptr) { + primitive.AddDracoArrayAttrib(attrDef, attribArr); + + accessor = accessors.hold(new AccessorData(attrDef.glType)); + accessor->count = attribArr.size(); + } + else { + auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER); + accessor = AddAccessorWithView(*bufferView, attrDef.glType, attribArr, std::string("")); + } + primitive.AddAttrib(attrDef.gltfName, *accessor); + return accessor; + }; + template void serializeHolder(json& glTFJson, std::string key, const Holder holder) { if (!holder.ptrs.empty()) { diff --git a/src/gltf/Raw2Gltf.cpp b/src/gltf/Raw2Gltf.cpp index 15834a9..880bd37 100644 --- a/src/gltf/Raw2Gltf.cpp +++ b/src/gltf/Raw2Gltf.cpp @@ -532,77 +532,31 @@ ModelData* Raw2Gltf( draco::DT_FLOAT32); gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_TEXCOORD_1); } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0) != 0) { - const AttributeDefinition ATTR_JOINTS( - "JOINTS_0", - &RawVertex::jointIndices0, + if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) != 0) { + for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) { + const AttributeArrayDefinition ATTR_JOINTS( + std::string("JOINTS_") + std::to_string(i/4), + //"JOINTS_0", + &RawVertex::jointIndices, GLT_VEC4I, draco::GeometryAttribute::GENERIC, - draco::DT_UINT16); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_JOINTS); + draco::DT_UINT16, + i/4); + gltf->AddAttributeArrayToPrimitive(buffer, surfaceModel, *primitive, ATTR_JOINTS); + } } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0) != 0) { - const AttributeDefinition ATTR_WEIGHTS( - "WEIGHTS_0", - &RawVertex::jointWeights0, + if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) != 0) { + for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) { + const AttributeArrayDefinition ATTR_WEIGHTS( + std::string("WEIGHTS_") + std::to_string(i/4), + //"WEIGHTS_0", + &RawVertex::jointWeights, GLT_VEC4F, draco::GeometryAttribute::GENERIC, - draco::DT_FLOAT32); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_WEIGHTS); - } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1) != 0) { - const AttributeDefinition ATTR_JOINTS( - "JOINTS_1", - &RawVertex::jointIndices1, - GLT_VEC4I, - draco::GeometryAttribute::GENERIC, - draco::DT_UINT16); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_JOINTS); - } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1) != 0) { - const AttributeDefinition ATTR_WEIGHTS( - "WEIGHTS_1", - &RawVertex::jointWeights1, - GLT_VEC4F, - draco::GeometryAttribute::GENERIC, - draco::DT_FLOAT32); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_WEIGHTS); - } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2) != 0) { - const AttributeDefinition ATTR_JOINTS( - "JOINTS_0", - &RawVertex::jointIndices2, - GLT_VEC4I, - draco::GeometryAttribute::GENERIC, - draco::DT_UINT16); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_JOINTS); - } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2) != 0) { - const AttributeDefinition ATTR_WEIGHTS( - "WEIGHTS_0", - &RawVertex::jointWeights2, - GLT_VEC4F, - draco::GeometryAttribute::GENERIC, - draco::DT_FLOAT32); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_WEIGHTS); - } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3) != 0) { - const AttributeDefinition ATTR_JOINTS( - "JOINTS_0", - &RawVertex::jointIndices3, - GLT_VEC4I, - draco::GeometryAttribute::GENERIC, - draco::DT_UINT16); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_JOINTS); - } - if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3) != 0) { - const AttributeDefinition ATTR_WEIGHTS( - "WEIGHTS_0", - &RawVertex::jointWeights3, - GLT_VEC4F, - draco::GeometryAttribute::GENERIC, - draco::DT_FLOAT32); - gltf->AddAttributeToPrimitive(buffer, surfaceModel, *primitive, ATTR_WEIGHTS); + draco::DT_FLOAT32, + i/4); + gltf->AddAttributeArrayToPrimitive(buffer, surfaceModel, *primitive, ATTR_WEIGHTS); + } } // each channel present in the mesh always ends up a target in the primitive diff --git a/src/gltf/Raw2Gltf.hpp b/src/gltf/Raw2Gltf.hpp index 0dbdc6e..fb0d6c9 100644 --- a/src/gltf/Raw2Gltf.hpp +++ b/src/gltf/Raw2Gltf.hpp @@ -154,6 +154,44 @@ struct AttributeDefinition { glType(_glType), dracoAttribute(draco::GeometryAttribute::INVALID), dracoComponentType(draco::DataType::DT_INVALID) {} + + AttributeDefinition( + const std::string gltfName, + const T RawVertex::*rawAttributeIx, + const GLType& _glType, + const draco::GeometryAttribute::Type dracoAttribute, + const draco::DataType dracoComponentType, + const int arrayOffset) + : gltfName(gltfName), + rawAttributeIx(rawAttributeIx), + glType(_glType), + dracoAttribute(dracoAttribute), + dracoComponentType(dracoComponentType), + arrayOffset(arrayOffset){} +}; + +template +struct AttributeArrayDefinition { + const std::string gltfName; + const T (RawVertex::*rawAttributeIx)[(RawModel::MAX_SUPPORTED_WEIGHTS -1 ) / 4 + 1]; + const GLType glType; + const int arrayOffset; + const draco::GeometryAttribute::Type dracoAttribute; + const draco::DataType dracoComponentType; + + AttributeArrayDefinition( + const std::string gltfName, + const T (RawVertex::*rawAttributeIx)[(RawModel::MAX_SUPPORTED_WEIGHTS - 1) / 4 + 1], + const GLType& _glType, + const draco::GeometryAttribute::Type dracoAttribute, + const draco::DataType dracoComponentType, + const int arrayOffset) + : gltfName(gltfName), + rawAttributeIx(rawAttributeIx), + glType(_glType), + dracoAttribute(dracoAttribute), + dracoComponentType(dracoComponentType), + arrayOffset(arrayOffset) {} }; struct AccessorData; diff --git a/src/gltf/properties/PrimitiveData.hpp b/src/gltf/properties/PrimitiveData.hpp index 16bf7e9..81ba4b1 100644 --- a/src/gltf/properties/PrimitiveData.hpp +++ b/src/gltf/properties/PrimitiveData.hpp @@ -62,6 +62,32 @@ struct PrimitiveData { dracoAttributes[attribute.gltfName] = dracoAttId; } + template + void AddDracoArrayAttrib(const AttributeArrayDefinition attribute, const std::vector& attribArr) { + draco::PointAttribute att; + int8_t componentCount = attribute.glType.count; + att.Init( + attribute.dracoAttribute, + nullptr, + componentCount, + attribute.dracoComponentType, + false, + componentCount * draco::DataTypeLength(attribute.dracoComponentType), + 0); + + const int dracoAttId = dracoMesh->AddAttribute(att, true, attribArr.size()); + draco::PointAttribute* attPtr = dracoMesh->attribute(dracoAttId); + + std::vector buf(sizeof(T)); + for (uint32_t ii = 0; ii < attribArr.size(); ii++) { + uint8_t* ptr = &buf[0]; + attribute.glType.write(ptr, attribArr[ii]); + attPtr->SetAttributeValue(attPtr->mapped_index(draco::PointIndex(ii)), ptr); + } + + dracoAttributes[attribute.gltfName] = dracoAttId; + } + void NoteDracoBuffer(const BufferViewData& data); const int indices; diff --git a/src/raw/RawModel.cpp b/src/raw/RawModel.cpp index cefa9e5..7977ccf 100644 --- a/src/raw/RawModel.cpp +++ b/src/raw/RawModel.cpp @@ -27,10 +27,7 @@ bool RawVertex::operator==(const RawVertex& other) const { return (position == other.position) && (normal == other.normal) && (tangent == other.tangent) && (binormal == other.binormal) && (color == other.color) && (uv0 == other.uv0) && (uv1 == other.uv1) && - (jointWeights0 == other.jointWeights0) && (jointWeights1 == other.jointWeights1) && - (jointWeights2 == other.jointWeights2) && (jointWeights3 == other.jointWeights3) && - (jointIndices0 == other.jointIndices0) && (jointIndices1 == other.jointIndices1) && - (jointIndices2 == other.jointIndices2) && (jointIndices3 == other.jointIndices3) && + (jointWeights == other.jointWeights) && (jointIndices == other.jointIndices) && (polarityUv0 == other.polarityUv0) && (blendSurfaceIx == other.blendSurfaceIx) && (blends == other.blends); } @@ -59,17 +56,8 @@ size_t RawVertex::Difference(const RawVertex& other) const { attributes |= RAW_VERTEX_ATTRIBUTE_UV1; } // Always need both or neither. - if (jointIndices0 != other.jointIndices0 || jointWeights0 != other.jointWeights0) { - attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0; - } - if (jointIndices1 != other.jointIndices1 || jointWeights1 != other.jointWeights1) { - attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1; - } - if (jointIndices2 != other.jointIndices2 || jointWeights2 != other.jointWeights2) { - attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2; - } - if (jointIndices3 != other.jointIndices3 || jointWeights3 != other.jointWeights3) { - attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3; + if (jointIndices != other.jointIndices || jointWeights != other.jointWeights) { + attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS; } return attributes; } @@ -409,7 +397,7 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight } { - int globalMaxWeights = 0; + globalMaxWeights = 0; for (auto& vertex: vertices) { // Sort from largest to smallest weight. @@ -432,26 +420,15 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight } if (globalMaxWeights > 0) { - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0); - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0); - } - if (globalMaxWeights > 1) { - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1); - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1); - } - if (globalMaxWeights > 2) { - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2); - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2); - } - if (globalMaxWeights > 3) { - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3); - AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3); + AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES); + AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS); } + assert(globalMaxWeights <= RawModel::MAX_SUPPORTED_WEIGHTS); // Copy to gltf friendly structure for (auto& vertex : vertices) { - for (int i = 0; i < globalMaxWeights; i += 4) { // Ensure all vertices have the same number of streams + for (int i = 0; i < globalMaxWeights; i += 4) { Vec4f weights{0.0}; Vec4i jointIds{0,0,0,0}; for (int j = i; j < i + 4 && j < vertex.skinningInfo.size(); j++) { @@ -459,26 +436,8 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight jointIds[j - i] = vertex.skinningInfo[j].jointIndex; } const int vertexStream = i / 4; - switch (vertexStream) { - case 0: - vertex.jointIndices0 = jointIds; - vertex.jointWeights0 = weights; - break; - case 1: - vertex.jointIndices1 = jointIds; - vertex.jointWeights1 = weights; - break; - case 2: - vertex.jointIndices2 = jointIds; - vertex.jointWeights2 = weights; - break; - case 3: - vertex.jointIndices3 = jointIds; - vertex.jointWeights3 = weights; - break; - default: - assert(0); - } + vertex.jointIndices[vertexStream] = jointIds; + vertex.jointWeights[vertexStream] = weights; } } } @@ -631,6 +590,7 @@ void RawModel::CreateMaterialModels( surfaces[sortedTriangles[i - 1].surfaceIndex].discrete))) { materialModels.resize(materialModels.size() + 1); model = &materialModels[materialModels.size() - 1]; + model->globalMaxWeights = globalMaxWeights; } // FIXME: will have to unlink from the nodes, transform both surfaces into a @@ -658,8 +618,7 @@ void RawModel::CreateMaterialModels( if (keepAttribs != -1) { int keep = keepAttribs; if ((keepAttribs & RAW_VERTEX_ATTRIBUTE_POSITION) != 0) { - keep |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0 | RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1 | - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2 | RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3; + keep |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS; } if ((keepAttribs & RAW_VERTEX_ATTRIBUTE_AUTO) != 0) { keep |= RAW_VERTEX_ATTRIBUTE_POSITION; @@ -700,29 +659,13 @@ void RawModel::CreateMaterialModels( if ((keep & RAW_VERTEX_ATTRIBUTE_UV1) == 0) { vertex.uv1 = defaultVertex.uv1; } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0) == 0) { - vertex.jointIndices0 = defaultVertex.jointIndices0; + if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) == 0) { + for (int i = 0; i < RawModel::MAX_SUPPORTED_WEIGHTS ; i++) + vertex.jointIndices[i] = defaultVertex.jointIndices[i]; } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0) == 0) { - vertex.jointWeights0 = defaultVertex.jointWeights0; - } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1) == 0) { - vertex.jointIndices1 = defaultVertex.jointIndices1; - } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1) == 0) { - vertex.jointWeights1 = defaultVertex.jointWeights1; - } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2) == 0) { - vertex.jointIndices2 = defaultVertex.jointIndices2; - } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2) == 0) { - vertex.jointWeights2 = defaultVertex.jointWeights2; - } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3) == 0) { - vertex.jointIndices3 = defaultVertex.jointIndices3; - } - if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3) == 0) { - vertex.jointWeights3 = defaultVertex.jointWeights3; + if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) == 0) { + for (int i = 0; i < RawModel::MAX_SUPPORTED_WEIGHTS; i++) + vertex.jointWeights[i] = defaultVertex.jointWeights[i]; } } diff --git a/src/raw/RawModel.hpp b/src/raw/RawModel.hpp index 2f42f31..45fe3a9 100644 --- a/src/raw/RawModel.hpp +++ b/src/raw/RawModel.hpp @@ -15,6 +15,8 @@ #include "FBX2glTF.h" +#define MAX_SKINNING_WEIGHTS 32 + enum RawVertexAttribute { RAW_VERTEX_ATTRIBUTE_POSITION = 1 << 0, RAW_VERTEX_ATTRIBUTE_NORMAL = 1 << 1, @@ -23,14 +25,8 @@ enum RawVertexAttribute { RAW_VERTEX_ATTRIBUTE_COLOR = 1 << 4, RAW_VERTEX_ATTRIBUTE_UV0 = 1 << 5, RAW_VERTEX_ATTRIBUTE_UV1 = 1 << 6, - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0 = 1 << 7, - RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0 = 1 << 8, - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1 = 1 << 9, - RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1 = 1 << 10, - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2 = 1 << 11, - RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2 = 1 << 12, - RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3 = 1 << 13, - RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3 = 1 << 14, + RAW_VERTEX_ATTRIBUTE_JOINT_INDICES = 1 << 7, + RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS = 1 << 8, RAW_VERTEX_ATTRIBUTE_AUTO = 1 << 31 }; @@ -65,14 +61,9 @@ struct RawVertex { Vec4f color{0.0f}; Vec2f uv0{0.0f}; Vec2f uv1{0.0f}; - Vec4i jointIndices0{0,0,0,0}; - Vec4i jointIndices1{0,0,0,0}; - Vec4i jointIndices2{0,0,0,0}; - Vec4i jointIndices3{0,0,0,0}; - Vec4f jointWeights0{0.0f}; - Vec4f jointWeights1{0.0f}; - Vec4f jointWeights2{0.0f}; - Vec4f jointWeights3{0.0f}; + Vec4i jointIndices[(MAX_SKINNING_WEIGHTS - 1) / 4 + 1]; + Vec4f jointWeights[(MAX_SKINNING_WEIGHTS - 1) / 4 + 1]; + std::vector skinningInfo; // end of members that directly correspond to vertex attributes @@ -381,7 +372,7 @@ struct RawNode { class RawModel { public: - static const int MAX_SUPPORTED_WEIGHTS = 16; + static const int MAX_SUPPORTED_WEIGHTS = MAX_SKINNING_WEIGHTS; RawModel(); @@ -460,6 +451,11 @@ class RawModel { int GetVertexCount() const { return (int)vertices.size(); } + + int GetGlobalWeightCount() const{ + return globalMaxWeights; + } + const RawVertex& GetVertex(const int index) const { return vertices[index]; } @@ -542,6 +538,14 @@ class RawModel { void GetAttributeArray(std::vector<_attrib_type_>& out, const _attrib_type_ RawVertex::*ptr) const; + // Create individual attribute arrays, with the source as an array. + // Returns true if the vertices store the particular attribute. + template + void GetArrayAttributeArray(std::vector<_attrib_type_>& out, + const _attrib_type_ (RawVertex::*ptr)[(RawModel::MAX_SUPPORTED_WEIGHTS - 1) / 4 + 1], + const int arrayOffset) + const; + // Create an array with a raw model for each material. // Multiple surfaces with the same material will turn into a single model. // However, surfaces that are marked as 'discrete' will turn into separate models. @@ -556,6 +560,7 @@ class RawModel { long rootNodeId; int vertexAttributes; + int globalMaxWeights; std::unordered_map vertexHash; std::vector vertices; std::vector triangles; @@ -577,3 +582,14 @@ void RawModel::GetAttributeArray( out[i] = vertices[i].*ptr; } } + +template +void RawModel::GetArrayAttributeArray( + std::vector<_attrib_type_>& out, + const _attrib_type_ (RawVertex::*ptr)[(RawModel::MAX_SUPPORTED_WEIGHTS - 1) / 4 + 1], + const int arrayOffset) const { + out.resize(vertices.size()); + for (size_t i = 0; i < vertices.size(); i++) { + out[i] = (vertices[i].*ptr)[arrayOffset]; + } +}