FOund the issue why the skinning was incorrect, removed unecessary data structures in the newly added objects and renamed Deformer to SkinCluster and DYnamicTransform to SkinDeformer

This commit is contained in:
Sam Gateau 2019-10-16 04:02:05 -07:00
parent f049ab7887
commit eecaeb1155
12 changed files with 110 additions and 104 deletions

View file

@ -30,8 +30,8 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
// we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose
// when we are dealing with a joint offset in the model
for (int i = 0; i < (int)hfmModel.dynamicTransforms.size(); i++) {
const auto& defor = hfmModel.dynamicTransforms[i];
for (int i = 0; i < (int)hfmModel.skinDeformers.size(); i++) {
const auto& defor = hfmModel.skinDeformers[i];
std::vector<HFMCluster> dummyClustersList;
for (int j = 0; j < defor.clusters.size(); j++) {

View file

@ -1593,9 +1593,9 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
// whether we're skinned depends on how many clusters are attached
if (clusterIDs.size() > 0) {
hfm::DynamicTransform dynamicTransform;
auto& clusters = dynamicTransform.clusters;
std::vector<hfm::Deformer> deformers;
hfm::SkinDeformer skinDeformer;
auto& clusters = skinDeformer.clusters;
std::vector<hfm::SkinCluster> skinClusters;
for (const auto& clusterID : clusterIDs) {
HFMCluster hfmCluster;
const Cluster& fbxCluster = fbxClusters[clusterID];
@ -1639,35 +1639,40 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
clusters.push_back(cluster);
// Skinned mesh instances have a dynamic transform
dynamicTransform.deformers.reserve(clusterIDs.size());
clusters.reserve(clusterIDs.size());
skinDeformer.skinClusterIndices.reserve(clusterIDs.size());
for (const auto& clusterID : clusterIDs) {
const Cluster& fbxCluster = fbxClusters[clusterID];
dynamicTransform.deformers.emplace_back();
deformers.emplace_back();
hfm::Deformer& deformer = deformers.back();
skinDeformer.skinClusterIndices.emplace_back();
skinClusters.emplace_back();
hfm::SkinCluster& skinCluster = skinClusters.back();
size_t indexWeightPairs = (size_t)std::min(fbxCluster.indices.size(), fbxCluster.weights.size());
deformer.indices.reserve(indexWeightPairs);
deformer.weights.reserve(indexWeightPairs);
for (int i = 0; i < (int)indexWeightPairs; i++) {
int oldIndex = fbxCluster.indices[i];
uint32_t newIndex = (uint32_t)extracted.newIndices.value(oldIndex);
deformer.indices.push_back(newIndex);
deformer.weights.push_back((float)fbxCluster.weights[i]);
skinCluster.indices.reserve(indexWeightPairs);
skinCluster.weights.reserve(indexWeightPairs);
for (int j = 0; j < fbxCluster.indices.size(); j++) {
int oldIndex = fbxCluster.indices.at(j);
float weight = fbxCluster.weights.at(j);
for (QMultiHash<int, int>::const_iterator it = extracted.newIndices.constFind(oldIndex);
it != extracted.newIndices.end() && it.key() == oldIndex; it++) {
int newIndex = it.value();
skinCluster.indices.push_back(newIndex);
skinCluster.weights.push_back(weight);
}
}
}
// Store this model's deformers, this dynamic transform's deformer IDs
uint32_t deformerMinID = (uint32_t)hfmModel.deformers.size();
hfmModel.deformers.insert(hfmModel.deformers.end(), deformers.cbegin(), deformers.cend());
dynamicTransform.deformers.resize(deformers.size());
std::iota(dynamicTransform.deformers.begin(), dynamicTransform.deformers.end(), deformerMinID);
uint32_t deformerMinID = (uint32_t)hfmModel.skinClusters.size();
hfmModel.skinClusters.insert(hfmModel.skinClusters.end(), skinClusters.cbegin(), skinClusters.cend());
skinDeformer.skinClusterIndices.resize(skinClusters.size());
std::iota(skinDeformer.skinClusterIndices.begin(), skinDeformer.skinClusterIndices.end(), deformerMinID);
// Store the model's dynamic transform, and put its ID in the shapes
hfmModel.dynamicTransforms.push_back(dynamicTransform);
uint32_t dynamicTransformID = (uint32_t)(hfmModel.dynamicTransforms.size() - 1);
hfmModel.skinDeformers.push_back(skinDeformer);
uint32_t skinDeformerID = (uint32_t)(hfmModel.skinDeformers.size() - 1);
for (hfm::Shape& shape : partShapes) {
shape.dynamicTransform = dynamicTransformID;
shape.skinDeformer = skinDeformerID;
}
} else {
// this is a no cluster mesh

View file

@ -242,17 +242,20 @@ public:
QVector<glm::vec3> colors;
QVector<glm::vec2> texCoords;
QVector<glm::vec2> texCoords1;
QVector<uint16_t> clusterIndices; // DEPRECATED (see hfm::Shape::dynamicTransform, hfm::DynamicTransform::deformers, hfm::Deformer)
QVector<uint16_t> clusterWeights; // DEPRECATED (see hfm::Shape::dynamicTransform, hfm::DynamicTransform::deformers, hfm::Deformer)
QVector<int32_t> originalIndices;
QVector<Cluster> clusters; // DEPRECATED (see hfm::Shape::dynamicTransform, hfm::DynamicTransform::clusters)
Extents meshExtents; // DEPRECATED (see hfm::Shape::transformedExtents)
glm::mat4 modelTransform; // DEPRECATED (see hfm::Joint::globalTransform, hfm::Shape::transform, hfm::Model::joints)
// Skinning cluster attributes
QVector<uint16_t> clusterIndices;
QVector<uint16_t> clusterWeights;
// Blendshape attributes
QVector<Blendshape> blendshapes;
QVector<int32_t> originalIndices; // Original indices of the vertices
unsigned int meshIndex; // the order the meshes appeared in the object file
graphics::MeshPointer _mesh;
@ -294,18 +297,16 @@ public:
};
// Formerly contained in hfm::Mesh
class Deformer {
class SkinCluster {
public:
std::vector<uint32_t> indices;
std::vector<float> weights;
};
class DynamicTransform {
class SkinDeformer {
public:
std::vector<uint16_t> deformers;
std::vector<Cluster> clusters; // affect the deformer of the same index
std::vector<uint32_t> blendshapes;
// There are also the meshExtents and modelTransform, which for now are left in hfm::Mesh
std::vector<uint16_t> skinClusterIndices;
std::vector<Cluster> clusters;
};
// The lightweight model part description.
@ -317,7 +318,7 @@ public:
uint32_t joint { UNDEFINED_KEY }; // The hfm::Joint associated with this shape, containing transform information
// TODO: Have all serializers calculate hfm::Shape::transformedExtents in world space where they previously calculated hfm::Mesh::meshExtents. Change all code that uses hfm::Mesh::meshExtents to use this instead.
Extents transformedExtents; // The precise extents of the meshPart vertices in world space, after transform information is applied, while not taking into account rigging/skinning
uint32_t dynamicTransform { UNDEFINED_KEY };
uint32_t skinDeformer { UNDEFINED_KEY };
};
/// The runtime model format.
@ -334,9 +335,9 @@ public:
std::vector<Mesh> meshes;
std::vector<Material> materials;
std::vector<Deformer> deformers;
std::vector<DynamicTransform> dynamicTransforms;
std::vector<SkinDeformer> skinDeformers;
std::vector<SkinCluster> skinClusters;
std::vector<Joint> joints;
QHash<QString, int> jointIndices; ///< 1-based, so as to more easily detect missing indices

View file

@ -29,7 +29,7 @@ namespace baker {
class GetModelPartsTask {
public:
using Input = hfm::Model::Pointer;
using Output = VaryingSet8<std::vector<hfm::Mesh>, hifi::URL, baker::MeshIndicesToModelNames, baker::BlendshapesPerMesh, std::vector<hfm::Joint>, std::vector<hfm::Shape>, std::vector<hfm::DynamicTransform>, std::vector<hfm::Deformer>>;
using Output = VaryingSet8<std::vector<hfm::Mesh>, hifi::URL, baker::MeshIndicesToModelNames, baker::BlendshapesPerMesh, std::vector<hfm::Joint>, std::vector<hfm::Shape>, std::vector<hfm::SkinDeformer>, std::vector<hfm::SkinCluster>>;
using JobModel = Job::ModelIO<GetModelPartsTask, Input, Output>;
void run(const BakeContextPointer& context, const Input& input, Output& output) {
@ -44,8 +44,8 @@ namespace baker {
}
output.edit4() = hfmModelIn->joints;
output.edit5() = hfmModelIn->shapes;
output.edit6() = hfmModelIn->dynamicTransforms;
output.edit7() = hfmModelIn->deformers;
output.edit6() = hfmModelIn->skinDeformers;
output.edit7() = hfmModelIn->skinClusters;
}
};
@ -143,7 +143,7 @@ namespace baker {
const auto blendshapesPerMeshIn = modelPartsIn.getN<GetModelPartsTask::Output>(3);
const auto jointsIn = modelPartsIn.getN<GetModelPartsTask::Output>(4);
const auto shapesIn = modelPartsIn.getN<GetModelPartsTask::Output>(5);
const auto dynamicTransformsIn = modelPartsIn.getN<GetModelPartsTask::Output>(6);
const auto skinDeformersIn = modelPartsIn.getN<GetModelPartsTask::Output>(6);
const auto deformersIn = modelPartsIn.getN<GetModelPartsTask::Output>(7);
// Calculate normals and tangents for meshes and blendshapes if they do not exist
@ -158,14 +158,14 @@ namespace baker {
// Skinning weight calculations
// NOTE: Due to limitations in the current graphics::MeshPointer representation, the output list of ReweightedDeformers is per-mesh. An element is empty if there are no deformers for the mesh of the same index.
const auto reweightDeformersInputs = ReweightDeformersTask::Input(meshesIn, shapesIn, dynamicTransformsIn, deformersIn).asVarying();
const auto reweightDeformersInputs = ReweightDeformersTask::Input(meshesIn, shapesIn, skinDeformersIn, deformersIn).asVarying();
const auto reweightedDeformers = model.addJob<ReweightDeformersTask>("ReweightDeformers", reweightDeformersInputs);
// Shape vertices are included/rejected based on skinning weight, and thus must use the reweighted deformers.
const auto collectShapeVerticesInputs = CollectShapeVerticesTask::Input(meshesIn, shapesIn, jointsIn, dynamicTransformsIn, reweightedDeformers).asVarying();
const auto collectShapeVerticesInputs = CollectShapeVerticesTask::Input(meshesIn, shapesIn, jointsIn, skinDeformersIn, reweightedDeformers).asVarying();
const auto shapeVerticesPerJoint = model.addJob<CollectShapeVerticesTask>("CollectShapeVertices", collectShapeVerticesInputs);
// Build the graphics::MeshPointer for each hfm::Mesh
const auto buildGraphicsMeshInputs = BuildGraphicsMeshTask::Input(meshesIn, url, meshIndicesToModelNames, normalsPerMesh, tangentsPerMesh, shapesIn, dynamicTransformsIn, reweightedDeformers).asVarying();
const auto buildGraphicsMeshInputs = BuildGraphicsMeshTask::Input(meshesIn, url, meshIndicesToModelNames, normalsPerMesh, tangentsPerMesh, shapesIn, skinDeformersIn, reweightedDeformers).asVarying();
const auto graphicsMeshes = model.addJob<BuildGraphicsMeshTask>("BuildGraphicsMesh", buildGraphicsMeshInputs);
// Prepare joint information

View file

@ -381,16 +381,16 @@ void BuildGraphicsMeshTask::run(const baker::BakeContextPointer& context, const
const auto& normalsPerMesh = input.get3();
const auto& tangentsPerMesh = input.get4();
const auto& shapes = input.get5();
const auto& dynamicTransforms = input.get6();
const auto& skinDeformers = input.get6();
const auto& reweightedDeformersPerMesh = input.get7();
// Currently, there is only (at most) one dynamicTransform per mesh
// An undefined shape.dynamicTransform has the value hfm::UNDEFINED_KEY
std::vector<uint32_t> dynamicTransformPerMesh;
dynamicTransformPerMesh.resize(meshes.size(), hfm::UNDEFINED_KEY);
// Currently, there is only (at most) one skinDeformer per mesh
// An undefined shape.skinDeformer has the value hfm::UNDEFINED_KEY
std::vector<uint32_t> skinDeformerPerMesh;
skinDeformerPerMesh.resize(meshes.size(), hfm::UNDEFINED_KEY);
for (const auto& shape : shapes) {
uint32_t dynamicTransformIndex = shape.dynamicTransform;
dynamicTransformPerMesh[shape.mesh] = dynamicTransformIndex;
uint32_t skinDeformerIndex = shape.skinDeformer;
skinDeformerPerMesh[shape.mesh] = skinDeformerIndex;
}
auto& graphicsMeshes = output;
@ -403,10 +403,10 @@ void BuildGraphicsMeshTask::run(const baker::BakeContextPointer& context, const
uint16_t numDeformerControllers = 0;
if (reweightedDeformers.weightsPerVertex != 0) {
uint32_t dynamicTransformIndex = dynamicTransformPerMesh[i];
if (dynamicTransformIndex != hfm::UNDEFINED_KEY) {
const hfm::DynamicTransform& dynamicTransform = dynamicTransforms[dynamicTransformIndex];
numDeformerControllers = (uint16_t)dynamicTransform.deformers.size();
uint32_t skinDeformerIndex = skinDeformerPerMesh[i];
if (skinDeformerIndex != hfm::UNDEFINED_KEY) {
const hfm::SkinDeformer& skinDeformer = skinDeformers[skinDeformerIndex];
numDeformerControllers = (uint16_t)skinDeformer.skinClusterIndices.size();
}
}

View file

@ -20,7 +20,7 @@
class BuildGraphicsMeshTask {
public:
using Input = baker::VaryingSet8<std::vector<hfm::Mesh>, hifi::URL, baker::MeshIndicesToModelNames, baker::NormalsPerMesh, baker::TangentsPerMesh, std::vector<hfm::Shape>, std::vector<hfm::DynamicTransform>, std::vector<baker::ReweightedDeformers>>;
using Input = baker::VaryingSet8<std::vector<hfm::Mesh>, hifi::URL, baker::MeshIndicesToModelNames, baker::NormalsPerMesh, baker::TangentsPerMesh, std::vector<hfm::Shape>, std::vector<hfm::SkinDeformer>, std::vector<baker::ReweightedDeformers>>;
using Output = std::vector<graphics::MeshPointer>;
using JobModel = baker::Job::ModelIO<BuildGraphicsMeshTask, Input, Output>;

View file

@ -13,15 +13,15 @@
#include <glm/gtx/transform.hpp>
// Used to track and avoid duplicate shape vertices, as multiple shapes can have the same mesh and dynamicTransform
// Used to track and avoid duplicate shape vertices, as multiple shapes can have the same mesh and skinDeformer
class VertexSource {
public:
uint32_t mesh;
uint32_t dynamicTransform;
uint32_t skinDeformer;
bool operator==(const VertexSource& other) const {
return mesh == other.mesh &&
dynamicTransform == other.dynamicTransform;
skinDeformer == other.skinDeformer;
}
};
@ -29,7 +29,7 @@ void CollectShapeVerticesTask::run(const baker::BakeContextPointer& context, con
const auto& meshes = input.get0();
const auto& shapes = input.get1();
const auto& joints = input.get2();
const auto& dynamicTransforms = input.get3();
const auto& skinDeformers = input.get3();
const auto& reweightedDeformers = input.get4();
auto& shapeVerticesPerJoint = output;
@ -38,18 +38,18 @@ void CollectShapeVerticesTask::run(const baker::BakeContextPointer& context, con
vertexSourcesPerJoint.resize(joints.size());
for (size_t i = 0; i < shapes.size(); ++i) {
const auto& shape = shapes[i];
const uint32_t dynamicTransformKey = shape.dynamicTransform;
if (dynamicTransformKey == hfm::UNDEFINED_KEY) {
const uint32_t skinDeformerKey = shape.skinDeformer;
if (skinDeformerKey == hfm::UNDEFINED_KEY) {
continue;
}
VertexSource vertexSource;
vertexSource.mesh = shape.mesh;
vertexSource.dynamicTransform = dynamicTransformKey;
vertexSource.skinDeformer = skinDeformerKey;
const auto& dynamicTransform = dynamicTransforms[dynamicTransformKey];
for (size_t j = 0; j < dynamicTransform.clusters.size(); ++j) {
const auto& cluster = dynamicTransform.clusters[j];
const auto& skinDeformer = skinDeformers[skinDeformerKey];
for (size_t j = 0; j < skinDeformer.clusters.size(); ++j) {
const auto& cluster = skinDeformer.clusters[j];
const uint32_t jointIndex = cluster.jointIndex;
auto& vertexSources = vertexSourcesPerJoint[jointIndex];

View file

@ -19,7 +19,7 @@
class CollectShapeVerticesTask {
public:
using Input = baker::VaryingSet5<std::vector<hfm::Mesh>, std::vector<hfm::Shape>, std::vector<hfm::Joint>, std::vector<hfm::DynamicTransform>, std::vector<baker::ReweightedDeformers>>;
using Input = baker::VaryingSet5<std::vector<hfm::Mesh>, std::vector<hfm::Shape>, std::vector<hfm::Joint>, std::vector<hfm::SkinDeformer>, std::vector<baker::ReweightedDeformers>>;
using Output = std::vector<ShapeVertices>;
using JobModel = baker::Job::ModelIO<CollectShapeVerticesTask, Input, Output>;

View file

@ -11,30 +11,30 @@
#include "ReweightDeformersTask.h"
baker::ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const std::vector<const hfm::Deformer*> deformers, const uint16_t weightsPerVertex) {
baker::ReweightedDeformers getReweightedDeformers(size_t numMeshVertices, const std::vector<const hfm::SkinCluster*> skinClusters, const uint16_t weightsPerVertex) {
baker::ReweightedDeformers reweightedDeformers;
if (deformers.size() == 0) {
if (skinClusters.size() == 0) {
return reweightedDeformers;
}
size_t numClusterIndices = numMeshVertices * weightsPerVertex;
reweightedDeformers.weightsPerVertex = weightsPerVertex;
// TODO: Consider having a rootCluster property in the DynamicTransform rather than appending the root to the end of the cluster list.
reweightedDeformers.indices.resize(numClusterIndices, (uint16_t)(deformers.size() - 1));
reweightedDeformers.indices.resize(numClusterIndices, (uint16_t)(skinClusters.size() - 1));
reweightedDeformers.weights.resize(numClusterIndices, 0);
std::vector<float> weightAccumulators;
weightAccumulators.resize(numClusterIndices, 0.0f);
for (uint16_t i = 0; i < (uint16_t)deformers.size(); ++i) {
const hfm::Deformer& deformer = *deformers[i];
for (uint16_t i = 0; i < (uint16_t)skinClusters.size(); ++i) {
const hfm::SkinCluster& skinCluster = *skinClusters[i];
if (deformer.indices.size() != deformer.weights.size()) {
if (skinCluster.indices.size() != skinCluster.weights.size()) {
reweightedDeformers.trimmedToMatch = true;
}
size_t numIndicesOrWeights = std::min(deformer.indices.size(), deformer.weights.size());
size_t numIndicesOrWeights = std::min(skinCluster.indices.size(), skinCluster.weights.size());
for (size_t j = 0; j < numIndicesOrWeights; ++j) {
uint32_t index = deformer.indices[j];
float weight = deformer.weights[j];
uint32_t index = skinCluster.indices[j];
float weight = skinCluster.weights[j];
// look for an unused slot in the weights vector
uint32_t weightIndex = index * weightsPerVertex;
@ -90,34 +90,34 @@ void ReweightDeformersTask::run(const baker::BakeContextPointer& context, const
const auto& meshes = input.get0();
const auto& shapes = input.get1();
const auto& dynamicTransforms = input.get2();
const auto& deformers = input.get3();
const auto& skinDeformers = input.get2();
const auto& skinClusters = input.get3();
auto& reweightedDeformers = output;
// Currently, there is only (at most) one dynamicTransform per mesh
// An undefined shape.dynamicTransform has the value hfm::UNDEFINED_KEY
std::vector<uint32_t> dynamicTransformPerMesh;
dynamicTransformPerMesh.resize(meshes.size(), hfm::UNDEFINED_KEY);
// Currently, there is only (at most) one skinDeformer per mesh
// An undefined shape.skinDeformer has the value hfm::UNDEFINED_KEY
std::vector<uint32_t> skinDeformerPerMesh;
skinDeformerPerMesh.resize(meshes.size(), hfm::UNDEFINED_KEY);
for (const auto& shape : shapes) {
uint32_t dynamicTransformIndex = shape.dynamicTransform;
dynamicTransformPerMesh[shape.mesh] = dynamicTransformIndex;
uint32_t skinDeformerIndex = shape.skinDeformer;
skinDeformerPerMesh[shape.mesh] = skinDeformerIndex;
}
reweightedDeformers.reserve(meshes.size());
for (size_t i = 0; i < meshes.size(); ++i) {
const auto& mesh = meshes[i];
uint32_t dynamicTransformIndex = dynamicTransformPerMesh[i];
uint32_t skinDeformerIndex = skinDeformerPerMesh[i];
const hfm::DynamicTransform* dynamicTransform = nullptr;
std::vector<const hfm::Deformer*> meshDeformers;
if (dynamicTransformIndex != hfm::UNDEFINED_KEY) {
dynamicTransform = &dynamicTransforms[dynamicTransformIndex];
for (const auto& deformerIndex : dynamicTransform->deformers) {
const auto& deformer = deformers[deformerIndex];
meshDeformers.push_back(&deformer);
const hfm::SkinDeformer* skinDeformer = nullptr;
std::vector<const hfm::SkinCluster*> meshSkinClusters;
if (skinDeformerIndex != hfm::UNDEFINED_KEY) {
skinDeformer = &skinDeformers[skinDeformerIndex];
for (const auto& skinClusterIndex : skinDeformer->skinClusterIndices) {
const auto& skinCluster = skinClusters[skinClusterIndex];
meshSkinClusters.push_back(&skinCluster);
}
}
reweightedDeformers.push_back(getReweightedDeformers((size_t)mesh.vertices.size(), meshDeformers, NUM_WEIGHTS_PER_VERTEX));
reweightedDeformers.push_back(getReweightedDeformers((size_t)mesh.vertices.size(), meshSkinClusters, NUM_WEIGHTS_PER_VERTEX));
}
}

View file

@ -19,7 +19,7 @@
class ReweightDeformersTask {
public:
using Input = baker::VaryingSet4<std::vector<hfm::Mesh>, std::vector<hfm::Shape>, std::vector<hfm::DynamicTransform>, std::vector<hfm::Deformer>>;
using Input = baker::VaryingSet4<std::vector<hfm::Mesh>, std::vector<hfm::Shape>, std::vector<hfm::SkinDeformer>, std::vector<hfm::SkinCluster>>;
using Output = std::vector<baker::ReweightedDeformers>;
using JobModel = baker::Job::ModelIO<ReweightDeformersTask, Input, Output>;

View file

@ -33,7 +33,7 @@ bool CauterizedModel::updateGeometry() {
if (_isCauterized && needsFullUpdate) {
assert(_cauterizeMeshStates.empty());
/* const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
const auto& hfmDynamicTransforms = hfmModel.skinDeformers;
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
const auto& dynT = hfmDynamicTransforms[i];
MeshState state;
@ -47,7 +47,7 @@ bool CauterizedModel::updateGeometry() {
}*/
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
const auto& hfmDynamicTransforms = hfmModel.skinDeformers;
int i = 0;
/* for (const auto& mesh: hfmModel.meshes) {
MeshState state;
@ -113,7 +113,7 @@ void CauterizedModel::createRenderItemSet() {
auto material = getNetworkModel()->getShapeMaterial(shapeID);
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.dynamicTransform });
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.skinDeformer });
}
/* int shapeID = 0;
@ -153,7 +153,7 @@ void CauterizedModel::updateClusterMatrices() {
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
const auto& hfmDynamicTransforms = hfmModel.skinDeformers;
for (int i = 0; i < (int)_meshStates.size(); i++) {
MeshState& state = _meshStates[i];
const auto& deformer = hfmDynamicTransforms[i];

View file

@ -336,7 +336,7 @@ bool Model::updateGeometry() {
updateShapeStatesFromRig();
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
const auto& hfmSkinDeformers = hfmModel.skinDeformers;
int i = 0;
/* for (const auto& mesh: hfmModel.meshes) {
MeshState state;
@ -346,8 +346,8 @@ bool Model::updateGeometry() {
i++;
}
*/
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
const auto& dynT = hfmDynamicTransforms[i];
for (int i = 0; i < hfmSkinDeformers.size(); i++) {
const auto& dynT = hfmSkinDeformers[i];
MeshState state;
state.clusterDualQuaternions.resize(dynT.clusters.size());
state.clusterMatrices.resize(dynT.clusters.size());
@ -1427,10 +1427,10 @@ void Model::updateClusterMatrices() {
_needsUpdateClusterMatrices = false;
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
const auto& hfmSkinDeformers = hfmModel.skinDeformers;
for (int i = 0; i < (int) _meshStates.size(); i++) {
MeshState& state = _meshStates[i];
const auto& deformer = hfmDynamicTransforms[i];
const auto& deformer = hfmSkinDeformers[i];
int meshIndex = i;
int clusterIndex = 0;
@ -1545,7 +1545,7 @@ void Model::createRenderItemSet() {
auto material = getNetworkModel()->getShapeMaterial(shapeID);
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.dynamicTransform });
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.skinDeformer });
}
/*
uint32_t numMeshes = (uint32_t)meshes.size();