the clusterMatrices should be working, but n skin index and weights are assigned yet

This commit is contained in:
Sam Gateau 2019-10-14 02:21:01 -07:00
parent 8af507571c
commit 05ac9aefa8
7 changed files with 242 additions and 117 deletions

View file

@ -30,6 +30,34 @@ 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];
std::vector<HFMCluster> dummyClustersList;
for (int j = 0; j < defor.clusters.size(); j++) {
std::vector<glm::mat4> bindMatrices;
// cast into a non-const reference, so we can mutate the FBXCluster
HFMCluster& cluster = const_cast<HFMCluster&>(defor.clusters.at(j));
HFMCluster localCluster;
localCluster.jointIndex = cluster.jointIndex;
localCluster.inverseBindMatrix = cluster.inverseBindMatrix;
localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix);
// if we have a joint offset in the fst file then multiply its inverse by the
// model cluster inverse bind matrix
if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) {
AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3());
localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix;
localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix);
}
dummyClustersList.push_back(localCluster);
}
_clusterBindMatrixOriginalValues.push_back(dummyClustersList);
}
/*
for (int i = 0; i < (int)hfmModel.meshes.size(); i++) {
const HFMMesh& mesh = hfmModel.meshes.at(i);
std::vector<HFMCluster> dummyClustersList;
@ -55,6 +83,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
}
_clusterBindMatrixOriginalValues.push_back(dummyClustersList);
}
*/
}
AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets) {

View file

@ -70,6 +70,8 @@ public:
std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const;
const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; }
// const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; }
protected:
void buildSkeletonFromJoints(const std::vector<HFMJoint>& joints, const QMap<int, glm::quat> jointOffsets);

View file

