From 695b9cdba64e20f739050da8afd76e98fb2fd874 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 18 Oct 2019 03:31:06 -0700 Subject: [PATCH 1/2] Clening up left over comments and typos, simplify the code to update Matrices in the model classes and removed renderITemsIdMap because not needed, chasing the problem of the physics objects transform --- libraries/animation/src/AnimSkeleton.cpp | 30 ----- libraries/animation/src/AnimSkeleton.h | 4 +- .../src/RenderableModelEntityItem.cpp | 4 +- libraries/hfm/src/hfm/HFM.h | 1 + .../render-utils/src/CauterizedModel.cpp | 87 ++++++-------- libraries/render-utils/src/CauterizedModel.h | 2 +- libraries/render-utils/src/Model.cpp | 107 ++++++++---------- libraries/render-utils/src/Model.h | 28 +++-- .../render-utils/src/SoftAttachmentModel.cpp | 38 +++---- tools/vhacd-util/src/VHACDUtil.cpp | 2 +- 10 files changed, 125 insertions(+), 178 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index bae1fb5b69..9a27ba766a 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -35,7 +35,6 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { 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)); @@ -55,35 +54,6 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { } _clusterBindMatrixOriginalValues.push_back(dummyClustersList); } - - -/* - for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { - const HFMMesh& mesh = hfmModel.meshes.at(i); - std::vector dummyClustersList; - - for (int j = 0; j < mesh.clusters.size(); j++) { - std::vector bindMatrices; - // cast into a non-const reference, so we can mutate the FBXCluster - HFMCluster& cluster = const_cast(mesh.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); - } -*/ } AnimSkeleton::AnimSkeleton(const std::vector& joints, const QMap jointOffsets) { diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 526959df9a..1477efb223 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -68,9 +68,7 @@ public: void dump(const AnimPoseVec& poses) const; 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]; } + const HFMCluster getClusterBindMatricesOriginalValues(const int skinDeformerIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[skinDeformerIndex][clusterIndex]; } protected: void buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e75b28f9ed..d7da3879f6 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -479,8 +479,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT)); for (uint32_t i = 0; i < numHFMMeshes; i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); - if (mesh.clusters.size() > 0) { - const HFMCluster& cluster = mesh.clusters.at(0); + if (i < hfmModel.skinDeformers.size() && hfmModel.skinDeformers[i].clusters.size() > 0) { + const HFMCluster& cluster = hfmModel.skinDeformers[i].clusters.at(0); auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex); // we backtranslate by the registration offset so we can apply that offset to the shapeInfo later localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix); diff --git a/libraries/hfm/src/hfm/HFM.h b/libraries/hfm/src/hfm/HFM.h index 15ed876d94..28dc8128e6 100644 --- a/libraries/hfm/src/hfm/HFM.h +++ b/libraries/hfm/src/hfm/HFM.h @@ -387,6 +387,7 @@ typedef hfm::Texture HFMTexture; typedef hfm::MeshPart HFMMeshPart; typedef hfm::Material HFMMaterial; typedef hfm::Mesh HFMMesh; +typedef hfm::SkinDeformer HFMSkinDeformer; typedef hfm::AnimationFrame HFMAnimationFrame; typedef hfm::Light HFMLight; typedef hfm::Model HFMModel; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 717d3cada7..2576b16354 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -33,14 +33,10 @@ bool CauterizedModel::updateGeometry() { if (_isCauterized && needsFullUpdate) { assert(_cauterizeMeshStates.empty()); - const HFMModel& hfmModel = getHFMModel(); - const auto& hfmDynamicTransforms = hfmModel.skinDeformers; - 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); + // initialize the cauterizedDeforemrStates as a copy of the standard deformerStates + _cauterizeMeshStates.resize(_meshStates.size()); + for (int i = 0; i < _meshStates.size(); ++i) { + _cauterizeMeshStates[i] = _meshStates[i]; } } return needsFullUpdate; @@ -57,7 +53,6 @@ void CauterizedModel::createRenderItemSet() { _modelMeshRenderItems.clear(); _modelMeshMaterialNames.clear(); - _modelMeshRenderItemShapes.clear(); Transform transform; transform.setTranslation(_translation); @@ -79,7 +74,6 @@ void CauterizedModel::createRenderItemSet() { auto material = getNetworkModel()->getShapeMaterial(shapeID); _modelMeshMaterialNames.push_back(material ? material->getName() : ""); - _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.skinDeformer }); } } else { Model::createRenderItemSet(); @@ -97,26 +91,20 @@ void CauterizedModel::updateClusterMatrices() { _needsUpdateClusterMatrices = false; - - const HFMModel& hfmModel = getHFMModel(); - const auto& hfmSkinDeformers = hfmModel.skinDeformers; - for (int meshIndex = 0; meshIndex < (int)_meshStates.size(); meshIndex++) { - MeshState& state = _meshStates[meshIndex]; - const auto& deformer = hfmSkinDeformers[meshIndex]; - - for (int clusterIndex = 0; clusterIndex < deformer.clusters.size(); clusterIndex++) { - const auto& cluster = deformer.clusters[clusterIndex]; - - const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex); + for (int skinDeformerIndex = 0; skinDeformerIndex < (int)_meshStates.size(); skinDeformerIndex++) { + MeshState& state = _meshStates[skinDeformerIndex]; + auto numClusters = state.getNumClusters(); + for (uint32_t clusterIndex = 0; clusterIndex < numClusters; clusterIndex++) { + const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(skinDeformerIndex, clusterIndex); if (_useDualQuaternionSkinning) { - auto jointPose = _rig.getJointPose(cluster.jointIndex); + auto jointPose = _rig.getJointPose(cbmov.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); } else { - auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); + auto jointMatrix = _rig.getJointTransform(cbmov.jointIndex); glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } } @@ -127,6 +115,7 @@ void CauterizedModel::updateClusterMatrices() { AnimPose cauterizePose = _rig.getJointPose(_rig.indexOfJoint("Neck")); cauterizePose.scale() = glm::vec3(0.0001f, 0.0001f, 0.0001f); + Transform cauterizedDQTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); static const glm::mat4 zeroScale( glm::vec4(0.0001f, 0.0f, 0.0f, 0.0f), @@ -135,30 +124,27 @@ void CauterizedModel::updateClusterMatrices() { glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig.getJointTransform(_rig.indexOfJoint("Neck")) * zeroScale; - for (int meshIndex = 0; meshIndex < _cauterizeMeshStates.size(); meshIndex++) { - Model::MeshState& state = _cauterizeMeshStates[meshIndex]; - const auto& deformer = hfmSkinDeformers[meshIndex]; + for (int skinDeformerIndex = 0; skinDeformerIndex < _cauterizeMeshStates.size(); skinDeformerIndex++) { + Model::MeshState& nonCauterizedState = _meshStates[skinDeformerIndex]; + Model::MeshState& state = _cauterizeMeshStates[skinDeformerIndex]; - for (int clusterIndex = 0; clusterIndex < deformer.clusters.size(); clusterIndex++) { - const auto& cluster = deformer.clusters[clusterIndex]; - - const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex); - - if (_useDualQuaternionSkinning) { - if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { - // not cauterized so just copy the value from the non-cauterized version. - state.clusterDualQuaternions[clusterIndex] = _meshStates[meshIndex].clusterDualQuaternions[clusterIndex]; - } else { - Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); + // Just reset cauterized state with normal state memcpy style + if (_useDualQuaternionSkinning) { + state.clusterDualQuaternions = nonCauterizedState.clusterDualQuaternions; + } else { + state.clusterMatrices = nonCauterizedState.clusterMatrices; + } + + // ANd only cauterize affected joints + auto numClusters = state.getNumClusters(); + for (uint32_t clusterIndex = 0; clusterIndex < numClusters; clusterIndex++) { + const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(skinDeformerIndex, clusterIndex); + if (_cauterizeBoneSet.find(cbmov.jointIndex) != _cauterizeBoneSet.end()) { + if (_useDualQuaternionSkinning) { Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); + Transform::mult(clusterTransform, cauterizedDQTransform, cbmov.inverseBindTransform); state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[clusterIndex].setCauterizationParameters(1.0f, cauterizePose.trans()); - } - } else { - if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { - // not cauterized so just copy the value from the non-cauterized version. - state.clusterMatrices[clusterIndex] = _meshStates[meshIndex].clusterMatrices[clusterIndex]; } else { glm_mat4u_mul(cauterizeMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } @@ -169,7 +155,7 @@ void CauterizedModel::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (modelBlender->shouldComputeBlendshapes() && getHFMModel().hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } @@ -209,22 +195,19 @@ void CauterizedModel::updateRenderItems() { render::Transaction transaction; for (int i = 0; i < (int)self->_modelMeshRenderItemIDs.size(); i++) { - auto itemID = self->_modelMeshRenderItemIDs[i]; - auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; const auto& shapeState = self->getShapeState(i); - auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex; - bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY); + auto skinDeformerIndex = shapeState._skinDeformerIndex; - bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); + bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(shapeState._meshIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); - if (isDeformed) { + if (skinDeformerIndex != hfm::UNDEFINED_KEY) { - const auto& meshState = self->getMeshState(deformerIndex); - const auto& cauterizedMeshState = self->getCauterizeMeshState(deformerIndex); + const auto& meshState = self->getMeshState(skinDeformerIndex); + const auto& cauterizedMeshState = self->getCauterizeMeshState(skinDeformerIndex); transaction.updateItem(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey, diff --git a/libraries/render-utils/src/CauterizedModel.h b/libraries/render-utils/src/CauterizedModel.h index 36a96fb006..7d241d7ac6 100644 --- a/libraries/render-utils/src/CauterizedModel.h +++ b/libraries/render-utils/src/CauterizedModel.h @@ -40,7 +40,7 @@ public: protected: std::unordered_set _cauterizeBoneSet; - QVector _cauterizeMeshStates; + std::vector _cauterizeMeshStates; bool _isCauterized { false }; bool _enableCauterization { false }; }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6df3c76a67..39ae7e6a8f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -151,7 +151,7 @@ void Model::setOffset(const glm::vec3& offset) { } void Model::calculateTextureInfo() { - if (!_hasCalculatedTextureInfo && isLoaded() && getNetworkModel()->areTexturesLoaded() && !_modelMeshRenderItemsMap.isEmpty()) { + if (!_hasCalculatedTextureInfo && isLoaded() && getNetworkModel()->areTexturesLoaded() && !_modelMeshRenderItemIDs.empty()) { size_t textureSize = 0; int textureCount = 0; bool allTexturesLoaded = true; @@ -228,25 +228,18 @@ void Model::updateRenderItems() { render::Transaction transaction; for (int i = 0; i < (int) self->_modelMeshRenderItemIDs.size(); i++) { - auto itemID = self->_modelMeshRenderItemIDs[i]; - auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; const auto& shapeState = self->getShapeState(i); - auto deformerIndex = self->_modelMeshRenderItemShapes[i].deformerIndex; - bool isDeformed = (deformerIndex != hfm::UNDEFINED_KEY); + auto skinDeformerIndex = shapeState._skinDeformerIndex; - bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); + bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(shapeState._meshIndex); - - if (isDeformed) { - - const auto& meshState = self->getMeshState(deformerIndex); - // MeshState meshState; + if (skinDeformerIndex != hfm::UNDEFINED_KEY) { + const auto& meshState = self->getMeshState(skinDeformerIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); - transaction.updateItem(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) { if (useDualQuaternionSkinning) { @@ -303,15 +296,11 @@ void Model::reset() { } void Model::updateShapeStatesFromRig() { - const HFMModel& hfmModel = getHFMModel(); - // TODO: should all Models have a valid _rig? { // Shapes state: - const auto& shapes = hfmModel.shapes; - _shapeStates.resize(shapes.size()); - for (int s = 0; s < shapes.size(); ++s) { - uint32_t jointId = shapes[s].joint; + for (auto& shape : _shapeStates) { + uint32_t jointId = shape._jointIndex; if (jointId < (uint32_t) _rig.getJointStateCount()) { - _shapeStates[s]._rootFromJointTransform = _rig.getJointTransform(jointId); + shape._rootFromJointTransform = _rig.getJointTransform(jointId); } } } @@ -331,9 +320,19 @@ bool Model::updateGeometry() { initJointStates(); assert(_meshStates.empty()); + const HFMModel& hfmModel = getHFMModel(); + + const auto& shapes = hfmModel.shapes; + _shapeStates.resize(shapes.size()); + for (int s = 0; s < shapes.size(); ++s) { + auto& shapeState = _shapeStates[s]; + shapeState._jointIndex = shapes[s].joint; + shapeState._meshIndex = shapes[s].mesh; + shapeState._meshPartIndex = shapes[s].meshPart; + shapeState._skinDeformerIndex = shapes[s].skinDeformer; + } updateShapeStatesFromRig(); - const HFMModel& hfmModel = getHFMModel(); const auto& hfmSkinDeformers = hfmModel.skinDeformers; for (int i = 0; i < hfmSkinDeformers.size(); i++) { const auto& dynT = hfmSkinDeformers[i]; @@ -740,9 +739,9 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe render::Transaction transaction; for (int i = 0; i < (int) _modelMeshRenderItemIDs.size(); i++) { auto itemID = _modelMeshRenderItemIDs[i]; - auto shape = _modelMeshRenderItemShapes[i]; + auto& shape = _shapeStates[i]; // TODO: check to see if .partIndex matches too - if (shape.meshIndex == meshIndex) { + if (shape._meshIndex == meshIndex) { transaction.updateItem(itemID, [=](ModelMeshPartPayload& data) { data.updateMeshPart(mesh, partIndex); }); @@ -904,8 +903,8 @@ void Model::updateRenderItemsKey(const render::ScenePointer& scene) { } auto renderItemsKey = _renderItemKeyGlobalFlags; render::Transaction transaction; - foreach(auto item, _modelMeshRenderItemsMap.keys()) { - transaction.updateItem(item, [renderItemsKey](ModelMeshPartPayload& data) { + for(auto itemID: _modelMeshRenderItemIDs) { + transaction.updateItem(itemID, [renderItemsKey](ModelMeshPartPayload& data) { data.updateKey(renderItemsKey); }); } @@ -975,8 +974,8 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) { return; } render::Transaction transaction; - foreach (auto item, _modelMeshRenderItemsMap.keys()) { - transaction.updateItem(item, [cauterized](ModelMeshPartPayload& data) { + for (auto itemID : _modelMeshRenderItemIDs) { + transaction.updateItem(itemID, [cauterized](ModelMeshPartPayload& data) { data.setCauterized(cauterized); }); } @@ -1003,26 +1002,25 @@ bool Model::addToScene(const render::ScenePointer& scene, bool somethingAdded = false; - if (_modelMeshRenderItemsMap.empty()) { + if (_modelMeshRenderItemIDs.empty()) { bool hasTransparent = false; size_t verticesCount = 0; foreach(auto renderItem, _modelMeshRenderItems) { auto item = scene->allocateID(); auto renderPayload = std::make_shared(renderItem); - if (_modelMeshRenderItemsMap.empty() && statusGetters.size()) { + if (_modelMeshRenderItemIDs.empty() && statusGetters.size()) { renderPayload->addStatusGetters(statusGetters); } transaction.resetItem(item, renderPayload); hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent(); verticesCount += renderItem.get()->getVerticesCount(); - _modelMeshRenderItemsMap.insert(item, renderPayload); _modelMeshRenderItemIDs.emplace_back(item); } - somethingAdded = !_modelMeshRenderItemsMap.empty(); + somethingAdded = !_modelMeshRenderItemIDs.empty(); _renderInfoVertexCount = verticesCount; - _renderInfoDrawCalls = _modelMeshRenderItemsMap.count(); + _renderInfoDrawCalls = (uint32_t) _modelMeshRenderItemIDs.size(); _renderInfoHasTransparent = hasTransparent; } @@ -1037,14 +1035,12 @@ bool Model::addToScene(const render::ScenePointer& scene, } void Model::removeFromScene(const render::ScenePointer& scene, render::Transaction& transaction) { - foreach (auto item, _modelMeshRenderItemsMap.keys()) { - transaction.removeItem(item); + for (auto itemID: _modelMeshRenderItemIDs) { + transaction.removeItem(itemID); } _modelMeshRenderItemIDs.clear(); - _modelMeshRenderItemsMap.clear(); _modelMeshRenderItems.clear(); _modelMeshMaterialNames.clear(); - _modelMeshRenderItemShapes.clear(); _priorityMap.clear(); _addedToScene = false; @@ -1415,25 +1411,22 @@ void Model::updateClusterMatrices() { updateShapeStatesFromRig(); _needsUpdateClusterMatrices = false; - const HFMModel& hfmModel = getHFMModel(); - const auto& hfmSkinDeformers = hfmModel.skinDeformers; - for (int meshIndex = 0; meshIndex < (int) _meshStates.size(); meshIndex++) { - MeshState& state = _meshStates[meshIndex]; - const auto& deformer = hfmSkinDeformers[meshIndex]; - for (int clusterIndex = 0; clusterIndex < deformer.clusters.size(); clusterIndex++) { - const auto& cluster = deformer.clusters[clusterIndex]; - - const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex); + for (int skinDeformerIndex = 0; skinDeformerIndex < (int)_meshStates.size(); skinDeformerIndex++) { + MeshState& state = _meshStates[skinDeformerIndex]; + auto numClusters = state.getNumClusters(); + for (uint32_t clusterIndex = 0; clusterIndex < numClusters; clusterIndex++) { + const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(skinDeformerIndex, clusterIndex); if (_useDualQuaternionSkinning) { - auto jointPose = _rig.getJointPose(cluster.jointIndex); + auto jointPose = _rig.getJointPose(cbmov.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); - } else { - auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); + } + else { + auto jointMatrix = _rig.getJointTransform(cbmov.jointIndex); glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } } @@ -1441,7 +1434,7 @@ void Model::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (modelBlender->shouldComputeBlendshapes() && getHFMModel().hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } @@ -1490,7 +1483,6 @@ void Model::createRenderItemSet() { _modelMeshRenderItems.clear(); _modelMeshMaterialNames.clear(); - _modelMeshRenderItemShapes.clear(); Transform transform; transform.setTranslation(_translation); @@ -1510,12 +1502,11 @@ void Model::createRenderItemSet() { auto material = getNetworkModel()->getShapeMaterial(shapeID); _modelMeshMaterialNames.push_back(material ? material->getName() : ""); - _modelMeshRenderItemShapes.emplace_back(ShapeInfo{ (int)shape.mesh, shape.skinDeformer }); } } bool Model::isRenderable() const { - return (!_shapeStates.empty() /* && !_meshStates.empty()*/) || (isLoaded() && _renderGeometry->getMeshes().empty()); + return (!_shapeStates.empty()) || (isLoaded() && _renderGeometry->getMeshes().empty()); } std::set Model::getMeshIDsFromMaterialID(QString parentMaterialName) { @@ -1571,11 +1562,11 @@ void Model::applyMaterialMapping() { PrimitiveMode primitiveMode = getPrimitiveMode(); bool useDualQuaternionSkinning = _useDualQuaternionSkinning; auto modelMeshRenderItemIDs = _modelMeshRenderItemIDs; - auto modelMeshRenderItemShapes = _modelMeshRenderItemShapes; + auto shapeStates = _shapeStates; std::unordered_map shouldInvalidatePayloadShapeKeyMap; - for (auto& shape : _modelMeshRenderItemShapes) { - shouldInvalidatePayloadShapeKeyMap[shape.meshIndex] = shouldInvalidatePayloadShapeKey(shape.meshIndex); + for (auto& shape : _shapeStates) { + shouldInvalidatePayloadShapeKeyMap[shape._meshIndex] = shouldInvalidatePayloadShapeKey(shape._meshIndex); } auto& materialMapping = getMaterialMapping(); @@ -1598,7 +1589,7 @@ void Model::applyMaterialMapping() { std::weak_ptr weakSelf = shared_from_this(); auto materialLoaded = [networkMaterialResource, shapeIDs, priorityMapPerResource, renderItemsKey, primitiveMode, useDualQuaternionSkinning, - modelMeshRenderItemIDs, modelMeshRenderItemShapes, shouldInvalidatePayloadShapeKeyMap, weakSelf]() { + modelMeshRenderItemIDs, shapeStates, shouldInvalidatePayloadShapeKeyMap, weakSelf]() { std::shared_ptr self = weakSelf.lock(); if (!self || networkMaterialResource->isFailed() || networkMaterialResource->parsedMaterials.names.size() == 0) { return; @@ -1624,7 +1615,7 @@ void Model::applyMaterialMapping() { for (auto shapeID : shapeIDs) { if (shapeID < modelMeshRenderItemIDs.size()) { auto itemID = modelMeshRenderItemIDs[shapeID]; - auto meshIndex = modelMeshRenderItemShapes[shapeID].meshIndex; + auto meshIndex = shapeStates[shapeID]._meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKeyMap.at(meshIndex); graphics::MaterialLayer material = graphics::MaterialLayer(networkMaterial, priorityMapPerResource.at(shapeID)); { @@ -1662,7 +1653,7 @@ void Model::addMaterial(graphics::MaterialLayer material, const std::string& par for (auto shapeID : shapeIDs) { if (shapeID < _modelMeshRenderItemIDs.size()) { auto itemID = _modelMeshRenderItemIDs[shapeID]; - auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; + auto meshIndex = _shapeStates[shapeID]._meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); transaction.updateItem(itemID, [material, renderItemsKey, invalidatePayloadShapeKey, primitiveMode, useDualQuaternionSkinning](ModelMeshPartPayload& data) { @@ -1684,7 +1675,7 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string auto itemID = _modelMeshRenderItemIDs[shapeID]; auto renderItemsKey = _renderItemKeyGlobalFlags; PrimitiveMode primitiveMode = getPrimitiveMode(); - auto meshIndex = _modelMeshRenderItemShapes[shapeID].meshIndex; + auto meshIndex = _shapeStates[shapeID]._meshIndex; bool invalidatePayloadShapeKey = shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = _useDualQuaternionSkinning; transaction.updateItem(itemID, [material, renderItemsKey, diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 09fb9b581e..0c04aca70c 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -297,6 +297,16 @@ public: int getRenderInfoDrawCalls() const { return _renderInfoDrawCalls; } bool getRenderInfoHasTransparent() const { return _renderInfoHasTransparent; } + class ShapeState { + public: + glm::mat4 _rootFromJointTransform; + uint32_t _jointIndex{ hfm::UNDEFINED_KEY }; + uint32_t _meshIndex{ hfm::UNDEFINED_KEY }; + uint32_t _meshPartIndex{ hfm::UNDEFINED_KEY }; + uint32_t _skinDeformerIndex{ hfm::UNDEFINED_KEY }; + }; + const ShapeState& getShapeState(int index) { return _shapeStates.at(index); } + class TransformDualQuaternion { public: TransformDualQuaternion() {} @@ -339,18 +349,13 @@ public: public: std::vector clusterDualQuaternions; std::vector clusterMatrices; - }; + uint32_t getNumClusters() const { return (uint32_t) std::max(clusterMatrices.size(), clusterMatrices.size()); } + }; const MeshState& getMeshState(int index) { return _meshStates.at(index); } - class ShapeState { - public: - glm::mat4 _rootFromJointTransform; - }; - const ShapeState& getShapeState(int index) { return _shapeStates.at(index); } - uint32_t getGeometryCounter() const { return _deleteGeometryCounter; } - const QMap& getRenderItems() const { return _modelMeshRenderItemsMap; } + BlendShapeOperator getModelBlendshapeOperator() const { return _modelBlendshapeOperator; } void renderDebugMeshBoxes(gpu::Batch& batch, bool forward); @@ -425,10 +430,12 @@ protected: bool _snappedToRegistrationPoint; /// are we currently snapped to a registration point glm::vec3 _registrationPoint = glm::vec3(0.5f); /// the point in model space our center is snapped to - std::vector _meshStates; + std::vector _shapeStates; void updateShapeStatesFromRig(); + std::vector _meshStates; + virtual void initJointStates(); void setScaleInternal(const glm::vec3& scale); @@ -471,10 +478,7 @@ protected: static AbstractViewStateInterface* _viewState; QVector> _modelMeshRenderItems; - QMap _modelMeshRenderItemsMap; render::ItemIDs _modelMeshRenderItemIDs; - using ShapeInfo = struct { int meshIndex; uint32_t deformerIndex{ hfm::UNDEFINED_KEY }; }; - std::vector _modelMeshRenderItemShapes; std::vector _modelMeshMaterialNames; bool _addedToScene { false }; // has been added to scene diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index 186f9e682a..1b8d1e7b69 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -41,37 +41,37 @@ void SoftAttachmentModel::updateClusterMatrices() { _needsUpdateClusterMatrices = false; - const HFMModel& hfmModel = getHFMModel(); - for (int i = 0; i < (int) _meshStates.size(); i++) { - MeshState& state = _meshStates[i]; - const HFMMesh& mesh = hfmModel.meshes.at(i); - int meshIndex = i; - for (int j = 0; j < mesh.clusters.size(); j++) { - const HFMCluster& cluster = mesh.clusters.at(j); + for (int skinDeformerIndex = 0; skinDeformerIndex < (int)_meshStates.size(); skinDeformerIndex++) { + MeshState& state = _meshStates[skinDeformerIndex]; + auto numClusters = state.getNumClusters(); + for (uint32_t clusterIndex = 0; clusterIndex < numClusters; clusterIndex++) { + const auto& cbmov = _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(skinDeformerIndex, clusterIndex); - int clusterIndex = j; // TODO: cache these look-ups as an optimization - int jointIndexOverride = getJointIndexOverride(cluster.jointIndex); - glm::mat4 jointMatrix; + int jointIndexOverride = getJointIndexOverride(cbmov.jointIndex); + auto rig = &_rigOverride; if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { - jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); - } else { - jointMatrix = _rig.getJointTransform(cluster.jointIndex); + rig = &_rig; } + if (_useDualQuaternionSkinning) { - glm::mat4 m; - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, m); - state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(m); - } else { - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); + auto jointPose = rig->getJointPose(cbmov.jointIndex); + Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); + Transform clusterTransform; + Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); + state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); + } + else { + auto jointMatrix = rig->getJointTransform(cbmov.jointIndex); + glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } } } // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (modelBlender->shouldComputeBlendshapes() && getHFMModel().hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/tools/vhacd-util/src/VHACDUtil.cpp b/tools/vhacd-util/src/VHACDUtil.cpp index 3410d35e6a..f0eb94a1cf 100644 --- a/tools/vhacd-util/src/VHACDUtil.cpp +++ b/tools/vhacd-util/src/VHACDUtil.cpp @@ -348,7 +348,7 @@ bool vhacd::VHACDUtil::computeVHACD(HFMModel& hfmModel, if (_verbose) { qDebug() << "mesh" << meshIndex << ": " - << " parts =" << mesh.parts.size() << " clusters =" << mesh.clusters.size() + << " parts =" << mesh.parts.size() << " vertices =" << numVertices; } ++meshIndex; From a95a4b5aa25dfbc88389bff32a9ddf84a6d6ded7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 18 Oct 2019 11:43:25 -0700 Subject: [PATCH 2/2] Address warnings and comments from review --- libraries/animation/src/AnimSkeleton.cpp | 2 +- libraries/fbx/src/OBJSerializer.cpp | 2 +- .../src/model-networking/ModelCache.cpp | 4 ++-- libraries/render-utils/src/CauterizedModel.cpp | 8 +++----- libraries/render-utils/src/MeshPartPayload.cpp | 3 --- libraries/render-utils/src/MeshPartPayload.h | 2 +- libraries/render-utils/src/Model.cpp | 13 +++++-------- 7 files changed, 13 insertions(+), 21 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 9a27ba766a..3afa7b0e3e 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -34,7 +34,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { const auto& defor = hfmModel.skinDeformers[i]; std::vector dummyClustersList; - for (int j = 0; j < defor.clusters.size(); j++) { + for (int j = 0; j < (uint32_t) defor.clusters.size(); j++) { // cast into a non-const reference, so we can mutate the FBXCluster HFMCluster& cluster = const_cast(defor.clusters.at(j)); diff --git a/libraries/fbx/src/OBJSerializer.cpp b/libraries/fbx/src/OBJSerializer.cpp index 47c88168b4..57fcf79aac 100644 --- a/libraries/fbx/src/OBJSerializer.cpp +++ b/libraries/fbx/src/OBJSerializer.cpp @@ -1009,7 +1009,7 @@ HFMModel::Pointer OBJSerializer::read(const hifi::ByteArray& data, const hifi::V } // GO over the shapes once more to assign hte material index correctly - for (int i = 0; i < hfmModel.shapes.size(); ++i) { + for (int i = 0; i < (uint32_t) hfmModel.shapes.size(); ++i) { auto foundMaterialIndex = materialNameToIndex.find(materialNamePerShape[i]); if (foundMaterialIndex != materialNameToIndex.end()) { hfmModel.shapes[i].material = foundMaterialIndex.value(); diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index 8b7db5957b..bb911c6914 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -491,8 +491,8 @@ bool NetworkModel::areTexturesLoaded() const { } const std::shared_ptr NetworkModel::getShapeMaterial(int shapeID) const { - auto materialID = getHFMModel().shapes[shapeID].material; - if ((materialID >= 0) && (materialID < (int)_materials.size())) { + uint32_t materialID = getHFMModel().shapes[shapeID].material; + if (materialID < (uint32_t)_materials.size()) { return _materials[materialID]; } return nullptr; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 2576b16354..ca26b9739c 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -35,7 +35,7 @@ bool CauterizedModel::updateGeometry() { // initialize the cauterizedDeforemrStates as a copy of the standard deformerStates _cauterizeMeshStates.resize(_meshStates.size()); - for (int i = 0; i < _meshStates.size(); ++i) { + for (int i = 0; i < (int) _meshStates.size(); ++i) { _cauterizeMeshStates[i] = _meshStates[i]; } } @@ -45,8 +45,6 @@ bool CauterizedModel::updateGeometry() { void CauterizedModel::createRenderItemSet() { if (_isCauterized) { assert(isLoaded()); - const auto& meshes = _renderGeometry->getMeshes(); - // We should not have any existing renderItems if we enter this section of code Q_ASSERT(_modelMeshRenderItems.isEmpty()); @@ -67,7 +65,7 @@ void CauterizedModel::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++) { + for (shapeID; shapeID < (int) shapes.size(); shapeID++) { const auto& shape = shapes[shapeID]; _modelMeshRenderItems << std::make_shared(shared_from_this(), shape.mesh, shape.meshPart, shapeID, transform); @@ -124,7 +122,7 @@ void CauterizedModel::updateClusterMatrices() { glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig.getJointTransform(_rig.indexOfJoint("Neck")) * zeroScale; - for (int skinDeformerIndex = 0; skinDeformerIndex < _cauterizeMeshStates.size(); skinDeformerIndex++) { + for (int skinDeformerIndex = 0; skinDeformerIndex < (int) _cauterizeMeshStates.size(); skinDeformerIndex++) { Model::MeshState& nonCauterizedState = _meshStates[skinDeformerIndex]; Model::MeshState& state = _cauterizeMeshStates[skinDeformerIndex]; diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 3f25d2ef80..6e3fe6ebec 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -210,11 +210,8 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in assert(shape.mesh == meshIndex); assert(shape.meshPart == partIndex); - bool useDualQuaternionSkinning = model->getUseDualQuaternionSkinning(); - auto& modelMesh = model->getNetworkModel()->getMeshes().at(_meshIndex); _meshNumVertices = (int)modelMesh->getNumVertices(); - // const Model::MeshState& state = model->getMeshState(_meshIndex); updateMeshPart(modelMesh, partIndex); diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 5d351e90d4..b207bd9403 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -118,7 +118,7 @@ public: int _meshIndex; int _shapeID; - int _deformerIndex; + uint32_t _deformerIndex; bool _isSkinned{ false }; bool _isBlendShaped { false }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 39ae7e6a8f..20568635f0 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -324,7 +324,7 @@ bool Model::updateGeometry() { const auto& shapes = hfmModel.shapes; _shapeStates.resize(shapes.size()); - for (int s = 0; s < shapes.size(); ++s) { + for (uint32_t s = 0; s < (uint32_t) shapes.size(); ++s) { auto& shapeState = _shapeStates[s]; shapeState._jointIndex = shapes[s].joint; shapeState._meshIndex = shapes[s].mesh; @@ -334,7 +334,7 @@ bool Model::updateGeometry() { updateShapeStatesFromRig(); const auto& hfmSkinDeformers = hfmModel.skinDeformers; - for (int i = 0; i < hfmSkinDeformers.size(); i++) { + for (uint32_t i = 0; i < (uint32_t) hfmSkinDeformers.size(); i++) { const auto& dynT = hfmSkinDeformers[i]; MeshState state; state.clusterDualQuaternions.resize(dynT.clusters.size()); @@ -741,7 +741,7 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe auto itemID = _modelMeshRenderItemIDs[i]; auto& shape = _shapeStates[i]; // TODO: check to see if .partIndex matches too - if (shape._meshIndex == meshIndex) { + if (shape._meshIndex == (uint32_t) meshIndex) { transaction.updateItem(itemID, [=](ModelMeshPartPayload& data) { data.updateMeshPart(mesh, partIndex); }); @@ -1424,8 +1424,7 @@ void Model::updateClusterMatrices() { Transform clusterTransform; Transform::mult(clusterTransform, jointTransform, cbmov.inverseBindTransform); state.clusterDualQuaternions[clusterIndex] = Model::TransformDualQuaternion(clusterTransform); - } - else { + } else { auto jointMatrix = _rig.getJointTransform(cbmov.jointIndex); glm_mat4u_mul(jointMatrix, cbmov.inverseBindMatrix, state.clusterMatrices[clusterIndex]); } @@ -1476,7 +1475,6 @@ const render::ItemIDs& Model::fetchRenderItemIDs() const { void Model::createRenderItemSet() { assert(isLoaded()); - const auto& meshes = _renderGeometry->getMeshes(); // We should not have any existing renderItems if we enter this section of code Q_ASSERT(_modelMeshRenderItems.isEmpty()); @@ -1493,9 +1491,8 @@ void Model::createRenderItemSet() { offset.postTranslate(_offset); // 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++) { + for (uint32_t shapeID = 0; shapeID < shapes.size(); shapeID++) { const auto& shape = shapes[shapeID]; _modelMeshRenderItems << std::make_shared(shared_from_this(), shape.mesh, shape.meshPart, shapeID, transform);