Allow arbitrary number of skinning weights. Controlled through command line parameter. Defaults to 4.

This commit is contained in:
hhalen 2019-04-19 15:59:07 -07:00
parent c4395b9b92
commit 10f4ac856f
5 changed files with 15 additions and 21 deletions

View File

@ -151,7 +151,7 @@ int main(int argc, char* argv[]) {
gltfOptions.maxSkinningWeights, gltfOptions.maxSkinningWeights,
"How many joint influences per vertex are allowed.", "How many joint influences per vertex are allowed.",
true) true)
->check(CLI::Range(1, RawModel::MAX_SUPPORTED_WEIGHTS)); ->check(CLI::Range(0, 512));
app.add_option( app.add_option(
"-k,--keep-attribute", "-k,--keep-attribute",

View File

@ -536,7 +536,6 @@ ModelData* Raw2Gltf(
for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) { for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) {
const AttributeArrayDefinition<Vec4i> ATTR_JOINTS( const AttributeArrayDefinition<Vec4i> ATTR_JOINTS(
std::string("JOINTS_") + std::to_string(i/4), std::string("JOINTS_") + std::to_string(i/4),
//"JOINTS_0",
&RawVertex::jointIndices, &RawVertex::jointIndices,
GLT_VEC4I, GLT_VEC4I,
draco::GeometryAttribute::GENERIC, draco::GeometryAttribute::GENERIC,
@ -549,7 +548,6 @@ ModelData* Raw2Gltf(
for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) { for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) {
const AttributeArrayDefinition<Vec4f> ATTR_WEIGHTS( const AttributeArrayDefinition<Vec4f> ATTR_WEIGHTS(
std::string("WEIGHTS_") + std::to_string(i/4), std::string("WEIGHTS_") + std::to_string(i/4),
//"WEIGHTS_0",
&RawVertex::jointWeights, &RawVertex::jointWeights,
GLT_VEC4F, GLT_VEC4F,
draco::GeometryAttribute::GENERIC, draco::GeometryAttribute::GENERIC,

View File

@ -173,7 +173,7 @@ struct AttributeDefinition {
template <class T> template <class T>
struct AttributeArrayDefinition { struct AttributeArrayDefinition {
const std::string gltfName; const std::string gltfName;
const T (RawVertex::*rawAttributeIx)[(RawModel::MAX_SUPPORTED_WEIGHTS -1 ) / 4 + 1]; const std::vector<T> RawVertex::*rawAttributeIx;
const GLType glType; const GLType glType;
const int arrayOffset; const int arrayOffset;
const draco::GeometryAttribute::Type dracoAttribute; const draco::GeometryAttribute::Type dracoAttribute;
@ -181,7 +181,7 @@ struct AttributeArrayDefinition {
AttributeArrayDefinition( AttributeArrayDefinition(
const std::string gltfName, const std::string gltfName,
const T (RawVertex::*rawAttributeIx)[(RawModel::MAX_SUPPORTED_WEIGHTS - 1) / 4 + 1], const std::vector<T> RawVertex::*rawAttributeIx,
const GLType& _glType, const GLType& _glType,
const draco::GeometryAttribute::Type dracoAttribute, const draco::GeometryAttribute::Type dracoAttribute,
const draco::DataType dracoComponentType, const draco::DataType dracoComponentType,

View File

@ -425,19 +425,20 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight
} }
assert(globalMaxWeights <= RawModel::MAX_SUPPORTED_WEIGHTS); assert(globalMaxWeights >= 0);
// Copy to gltf friendly structure // Copy to gltf friendly structure
for (auto& vertex : vertices) { for (auto& vertex : vertices) {
for (int i = 0; i < globalMaxWeights; i += 4) { vertex.jointIndices.reserve(globalMaxWeights);
vertex.jointWeights.reserve(globalMaxWeights);
for (int i = 0; i < globalMaxWeights; i += 4) { // ensure every vertex has the same amount of weights
Vec4f weights{0.0}; Vec4f weights{0.0};
Vec4i jointIds{0,0,0,0}; Vec4i jointIds{0,0,0,0};
for (int j = i; j < i + 4 && j < vertex.skinningInfo.size(); j++) { for (int j = i; j < i + 4 && j < vertex.skinningInfo.size(); j++) {
weights[j - i] = vertex.skinningInfo[j].jointWeight; weights[j - i] = vertex.skinningInfo[j].jointWeight;
jointIds[j - i] = vertex.skinningInfo[j].jointIndex; jointIds[j - i] = vertex.skinningInfo[j].jointIndex;
} }
const int vertexStream = i / 4; vertex.jointIndices.push_back(jointIds);
vertex.jointIndices[vertexStream] = jointIds; vertex.jointWeights.push_back(weights);
vertex.jointWeights[vertexStream] = weights;
} }
} }
} }
@ -660,12 +661,10 @@ void RawModel::CreateMaterialModels(
vertex.uv1 = defaultVertex.uv1; vertex.uv1 = defaultVertex.uv1;
} }
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) == 0) { if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) == 0) {
for (int i = 0; i < RawModel::MAX_SUPPORTED_WEIGHTS ; i++) vertex.jointIndices = defaultVertex.jointIndices;
vertex.jointIndices[i] = defaultVertex.jointIndices[i];
} }
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) == 0) { if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) == 0) {
for (int i = 0; i < RawModel::MAX_SUPPORTED_WEIGHTS; i++) vertex.jointWeights = defaultVertex.jointWeights;
vertex.jointWeights[i] = defaultVertex.jointWeights[i];
} }
} }

