mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-07 10:02:24 +02:00
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:
parent
f049ab7887
commit
eecaeb1155
12 changed files with 110 additions and 104 deletions
|
@ -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++) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>;
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue