From 1f3993c3080c93931f4e6e2e3d7639e1c2b7fe32 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 8 Oct 2019 18:13:24 -0700 Subject: [PATCH] getting the transform right for the rigid bodies --- interface/src/avatar/MyAvatar.cpp | 4 +-- libraries/fbx/src/FBXSerializer.cpp | 14 ++++----- .../render-utils/src/CauterizedModel.cpp | 12 ++++++-- .../render-utils/src/MeshPartPayload.cpp | 11 +++++-- libraries/render-utils/src/Model.cpp | 30 +++++++++++++++++-- libraries/render-utils/src/Model.h | 8 +++++ 6 files changed, 62 insertions(+), 17 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index de6ae526b4..a7fd397915 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2496,7 +2496,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { if (_fullAvatarModelName.isEmpty()) { // Store the FST file name into preferences - const auto& mapping = _skeletonModel->getGeometry()->getMapping(); + const auto& mapping = _skeletonModel->getNetworkModel()->getMapping(); if (mapping.value("name").isValid()) { _fullAvatarModelName = mapping.value("name").toString(); } @@ -2504,7 +2504,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { initHeadBones(); _skeletonModel->setCauterizeBoneSet(_headBoneSet); - _fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl(); + _fstAnimGraphOverrideUrl = _skeletonModel->getNetworkModel()->getAnimGraphOverrideUrl(); initAnimGraph(); initFlowFromFST(); diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 0299648294..2fa90af9db 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -530,8 +530,8 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const if (object.properties.at(2) == "Mesh") { meshes.insert(getID(object.properties), extractMesh(object, meshIndex, deduplicateIndices)); } else { // object.properties.at(2) == "Shape" - ExtractedBlendshape extracted = { getID(object.properties), extractBlendshape(object) }; - blendshapes.append(extracted); + ExtractedBlendshape blendshape = { getID(object.properties), extractBlendshape(object) }; + blendshapes.append(blendshape); } } else if (object.name == "Model") { QString name = getModelName(object.properties); @@ -705,8 +705,8 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const // add the blendshapes included in the model, if any if (mesh) { - foreach (const ExtractedBlendshape& extracted, blendshapes) { - addBlendshapes(extracted, blendshapeIndices.values(extracted.id.toLatin1()), *mesh); + foreach (const ExtractedBlendshape& blendshape, blendshapes) { + addBlendshapes(blendshape, blendshapeIndices.values(blendshape.id.toLatin1()), *mesh); } } @@ -1229,11 +1229,11 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const } // assign the blendshapes to their corresponding meshes - foreach (const ExtractedBlendshape& extracted, blendshapes) { - QString blendshapeChannelID = _connectionParentMap.value(extracted.id); + foreach (const ExtractedBlendshape& blendshape, blendshapes) { + QString blendshapeChannelID = _connectionParentMap.value(blendshape.id); QString blendshapeID = _connectionParentMap.value(blendshapeChannelID); QString meshID = _connectionParentMap.value(blendshapeID); - addBlendshapes(extracted, blendshapeChannelIndices.values(blendshapeChannelID), meshes[meshID]); + addBlendshapes(blendshape, blendshapeChannelIndices.values(blendshapeChannelID), meshes[meshID]); } // get offset transform from mapping diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 6e8f37d354..87eacc20ec 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -104,9 +104,11 @@ void CauterizedModel::updateClusterMatrices() { if (!_needsUpdateClusterMatrices || !isLoaded()) { return; } + + updateShapeStatesFromRig(); + _needsUpdateClusterMatrices = false; const HFMModel& hfmModel = getHFMModel(); - for (int i = 0; i < (int)_meshStates.size(); i++) { Model::MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); @@ -221,13 +223,14 @@ void CauterizedModel::updateRenderItems() { auto itemID = self->_modelMeshRenderItemIDs[i]; auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; + const auto& shapeState = self->getShapeState(i); const auto& meshState = self->getMeshState(meshIndex); const auto& cauterizedMeshState = self->getCauterizeMeshState(meshIndex); bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); - transaction.updateItem(itemID, [modelTransform, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey, + transaction.updateItem(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) { CauterizedMeshPartPayload& data = static_cast(mmppData); if (useDualQuaternionSkinning) { @@ -241,7 +244,7 @@ void CauterizedModel::updateRenderItems() { } Transform renderTransform = modelTransform; - if (useDualQuaternionSkinning) { + /*if (useDualQuaternionSkinning) { if (meshState.clusterDualQuaternions.size() == 1 || meshState.clusterDualQuaternions.size() == 2) { const auto& dq = meshState.clusterDualQuaternions[0]; Transform transform(dq.getRotation(), @@ -253,6 +256,9 @@ void CauterizedModel::updateRenderItems() { if (meshState.clusterMatrices.size() == 1 || meshState.clusterMatrices.size() == 2) { renderTransform = modelTransform.worldTransform(Transform(meshState.clusterMatrices[0])); } + }*/ + if (meshState.clusterMatrices.size() <= 1) { + renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform); } data.updateTransformForSkinnedMesh(renderTransform, modelTransform); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index fcf0ffaa48..8f992ba329 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -221,8 +221,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in } updateTransform(transform, offsetTransform); + Transform renderTransform = transform; - if (useDualQuaternionSkinning) { + +/* if (useDualQuaternionSkinning) { if (state.clusterDualQuaternions.size() == 1) { const auto& dq = state.clusterDualQuaternions[0]; Transform transform(dq.getRotation(), @@ -235,6 +237,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in renderTransform = transform.worldTransform(Transform(state.clusterMatrices[0])); } } +*/ + + const Model::ShapeState& shapeState = model->getShapeState(shapeIndex); + renderTransform = transform.worldTransform(shapeState._rootFromJointTransform); updateTransformForSkinnedMesh(renderTransform, transform); initCache(model); @@ -320,7 +326,8 @@ void ModelMeshPartPayload::updateClusterBuffer(const std::vector_modelMeshRenderItemIDs[i]; auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; + const auto& shapeState = self->getShapeState(i); const auto& meshState = self->getMeshState(meshIndex); bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); - transaction.updateItem(itemID, [modelTransform, meshState, useDualQuaternionSkinning, + transaction.updateItem(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) { if (useDualQuaternionSkinning) { data.updateClusterBuffer(meshState.clusterDualQuaternions); @@ -249,7 +250,7 @@ void Model::updateRenderItems() { Transform renderTransform = modelTransform; - if (useDualQuaternionSkinning) { + /*if (useDualQuaternionSkinning) { if (meshState.clusterDualQuaternions.size() == 1 || meshState.clusterDualQuaternions.size() == 2) { const auto& dq = meshState.clusterDualQuaternions[0]; Transform transform(dq.getRotation(), @@ -261,6 +262,9 @@ void Model::updateRenderItems() { if (meshState.clusterMatrices.size() == 1 || meshState.clusterMatrices.size() == 2) { renderTransform = modelTransform.worldTransform(Transform(meshState.clusterMatrices[0])); } + }*/ + if (meshState.clusterMatrices.size() <= 1) { + renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform); } data.updateTransformForSkinnedMesh(renderTransform, modelTransform); @@ -293,6 +297,21 @@ 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].transform; + if (jointId < _rig.getJointStateCount()) { + _shapeStates[s]._rootFromJointTransform = _rig.getJointTransform(shapes[s].transform); + } + } + } +} + bool Model::updateGeometry() { bool needFullUpdate = false; @@ -307,6 +326,8 @@ bool Model::updateGeometry() { initJointStates(); assert(_meshStates.empty()); + updateShapeStatesFromRig(); + const HFMModel& hfmModel = getHFMModel(); int i = 0; foreach (const HFMMesh& mesh, hfmModel.meshes) { @@ -1385,6 +1406,8 @@ void Model::updateClusterMatrices() { return; } + updateShapeStatesFromRig(); + _needsUpdateClusterMatrices = false; const HFMModel& hfmModel = getHFMModel(); for (int i = 0; i < (int) _meshStates.size(); i++) { @@ -1418,6 +1441,7 @@ void Model::updateClusterMatrices() { void Model::deleteGeometry() { _deleteGeometryCounter++; + _shapeStates.clear(); _meshStates.clear(); _rig.destroyAnimGraph(); _blendedBlendshapeCoefficients.clear(); @@ -1496,7 +1520,7 @@ void Model::createRenderItemSet() { } bool Model::isRenderable() const { - return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty()); + return (!_shapeStates.empty() && !_meshStates.empty()) || (isLoaded() && _renderGeometry->getMeshes().empty()); } std::set Model::getMeshIDsFromMaterialID(QString parentMaterialName) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 79ddaeb68d..85661d4b6b 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -343,6 +343,12 @@ public: 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; } @@ -420,6 +426,8 @@ protected: 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(); virtual void initJointStates();