@ -32,8 +32,8 @@ bool CauterizedModel::updateGeometry() {
bool needsFullUpdate = Model::updateGeometry();
if (_isCauterized && needsFullUpdate) {
assert(_cauterizeMeshStates.empty());
const HFMModel& hfmModel = getHFMModel();
/* const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
/* const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
const auto& dynT = hfmDynamicTransforms[i];
MeshState state;
@ -45,7 +45,27 @@ bool CauterizedModel::updateGeometry() {
_cauterizeMeshStates.append(state);
_meshStates.push_back(state);
}*/
foreach (const HFMMesh& mesh, hfmModel.meshes) {
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
int i = 0;
/* for (const auto& mesh: hfmModel.meshes) {
MeshState state;
state.clusterDualQuaternions.resize(mesh.clusters.size());
state.clusterMatrices.resize(mesh.clusters.size());
_meshStates.push_back(state);
i++;
}
*/
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
const auto& dynT = hfmDynamicTransforms[i];
MeshState state;
state.clusterDualQuaternions.resize(dynT.clusters.size());
state.clusterMatrices.resize(dynT.clusters.size());
_cauterizeMeshStates.push_back(state);
}
/* foreach (const HFMMesh& mesh, hfmModel.meshes) {
Model::MeshState state;
if (_useDualQuaternionSkinning) {
state.clusterDualQuaternions.resize(mesh.clusters.size());
@ -54,7 +74,7 @@ bool CauterizedModel::updateGeometry() {
state.clusterMatrices.resize(mesh.clusters.size());
_cauterizeMeshStates.append(state);
}
}
}*/
}
return needsFullUpdate;
}
@ -64,11 +84,6 @@ void CauterizedModel::createRenderItemSet() {
assert(isLoaded());
const auto& meshes = _renderGeometry->getMeshes();
// all of our mesh vectors must match in size
if (meshes.size() != _meshStates.size()) {
qCDebug(renderutils) << "WARNING!!!! Mesh Sizes don't match! We will not segregate mesh groups yet.";
// return;
}
// We should not have any existing renderItems if we enter this section of code
Q_ASSERT(_modelMeshRenderItems.isEmpty());
@ -88,7 +103,20 @@ void CauterizedModel::createRenderItemSet() {
Transform::mult(transform, transform, offset);
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0;
const auto& shapes = _renderGeometry->getHFMModel().shapes;
for (shapeID; shapeID < shapes.size(); shapeID++) {
const auto& shape = shapes[shapeID];
_modelMeshRenderItems << std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), shape.mesh, shape.meshPart, shapeID, transform);
auto material = getNetworkModel()->getShapeMaterial(shapeID);
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.dynamicTransform });
}
/* int shapeID = 0;
uint32_t numMeshes = (uint32_t)meshes.size();
for (uint32_t i = 0; i < numMeshes; i++) {
const auto& mesh = meshes.at(i);
@ -106,7 +134,7 @@ void CauterizedModel::createRenderItemSet() {
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i });
shapeID++;
}
}
}*/
} else {
Model::createRenderItemSet();
}
@ -122,6 +150,38 @@ void CauterizedModel::updateClusterMatrices() {
updateShapeStatesFromRig();
_needsUpdateClusterMatrices = false;
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
for (int i = 0; i < (int)_meshStates.size(); i++) {
MeshState& state = _meshStates[i];
const auto& deformer = hfmDynamicTransforms[i];
int meshIndex = i;
int clusterIndex = 0;
for (int d = 0; d < deformer.clusters.size(); d++) {
const auto& cluster = deformer.clusters[d];
clusterIndex = d;
const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex);
if (_useDualQuaternionSkinning) {
auto jointPose = _rig.getJointPose(cluster.jointIndex);
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
Transform clusterTransform;
Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform);
state.clusterDualQuaternions[d] = Model::TransformDualQuaternion(clusterTransform);
}
else {
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[d]);
}
}
}
/*
const HFMModel& hfmModel = getHFMModel();
for (int i = 0; i < (int)_meshStates.size(); i++) {
Model::MeshState& state = _meshStates[i];
@ -145,7 +205,7 @@ void CauterizedModel::updateClusterMatrices() {
}
}
}
*/
// as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty.
if (!_cauterizeBoneSet.empty()) {
@ -236,42 +296,66 @@ void CauterizedModel::updateRenderItems() {
auto itemID = self->_modelMeshRenderItemIDs[i];
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
auto deformerIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
const auto& shapeState = self->getShapeState(i);
// const auto& meshState = self->getMeshState(meshIndex);
// const auto& cauterizedMeshState = self->getCauterizeMeshState(meshIndex);
MeshState meshState;
MeshState cauterizedMeshState;
auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex;
bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY);
// auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
// auto deformerIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
// const auto& shapeState = self->getShapeState(i);
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData);
if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions,
cauterizedMeshState.clusterDualQuaternions);
data.computeAdjustedLocalBound(meshState.clusterDualQuaternions);
} else {
data.updateClusterBuffer(meshState.clusterMatrices,
cauterizedMeshState.clusterMatrices);
data.computeAdjustedLocalBound(meshState.clusterMatrices);
}
Transform renderTransform = modelTransform;
if (meshState.clusterMatrices.size() <= 2) {
if (isDeformed) {
const auto& meshState = self->getMeshState(deformerIndex);
const auto& cauterizedMeshState = self->getCauterizeMeshState(deformerIndex);
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData);
if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions,
cauterizedMeshState.clusterDualQuaternions);
} else {
data.updateClusterBuffer(meshState.clusterMatrices,
cauterizedMeshState.clusterMatrices);
}
Transform renderTransform = modelTransform;
// if (meshState.clusterMatrices.size() <= 2) {
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
// }
data.updateTransform(renderTransform);
data.updateTransformForCauterizedMesh(renderTransform);
data.setEnableCauterization(enableCauterization);
data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
});
} else {
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
Transform renderTransform = modelTransform;
// if (meshState.clusterMatrices.size() <= 1) {
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
}
data.updateTransform(renderTransform);
data.updateTransformForCauterizedMesh(renderTransform);
// }
data.updateTransform(renderTransform);
data.setEnableCauterization(enableCauterization);
data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
});
// data.setEnableCauterization(enableCauterization);
data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, false);
});
}
}
scene->enqueueTransaction(transaction);

View file

