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.
This commit is contained in:
parent
467e7b2171
commit
c4395b9b92
|
@ -140,10 +140,11 @@ int main(int argc, char* argv[]) {
|
||||||
gltfOptions.useBlendShapeTangents,
|
gltfOptions.useBlendShapeTangents,
|
||||||
"Include blend shape tangents, if reported present by the FBX SDK.");
|
"Include blend shape tangents, if reported present by the FBX SDK.");
|
||||||
|
|
||||||
app.add_flag(
|
app.add_option(
|
||||||
"--normalize-weights",
|
"--normalize-weights",
|
||||||
gltfOptions.normalizeSkinningWeights,
|
gltfOptions.normalizeSkinningWeights,
|
||||||
"Normalize skinning weights.");
|
"Normalize skinning weights.",
|
||||||
|
true);
|
||||||
|
|
||||||
app.add_option(
|
app.add_option(
|
||||||
"--skinning-weights",
|
"--skinning-weights",
|
||||||
|
@ -156,8 +157,7 @@ int main(int argc, char* argv[]) {
|
||||||
"-k,--keep-attribute",
|
"-k,--keep-attribute",
|
||||||
[&](std::vector<std::string> attributes) -> bool {
|
[&](std::vector<std::string> attributes) -> bool {
|
||||||
gltfOptions.keepAttribs =
|
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_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS;
|
||||||
RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2 | RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3;
|
|
||||||
for (std::string attribute : attributes) {
|
for (std::string attribute : attributes) {
|
||||||
if (attribute == "position") {
|
if (attribute == "position") {
|
||||||
gltfOptions.keepAttribs |= RAW_VERTEX_ATTRIBUTE_POSITION;
|
gltfOptions.keepAttribs |= RAW_VERTEX_ATTRIBUTE_POSITION;
|
||||||
|
|
|
@ -123,6 +123,31 @@ class GltfModel {
|
||||||
return accessor;
|
return accessor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
std::shared_ptr<AccessorData> AddAttributeArrayToPrimitive(
|
||||||
|
BufferData& buffer,
|
||||||
|
const RawModel& surfaceModel,
|
||||||
|
PrimitiveData& primitive,
|
||||||
|
const AttributeArrayDefinition<T>& attrDef) {
|
||||||
|
// copy attribute data into vector
|
||||||
|
std::vector<T> attribArr;
|
||||||
|
surfaceModel.GetArrayAttributeArray<T>(attribArr, attrDef.rawAttributeIx, attrDef.arrayOffset);
|
||||||
|
|
||||||
|
std::shared_ptr<AccessorData> 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 <class T>
|
template <class T>
|
||||||
void serializeHolder(json& glTFJson, std::string key, const Holder<T> holder) {
|
void serializeHolder(json& glTFJson, std::string key, const Holder<T> holder) {
|
||||||
if (!holder.ptrs.empty()) {
|
if (!holder.ptrs.empty()) {
|
||||||
|
|
|
@ -532,77 +532,31 @@ ModelData* Raw2Gltf(
|
||||||
draco::DT_FLOAT32);
|
draco::DT_FLOAT32);
|
||||||
gltf->AddAttributeToPrimitive<Vec2f>(buffer, surfaceModel, *primitive, ATTR_TEXCOORD_1);
|
gltf->AddAttributeToPrimitive<Vec2f>(buffer, surfaceModel, *primitive, ATTR_TEXCOORD_1);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) != 0) {
|
||||||
const AttributeDefinition<Vec4i> ATTR_JOINTS(
|
for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) {
|
||||||
"JOINTS_0",
|
const AttributeArrayDefinition<Vec4i> ATTR_JOINTS(
|
||||||
&RawVertex::jointIndices0,
|
std::string("JOINTS_") + std::to_string(i/4),
|
||||||
|
//"JOINTS_0",
|
||||||
|
&RawVertex::jointIndices,
|
||||||
GLT_VEC4I,
|
GLT_VEC4I,
|
||||||
draco::GeometryAttribute::GENERIC,
|
draco::GeometryAttribute::GENERIC,
|
||||||
draco::DT_UINT16);
|
draco::DT_UINT16,
|
||||||
gltf->AddAttributeToPrimitive<Vec4i>(buffer, surfaceModel, *primitive, ATTR_JOINTS);
|
i/4);
|
||||||
|
gltf->AddAttributeArrayToPrimitive<Vec4i>(buffer, surfaceModel, *primitive, ATTR_JOINTS);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0) != 0) {
|
}
|
||||||
const AttributeDefinition<Vec4f> ATTR_WEIGHTS(
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) != 0) {
|
||||||
"WEIGHTS_0",
|
for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) {
|
||||||
&RawVertex::jointWeights0,
|
const AttributeArrayDefinition<Vec4f> ATTR_WEIGHTS(
|
||||||
|
std::string("WEIGHTS_") + std::to_string(i/4),
|
||||||
|
//"WEIGHTS_0",
|
||||||
|
&RawVertex::jointWeights,
|
||||||
GLT_VEC4F,
|
GLT_VEC4F,
|
||||||
draco::GeometryAttribute::GENERIC,
|
draco::GeometryAttribute::GENERIC,
|
||||||
draco::DT_FLOAT32);
|
draco::DT_FLOAT32,
|
||||||
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_WEIGHTS);
|
i/4);
|
||||||
|
gltf->AddAttributeArrayToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_WEIGHTS);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES1) != 0) {
|
|
||||||
const AttributeDefinition<Vec4i> ATTR_JOINTS(
|
|
||||||
"JOINTS_1",
|
|
||||||
&RawVertex::jointIndices1,
|
|
||||||
GLT_VEC4I,
|
|
||||||
draco::GeometryAttribute::GENERIC,
|
|
||||||
draco::DT_UINT16);
|
|
||||||
gltf->AddAttributeToPrimitive<Vec4i>(buffer, surfaceModel, *primitive, ATTR_JOINTS);
|
|
||||||
}
|
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS1) != 0) {
|
|
||||||
const AttributeDefinition<Vec4f> ATTR_WEIGHTS(
|
|
||||||
"WEIGHTS_1",
|
|
||||||
&RawVertex::jointWeights1,
|
|
||||||
GLT_VEC4F,
|
|
||||||
draco::GeometryAttribute::GENERIC,
|
|
||||||
draco::DT_FLOAT32);
|
|
||||||
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_WEIGHTS);
|
|
||||||
}
|
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2) != 0) {
|
|
||||||
const AttributeDefinition<Vec4i> ATTR_JOINTS(
|
|
||||||
"JOINTS_0",
|
|
||||||
&RawVertex::jointIndices2,
|
|
||||||
GLT_VEC4I,
|
|
||||||
draco::GeometryAttribute::GENERIC,
|
|
||||||
draco::DT_UINT16);
|
|
||||||
gltf->AddAttributeToPrimitive<Vec4i>(buffer, surfaceModel, *primitive, ATTR_JOINTS);
|
|
||||||
}
|
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2) != 0) {
|
|
||||||
const AttributeDefinition<Vec4f> ATTR_WEIGHTS(
|
|
||||||
"WEIGHTS_0",
|
|
||||||
&RawVertex::jointWeights2,
|
|
||||||
GLT_VEC4F,
|
|
||||||
draco::GeometryAttribute::GENERIC,
|
|
||||||
draco::DT_FLOAT32);
|
|
||||||
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_WEIGHTS);
|
|
||||||
}
|
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3) != 0) {
|
|
||||||
const AttributeDefinition<Vec4i> ATTR_JOINTS(
|
|
||||||
"JOINTS_0",
|
|
||||||
&RawVertex::jointIndices3,
|
|
||||||
GLT_VEC4I,
|
|
||||||
draco::GeometryAttribute::GENERIC,
|
|
||||||
draco::DT_UINT16);
|
|
||||||
gltf->AddAttributeToPrimitive<Vec4i>(buffer, surfaceModel, *primitive, ATTR_JOINTS);
|
|
||||||
}
|
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3) != 0) {
|
|
||||||
const AttributeDefinition<Vec4f> ATTR_WEIGHTS(
|
|
||||||
"WEIGHTS_0",
|
|
||||||
&RawVertex::jointWeights3,
|
|
||||||
GLT_VEC4F,
|
|
||||||
draco::GeometryAttribute::GENERIC,
|
|
||||||
draco::DT_FLOAT32);
|
|
||||||
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_WEIGHTS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// each channel present in the mesh always ends up a target in the primitive
|
// each channel present in the mesh always ends up a target in the primitive
|
||||||
|
|
|
@ -154,6 +154,44 @@ struct AttributeDefinition {
|
||||||
glType(_glType),
|
glType(_glType),
|
||||||
dracoAttribute(draco::GeometryAttribute::INVALID),
|
dracoAttribute(draco::GeometryAttribute::INVALID),
|
||||||
dracoComponentType(draco::DataType::DT_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 <class T>
|
||||||
|
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;
|
struct AccessorData;
|
||||||
|
|
|
@ -62,6 +62,32 @@ struct PrimitiveData {
|
||||||
dracoAttributes[attribute.gltfName] = dracoAttId;
|
dracoAttributes[attribute.gltfName] = dracoAttId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void AddDracoArrayAttrib(const AttributeArrayDefinition<T> attribute, const std::vector<T>& 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<uint8_t> 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);
|
void NoteDracoBuffer(const BufferViewData& data);
|
||||||
|
|
||||||
const int indices;
|
const int indices;
|
||||||
|
|
|
@ -27,10 +27,7 @@ bool RawVertex::operator==(const RawVertex& other) const {
|
||||||
return (position == other.position) && (normal == other.normal) && (tangent == other.tangent) &&
|
return (position == other.position) && (normal == other.normal) && (tangent == other.tangent) &&
|
||||||
(binormal == other.binormal) && (color == other.color) && (uv0 == other.uv0) &&
|
(binormal == other.binormal) && (color == other.color) && (uv0 == other.uv0) &&
|
||||||
(uv1 == other.uv1) &&
|
(uv1 == other.uv1) &&
|
||||||
(jointWeights0 == other.jointWeights0) && (jointWeights1 == other.jointWeights1) &&
|
(jointWeights == other.jointWeights) && (jointIndices == other.jointIndices) &&
|
||||||
(jointWeights2 == other.jointWeights2) && (jointWeights3 == other.jointWeights3) &&
|
|
||||||
(jointIndices0 == other.jointIndices0) && (jointIndices1 == other.jointIndices1) &&
|
|
||||||
(jointIndices2 == other.jointIndices2) && (jointIndices3 == other.jointIndices3) &&
|
|
||||||
(polarityUv0 == other.polarityUv0) &&
|
(polarityUv0 == other.polarityUv0) &&
|
||||||
(blendSurfaceIx == other.blendSurfaceIx) && (blends == other.blends);
|
(blendSurfaceIx == other.blendSurfaceIx) && (blends == other.blends);
|
||||||
}
|
}
|
||||||
|
@ -59,17 +56,8 @@ size_t RawVertex::Difference(const RawVertex& other) const {
|
||||||
attributes |= RAW_VERTEX_ATTRIBUTE_UV1;
|
attributes |= RAW_VERTEX_ATTRIBUTE_UV1;
|
||||||
}
|
}
|
||||||
// Always need both or neither.
|
// Always need both or neither.
|
||||||
if (jointIndices0 != other.jointIndices0 || jointWeights0 != other.jointWeights0) {
|
if (jointIndices != other.jointIndices || jointWeights != other.jointWeights) {
|
||||||
attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0;
|
attributes |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS;
|
||||||
}
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +397,7 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int globalMaxWeights = 0;
|
globalMaxWeights = 0;
|
||||||
for (auto& vertex: vertices) {
|
for (auto& vertex: vertices) {
|
||||||
|
|
||||||
// Sort from largest to smallest weight.
|
// Sort from largest to smallest weight.
|
||||||
|
@ -432,26 +420,15 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalMaxWeights > 0) {
|
if (globalMaxWeights > 0) {
|
||||||
AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0);
|
AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_INDICES);
|
||||||
AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0);
|
AddVertexAttribute(RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS);
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
assert(globalMaxWeights <= RawModel::MAX_SUPPORTED_WEIGHTS);
|
assert(globalMaxWeights <= RawModel::MAX_SUPPORTED_WEIGHTS);
|
||||||
// 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) { // Ensure all vertices have the same number of streams
|
for (int i = 0; i < globalMaxWeights; i += 4) {
|
||||||
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++) {
|
||||||
|
@ -459,26 +436,8 @@ void RawModel::Condense(const int maxSkinningWeights, const bool normalizeWeight
|
||||||
jointIds[j - i] = vertex.skinningInfo[j].jointIndex;
|
jointIds[j - i] = vertex.skinningInfo[j].jointIndex;
|
||||||
}
|
}
|
||||||
const int vertexStream = i / 4;
|
const int vertexStream = i / 4;
|
||||||
switch (vertexStream) {
|
vertex.jointIndices[vertexStream] = jointIds;
|
||||||
case 0:
|
vertex.jointWeights[vertexStream] = weights;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -631,6 +590,7 @@ void RawModel::CreateMaterialModels(
|
||||||
surfaces[sortedTriangles[i - 1].surfaceIndex].discrete))) {
|
surfaces[sortedTriangles[i - 1].surfaceIndex].discrete))) {
|
||||||
materialModels.resize(materialModels.size() + 1);
|
materialModels.resize(materialModels.size() + 1);
|
||||||
model = &materialModels[materialModels.size() - 1];
|
model = &materialModels[materialModels.size() - 1];
|
||||||
|
model->globalMaxWeights = globalMaxWeights;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: will have to unlink from the nodes, transform both surfaces into a
|
// FIXME: will have to unlink from the nodes, transform both surfaces into a
|
||||||
|
@ -658,8 +618,7 @@ void RawModel::CreateMaterialModels(
|
||||||
if (keepAttribs != -1) {
|
if (keepAttribs != -1) {
|
||||||
int keep = keepAttribs;
|
int keep = keepAttribs;
|
||||||
if ((keepAttribs & RAW_VERTEX_ATTRIBUTE_POSITION) != 0) {
|
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 |
|
keep |= RAW_VERTEX_ATTRIBUTE_JOINT_INDICES | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS;
|
||||||
RAW_VERTEX_ATTRIBUTE_JOINT_INDICES2 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS2 | RAW_VERTEX_ATTRIBUTE_JOINT_INDICES3 | RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS3;
|
|
||||||
}
|
}
|
||||||
if ((keepAttribs & RAW_VERTEX_ATTRIBUTE_AUTO) != 0) {
|
if ((keepAttribs & RAW_VERTEX_ATTRIBUTE_AUTO) != 0) {
|
||||||
keep |= RAW_VERTEX_ATTRIBUTE_POSITION;
|
keep |= RAW_VERTEX_ATTRIBUTE_POSITION;
|
||||||
|
@ -700,29 +659,13 @@ void RawModel::CreateMaterialModels(
|
||||||
if ((keep & RAW_VERTEX_ATTRIBUTE_UV1) == 0) {
|
if ((keep & RAW_VERTEX_ATTRIBUTE_UV1) == 0) {
|
||||||
vertex.uv1 = defaultVertex.uv1;
|
vertex.uv1 = defaultVertex.uv1;
|
||||||
}
|
}
|
||||||
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0) == 0) {
|
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) == 0) {
|
||||||
vertex.jointIndices0 = defaultVertex.jointIndices0;
|
for (int i = 0; i < RawModel::MAX_SUPPORTED_WEIGHTS ; i++)
|
||||||
|
vertex.jointIndices[i] = defaultVertex.jointIndices[i];
|
||||||
}
|
}
|
||||||
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0) == 0) {
|
if ((keep & RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS) == 0) {
|
||||||
vertex.jointWeights0 = defaultVertex.jointWeights0;
|
for (int i = 0; i < RawModel::MAX_SUPPORTED_WEIGHTS; i++)
|
||||||
}
|
vertex.jointWeights[i] = defaultVertex.jointWeights[i];
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#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,
|
||||||
|
@ -23,14 +25,8 @@ enum RawVertexAttribute {
|
||||||
RAW_VERTEX_ATTRIBUTE_COLOR = 1 << 4,
|
RAW_VERTEX_ATTRIBUTE_COLOR = 1 << 4,
|
||||||
RAW_VERTEX_ATTRIBUTE_UV0 = 1 << 5,
|
RAW_VERTEX_ATTRIBUTE_UV0 = 1 << 5,
|
||||||
RAW_VERTEX_ATTRIBUTE_UV1 = 1 << 6,
|
RAW_VERTEX_ATTRIBUTE_UV1 = 1 << 6,
|
||||||
RAW_VERTEX_ATTRIBUTE_JOINT_INDICES0 = 1 << 7,
|
RAW_VERTEX_ATTRIBUTE_JOINT_INDICES = 1 << 7,
|
||||||
RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS0 = 1 << 8,
|
RAW_VERTEX_ATTRIBUTE_JOINT_WEIGHTS = 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_AUTO = 1 << 31
|
RAW_VERTEX_ATTRIBUTE_AUTO = 1 << 31
|
||||||
};
|
};
|
||||||
|
@ -65,14 +61,9 @@ 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 jointIndices0{0,0,0,0};
|
Vec4i jointIndices[(MAX_SKINNING_WEIGHTS - 1) / 4 + 1];
|
||||||
Vec4i jointIndices1{0,0,0,0};
|
Vec4f jointWeights[(MAX_SKINNING_WEIGHTS - 1) / 4 + 1];
|
||||||
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};
|
|
||||||
|
|
||||||
std::vector<RawVertexSkinningInfo> skinningInfo;
|
std::vector<RawVertexSkinningInfo> skinningInfo;
|
||||||
// end of members that directly correspond to vertex attributes
|
// end of members that directly correspond to vertex attributes
|
||||||
|
@ -381,7 +372,7 @@ struct RawNode {
|
||||||
|
|
||||||
class RawModel {
|
class RawModel {
|
||||||
public:
|
public:
|
||||||
static const int MAX_SUPPORTED_WEIGHTS = 16;
|
static const int MAX_SUPPORTED_WEIGHTS = MAX_SKINNING_WEIGHTS;
|
||||||
|
|
||||||
RawModel();
|
RawModel();
|
||||||
|
|
||||||
|
@ -460,6 +451,11 @@ class RawModel {
|
||||||
int GetVertexCount() const {
|
int GetVertexCount() const {
|
||||||
return (int)vertices.size();
|
return (int)vertices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetGlobalWeightCount() const{
|
||||||
|
return globalMaxWeights;
|
||||||
|
}
|
||||||
|
|
||||||
const RawVertex& GetVertex(const int index) const {
|
const RawVertex& GetVertex(const int index) const {
|
||||||
return vertices[index];
|
return vertices[index];
|
||||||
}
|
}
|
||||||
|
@ -542,6 +538,14 @@ class RawModel {
|
||||||
void GetAttributeArray(std::vector<_attrib_type_>& out, const _attrib_type_ RawVertex::*ptr)
|
void GetAttributeArray(std::vector<_attrib_type_>& out, const _attrib_type_ RawVertex::*ptr)
|
||||||
const;
|
const;
|
||||||
|
|
||||||
|
// Create individual attribute arrays, with the source as an array.
|
||||||
|
// Returns true if the vertices store the particular attribute.
|
||||||
|
template <typename _attrib_type_>
|
||||||
|
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.
|
// Create an array with a raw model for each material.
|
||||||
// Multiple surfaces with the same material will turn into a single model.
|
// Multiple surfaces with the same material will turn into a single model.
|
||||||
// However, surfaces that are marked as 'discrete' will turn into separate models.
|
// However, surfaces that are marked as 'discrete' will turn into separate models.
|
||||||
|
@ -556,6 +560,7 @@ class RawModel {
|
||||||
|
|
||||||
long rootNodeId;
|
long rootNodeId;
|
||||||
int vertexAttributes;
|
int vertexAttributes;
|
||||||
|
int globalMaxWeights;
|
||||||
std::unordered_map<RawVertex, int, VertexHasher> vertexHash;
|
std::unordered_map<RawVertex, int, VertexHasher> vertexHash;
|
||||||
std::vector<RawVertex> vertices;
|
std::vector<RawVertex> vertices;
|
||||||
std::vector<RawTriangle> triangles;
|
std::vector<RawTriangle> triangles;
|
||||||
|
@ -577,3 +582,14 @@ void RawModel::GetAttributeArray(
|
||||||
out[i] = vertices[i].*ptr;
|
out[i] = vertices[i].*ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename _attrib_type_>
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue