From 05ac9aefa8fbd9121e27c009ac9b8b06f2e3cee7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 14 Oct 2019 02:21:01 -0700 Subject: [PATCH] the clusterMatrices should be working, but n skin index and weights are assigned yet --- libraries/animation/src/AnimSkeleton.cpp | 29 ++++ libraries/animation/src/AnimSkeleton.h | 2 + .../render-utils/src/CauterizedModel.cpp | 158 ++++++++++++++---- .../render-utils/src/MeshPartPayload.cpp | 44 +---- libraries/render-utils/src/MeshPartPayload.h | 8 +- libraries/render-utils/src/Model.cpp | 116 +++++++++---- libraries/render-utils/src/Model.h | 2 +- 7 files changed, 242 insertions(+), 117 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index b26d00d8d0..a68f5c869f 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -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 dummyClustersList; + + for (int j = 0; j < defor.clusters.size(); j++) { + std::vector bindMatrices; + // cast into a non-const reference, so we can mutate the FBXCluster + HFMCluster& cluster = const_cast(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 dummyClustersList; @@ -55,6 +83,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { } _clusterBindMatrixOriginalValues.push_back(dummyClustersList); } +*/ } AnimSkeleton::AnimSkeleton(const std::vector& joints, const QMap jointOffsets) { diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index efc1c1599f..526959df9a 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -70,6 +70,8 @@ public: std::vector lookUpJointIndices(const std::vector& 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& joints, const QMap jointOffsets); diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 9849880822..3e7c694768 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -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(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(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey, - primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) { - CauterizedMeshPartPayload& data = static_cast(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(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey, + primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) { + CauterizedMeshPartPayload& data = static_cast(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(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); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 2fb36dad67..a242c94299 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -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& 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& 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& blendshapeBuffers, const QVector& blendedMeshSizes) { if (_meshIndex < blendedMeshSizes.length() && blendedMeshSizes.at(_meshIndex) == _meshNumVertices) { auto blendshapeBuffer = blendshapeBuffers.find(_meshIndex); diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 9ddc62db40..50e06c024c 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -57,7 +57,6 @@ public: bool _hasColorAttrib { false }; graphics::Box _localBound; - graphics::Box _adjustedLocalBound; mutable graphics::Box _worldBound; std::shared_ptr _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& clusterMatrices); - - // dual quaternion skinning - void computeAdjustedLocalBound(const std::vector& 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 }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 662b6f190a..27e8725572 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -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(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(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(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(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 { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 0a102630b6..09fb9b581e 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -473,7 +473,7 @@ protected: QVector> _modelMeshRenderItems; QMap _modelMeshRenderItemsMap; render::ItemIDs _modelMeshRenderItemIDs; - using ShapeInfo = struct { int meshIndex; int deformerIndex; }; + using ShapeInfo = struct { int meshIndex; uint32_t deformerIndex{ hfm::UNDEFINED_KEY }; }; std::vector _modelMeshRenderItemShapes; std::vector _modelMeshMaterialNames;