@ -213,17 +213,13 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
updateMeshPart(modelMesh, partIndex);
if (useDualQuaternionSkinning) {
// computeAdjustedLocalBound(state.clusterDualQuaternions);
} else {
// computeAdjustedLocalBound(state.clusterMatrices);
}
Transform renderTransform = transform;
const Model::ShapeState& shapeState = model->getShapeState(shapeIndex);
renderTransform = transform.worldTransform(shapeState._rootFromJointTransform);
updateTransform(renderTransform);
_deformerIndex = shape.dynamicTransform;
initCache(model);
#if defined(Q_OS_MAC) || defined(Q_OS_ANDROID)
@ -245,7 +241,9 @@ void ModelMeshPartPayload::initCache(const ModelPointer& model) {
if (_drawMesh) {
auto vertexFormat = _drawMesh->getVertexFormat();
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
if (_deformerIndex != hfm::UNDEFINED_KEY) {
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
}
const HFMModel& hfmModel = model->getHFMModel();
const HFMMesh& mesh = hfmModel.meshes.at(_meshIndex);
@ -432,38 +430,6 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
args->_details._trianglesRendered += _drawPart._numIndices / INDICES_PER_TRIANGLE;
}
void ModelMeshPartPayload::computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices) {
_adjustedLocalBound = _localBound;
if (clusterMatrices.size() > 0) {
_adjustedLocalBound.transform(clusterMatrices.back());
for (int i = 0; i < (int)clusterMatrices.size() - 1; ++i) {
AABox clusterBound = _localBound;
clusterBound.transform(clusterMatrices[i]);
_adjustedLocalBound += clusterBound;
}
}
}
void ModelMeshPartPayload::computeAdjustedLocalBound(const std::vector<Model::TransformDualQuaternion>& clusterDualQuaternions) {
_adjustedLocalBound = _localBound;
if (clusterDualQuaternions.size() > 0) {
Transform rootTransform(clusterDualQuaternions.back().getRotation(),
clusterDualQuaternions.back().getScale(),
clusterDualQuaternions.back().getTranslation());
_adjustedLocalBound.transform(rootTransform);
for (int i = 0; i < (int)clusterDualQuaternions.size() - 1; ++i) {
AABox clusterBound = _localBound;
Transform transform(clusterDualQuaternions[i].getRotation(),
clusterDualQuaternions[i].getScale(),
clusterDualQuaternions[i].getTranslation());
clusterBound.transform(transform);
_adjustedLocalBound += clusterBound;
}
}
}
void ModelMeshPartPayload::setBlendshapeBuffer(const std::unordered_map<int, gpu::BufferPointer>& blendshapeBuffers, const QVector<int>& blendedMeshSizes) {
if (_meshIndex < blendedMeshSizes.length() && blendedMeshSizes.at(_meshIndex) == _meshNumVertices) {
auto blendshapeBuffer = blendshapeBuffers.find(_meshIndex);

View file

@ -57,7 +57,6 @@ public:
bool _hasColorAttrib { false };
graphics::Box _localBound;
graphics::Box _adjustedLocalBound;
mutable graphics::Box _worldBound;
std::shared_ptr<const graphics::Mesh> _drawMesh;
@ -111,12 +110,6 @@ public:
void bindMesh(gpu::Batch& batch) override;
void bindTransform(gpu::Batch& batch, RenderArgs::RenderMode renderMode) const override;
// matrix palette skinning
void computeAdjustedLocalBound(const std::vector<glm::mat4>& clusterMatrices);
// dual quaternion skinning
void computeAdjustedLocalBound(const std::vector<Model::TransformDualQuaternion>& clusterDualQuaternions);
gpu::BufferPointer _clusterBuffer;
enum class ClusterBufferType { Matrices, DualQuaternions };
@ -124,6 +117,7 @@ public:
int _meshIndex;
int _shapeID;
int _deformerIndex;
bool _isSkinned{ false };
bool _isBlendShaped { false };

View file

@ -186,7 +186,7 @@ bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
const auto& networkMeshes = getNetworkModel()->getMeshes();
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
// to false to rebuild out mesh groups.
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)hfmModel.meshes.size() || meshIndex >= (int)_meshStates.size()) {
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)hfmModel.meshes.size() /* || meshIndex >= (int)_meshStates.size()*/) {
_needsFixupInScene = true; // trigger remove/add cycle
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
return true;
@ -233,32 +233,51 @@ void Model::updateRenderItems() {
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
const auto& shapeState = self->getShapeState(i);
// const auto& meshState = self->getMeshState(meshIndex);
MeshState meshState;
auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex;
bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY);
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning,
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) {
if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions);
data.computeAdjustedLocalBound(meshState.clusterDualQuaternions);
} else {
data.updateClusterBuffer(meshState.clusterMatrices);
data.computeAdjustedLocalBound(meshState.clusterMatrices);
}
if (isDeformed) {
Transform renderTransform = modelTransform;
if (meshState.clusterMatrices.size() <= 1) {
const auto& meshState = self->getMeshState(deformerIndex);
// MeshState meshState;
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning,
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) {
if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions);
} else {
data.updateClusterBuffer(meshState.clusterMatrices);
}
Transform renderTransform = modelTransform;
// if (meshState.clusterMatrices.size() <= 1) {
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
// }
data.updateTransform(renderTransform);
data.setCauterized(cauterized);
data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
});
} else {
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) {
Transform renderTransform = modelTransform;
// if (meshState.clusterMatrices.size() <= 1) {
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
}
data.updateTransform(renderTransform);
// }
data.updateTransform(renderTransform);
data.setCauterized(cauterized);
data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning);
});
data.updateKey(renderItemKeyGlobalFlags);
data.setShapeKey(invalidatePayloadShapeKey, primitiveMode, false);
});
}
}
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
@ -317,8 +336,8 @@ bool Model::updateGeometry() {
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
/* int i = 0;
for (const auto& mesh: hfmModel.meshes) {
int i = 0;
/* for (const auto& mesh: hfmModel.meshes) {
MeshState state;
state.clusterDualQuaternions.resize(mesh.clusters.size());
state.clusterMatrices.resize(mesh.clusters.size());
@ -326,13 +345,13 @@ bool Model::updateGeometry() {
i++;
}
*/
/*for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
for (int i = 0; i < hfmDynamicTransforms.size(); i++) {
const auto& dynT = hfmDynamicTransforms[i];
MeshState state;
state.clusterDualQuaternions.resize(dynT.clusters.size());
state.clusterMatrices.resize(dynT.clusters.size());
_meshStates.push_back(state);
}*/
}
needFullUpdate = true;
emit rigReady();
@ -1407,8 +1426,34 @@ void Model::updateClusterMatrices() {
_needsUpdateClusterMatrices = false;
const HFMModel& hfmModel = getHFMModel();
const auto& hfmDynamicTransforms = hfmModel.dynamicTransforms;
for (int i = 0; i < (int) _meshStates.size(); i++) {
MeshState& state = _meshStates[i];
const auto& deformer = hfmDynamicTransforms[i];
int meshIndex = i;
int clusterIndex = 0;
for (int d = 0; d < deformer.clusters.size(); d++) {
const auto& cluster = deformer.clusters[d];
clusterIndex = d;
const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex);
if (_useDualQuaternionSkinning) {
auto jointPose = _rig.getJointPose(cluster.jointIndex);
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
Transform clusterTransform;
Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform);
state.clusterDualQuaternions[d] = Model::TransformDualQuaternion(clusterTransform);
}
else {
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[d]);
}
}
/*
int meshIndex = i;
const HFMMesh& mesh = hfmModel.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) {
@ -1425,7 +1470,7 @@ void Model::updateClusterMatrices() {
auto jointMatrix = _rig.getJointTransform(cluster.jointIndex);
glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]);
}
}
}*/
}
// post the blender if we're not currently waiting for one to finish
@ -1474,12 +1519,6 @@ void Model::createRenderItemSet() {
assert(isLoaded());
const auto& meshes = _renderGeometry->getMeshes();
// all of our mesh vectors must match in size
if (meshes.size() != _meshStates.size()) {
qCDebug(renderutils) << "WARNING!!!! Mesh Sizes don't match! " << meshes.size() << _meshStates.size() << " We will not segregate mesh groups yet.";
// return;
}
// We should not have any existing renderItems if we enter this section of code
Q_ASSERT(_modelMeshRenderItems.isEmpty());
@ -1497,6 +1536,17 @@ void Model::createRenderItemSet() {
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0;
const auto& shapes = _renderGeometry->getHFMModel().shapes;
for (shapeID; shapeID < shapes.size(); shapeID++) {
const auto& shape = shapes[shapeID];
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), shape.mesh, shape.meshPart, shapeID, transform);
auto material = getNetworkModel()->getShapeMaterial(shapeID);
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.dynamicTransform });
}
/*
uint32_t numMeshes = (uint32_t)meshes.size();
for (uint32_t i = 0; i < numMeshes; i++) {
const auto& mesh = meshes.at(i);
@ -1513,7 +1563,7 @@ void Model::createRenderItemSet() {
_modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)i });
shapeID++;
}
}
}*/
}
bool Model::isRenderable() const {

View file

@ -473,7 +473,7 @@ protected:
QVector<std::shared_ptr<ModelMeshPartPayload>> _modelMeshRenderItems;
QMap<render::ItemID, render::PayloadPointer> _modelMeshRenderItemsMap;
render::ItemIDs _modelMeshRenderItemIDs;
using ShapeInfo = struct { int meshIndex; int deformerIndex; };
using ShapeInfo = struct { int meshIndex; uint32_t deformerIndex{ hfm::UNDEFINED_KEY }; };
std::vector<ShapeInfo> _modelMeshRenderItemShapes;
std::vector<std::string> _modelMeshMaterialNames;