View File

@ -15,8 +15,6 @@
#include "FBX2glTF.h" #include "FBX2glTF.h"
#define MAX_SKINNING_WEIGHTS 32
enum RawVertexAttribute { enum RawVertexAttribute {
RAW_VERTEX_ATTRIBUTE_POSITION = 1 << 0, RAW_VERTEX_ATTRIBUTE_POSITION = 1 << 0,
RAW_VERTEX_ATTRIBUTE_NORMAL = 1 << 1, RAW_VERTEX_ATTRIBUTE_NORMAL = 1 << 1,
@ -61,8 +59,8 @@ struct RawVertex {
Vec4f color{0.0f}; Vec4f color{0.0f};
Vec2f uv0{0.0f}; Vec2f uv0{0.0f};
Vec2f uv1{0.0f}; Vec2f uv1{0.0f};
Vec4i jointIndices[(MAX_SKINNING_WEIGHTS - 1) / 4 + 1]; std::vector<Vec4i> jointIndices;
Vec4f jointWeights[(MAX_SKINNING_WEIGHTS - 1) / 4 + 1]; std::vector<Vec4f> jointWeights;
std::vector<RawVertexSkinningInfo> skinningInfo; std::vector<RawVertexSkinningInfo> skinningInfo;
@ -372,7 +370,6 @@ struct RawNode {
class RawModel { class RawModel {
public: public:
static const int MAX_SUPPORTED_WEIGHTS = MAX_SKINNING_WEIGHTS;
RawModel(); RawModel();
@ -542,7 +539,7 @@ class RawModel {
// Returns true if the vertices store the particular attribute. // Returns true if the vertices store the particular attribute.
template <typename _attrib_type_> template <typename _attrib_type_>
void GetArrayAttributeArray(std::vector<_attrib_type_>& out, void GetArrayAttributeArray(std::vector<_attrib_type_>& out,
const _attrib_type_ (RawVertex::*ptr)[(RawModel::MAX_SUPPORTED_WEIGHTS - 1) / 4 + 1], const std::vector<_attrib_type_> RawVertex::*ptr,
const int arrayOffset) const int arrayOffset)
const; const;
@ -586,7 +583,7 @@ void RawModel::GetAttributeArray(
template <typename _attrib_type_> template <typename _attrib_type_>
void RawModel::GetArrayAttributeArray( void RawModel::GetArrayAttributeArray(
std::vector<_attrib_type_>& out, std::vector<_attrib_type_>& out,
const _attrib_type_ (RawVertex::*ptr)[(RawModel::MAX_SUPPORTED_WEIGHTS - 1) / 4 + 1], const std::vector<_attrib_type_> RawVertex::*ptr,
const int arrayOffset) const { const int arrayOffset) const {
out.resize(vertices.size()); out.resize(vertices.size());
for (size_t i = 0; i < vertices.size(); i++) { for (size_t i = 0; i < vertices.size(); i++) {