getting the transform right for the rigid bodies

This commit is contained in:
Sam Gateau 2019-10-08 18:13:24 -07:00
parent 76bb720e12
commit 1f3993c308
6 changed files with 62 additions and 17 deletions

View file

@ -2496,7 +2496,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
if (_fullAvatarModelName.isEmpty()) { if (_fullAvatarModelName.isEmpty()) {
// Store the FST file name into preferences // Store the FST file name into preferences
const auto& mapping = _skeletonModel->getGeometry()->getMapping(); const auto& mapping = _skeletonModel->getNetworkModel()->getMapping();
if (mapping.value("name").isValid()) { if (mapping.value("name").isValid()) {
_fullAvatarModelName = mapping.value("name").toString(); _fullAvatarModelName = mapping.value("name").toString();
} }
@ -2504,7 +2504,7 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
initHeadBones(); initHeadBones();
_skeletonModel->setCauterizeBoneSet(_headBoneSet); _skeletonModel->setCauterizeBoneSet(_headBoneSet);
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl(); _fstAnimGraphOverrideUrl = _skeletonModel->getNetworkModel()->getAnimGraphOverrideUrl();
initAnimGraph(); initAnimGraph();
initFlowFromFST(); initFlowFromFST();

View file

@ -530,8 +530,8 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
if (object.properties.at(2) == "Mesh") { if (object.properties.at(2) == "Mesh") {
meshes.insert(getID(object.properties), extractMesh(object, meshIndex, deduplicateIndices)); meshes.insert(getID(object.properties), extractMesh(object, meshIndex, deduplicateIndices));
} else { // object.properties.at(2) == "Shape" } else { // object.properties.at(2) == "Shape"
ExtractedBlendshape extracted = { getID(object.properties), extractBlendshape(object) }; ExtractedBlendshape blendshape = { getID(object.properties), extractBlendshape(object) };
blendshapes.append(extracted); blendshapes.append(blendshape);
} }
} else if (object.name == "Model") { } else if (object.name == "Model") {
QString name = getModelName(object.properties); 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 // add the blendshapes included in the model, if any
if (mesh) { if (mesh) {
foreach (const ExtractedBlendshape& extracted, blendshapes) { foreach (const ExtractedBlendshape& blendshape, blendshapes) {
addBlendshapes(extracted, blendshapeIndices.values(extracted.id.toLatin1()), *mesh); 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 // assign the blendshapes to their corresponding meshes
foreach (const ExtractedBlendshape& extracted, blendshapes) { foreach (const ExtractedBlendshape& blendshape, blendshapes) {
QString blendshapeChannelID = _connectionParentMap.value(extracted.id); QString blendshapeChannelID = _connectionParentMap.value(blendshape.id);
QString blendshapeID = _connectionParentMap.value(blendshapeChannelID); QString blendshapeID = _connectionParentMap.value(blendshapeChannelID);
QString meshID = _connectionParentMap.value(blendshapeID); QString meshID = _connectionParentMap.value(blendshapeID);
addBlendshapes(extracted, blendshapeChannelIndices.values(blendshapeChannelID), meshes[meshID]); addBlendshapes(blendshape, blendshapeChannelIndices.values(blendshapeChannelID), meshes[meshID]);
} }
// get offset transform from mapping // get offset transform from mapping

View file

@ -104,9 +104,11 @@ void CauterizedModel::updateClusterMatrices() {
if (!_needsUpdateClusterMatrices || !isLoaded()) { if (!_needsUpdateClusterMatrices || !isLoaded()) {
return; return;
} }
updateShapeStatesFromRig();
_needsUpdateClusterMatrices = false; _needsUpdateClusterMatrices = false;
const HFMModel& hfmModel = getHFMModel(); const HFMModel& hfmModel = getHFMModel();
for (int i = 0; i < (int)_meshStates.size(); i++) { for (int i = 0; i < (int)_meshStates.size(); i++) {
Model::MeshState& state = _meshStates[i]; Model::MeshState& state = _meshStates[i];
const HFMMesh& mesh = hfmModel.meshes.at(i); const HFMMesh& mesh = hfmModel.meshes.at(i);
@ -221,13 +223,14 @@ void CauterizedModel::updateRenderItems() {
auto itemID = self->_modelMeshRenderItemIDs[i]; auto itemID = self->_modelMeshRenderItemIDs[i];
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
const auto& shapeState = self->getShapeState(i);
const auto& meshState = self->getMeshState(meshIndex); const auto& meshState = self->getMeshState(meshIndex);
const auto& cauterizedMeshState = self->getCauterizeMeshState(meshIndex); const auto& cauterizedMeshState = self->getCauterizeMeshState(meshIndex);
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey, transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning, cauterizedMeshState, invalidatePayloadShapeKey,
primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) { primitiveMode, renderItemKeyGlobalFlags, enableCauterization](ModelMeshPartPayload& mmppData) {
CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData); CauterizedMeshPartPayload& data = static_cast<CauterizedMeshPartPayload&>(mmppData);
if (useDualQuaternionSkinning) { if (useDualQuaternionSkinning) {
@ -241,7 +244,7 @@ void CauterizedModel::updateRenderItems() {
} }
Transform renderTransform = modelTransform; Transform renderTransform = modelTransform;
if (useDualQuaternionSkinning) { /*if (useDualQuaternionSkinning) {
if (meshState.clusterDualQuaternions.size() == 1 || meshState.clusterDualQuaternions.size() == 2) { if (meshState.clusterDualQuaternions.size() == 1 || meshState.clusterDualQuaternions.size() == 2) {
const auto& dq = meshState.clusterDualQuaternions[0]; const auto& dq = meshState.clusterDualQuaternions[0];
Transform transform(dq.getRotation(), Transform transform(dq.getRotation(),
@ -253,6 +256,9 @@ void CauterizedModel::updateRenderItems() {
if (meshState.clusterMatrices.size() == 1 || meshState.clusterMatrices.size() == 2) { if (meshState.clusterMatrices.size() == 1 || meshState.clusterMatrices.size() == 2) {
renderTransform = modelTransform.worldTransform(Transform(meshState.clusterMatrices[0])); renderTransform = modelTransform.worldTransform(Transform(meshState.clusterMatrices[0]));
} }
}*/
if (meshState.clusterMatrices.size() <= 1) {
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
} }
data.updateTransformForSkinnedMesh(renderTransform, modelTransform); data.updateTransformForSkinnedMesh(renderTransform, modelTransform);

View file

@ -221,8 +221,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
} }
updateTransform(transform, offsetTransform); updateTransform(transform, offsetTransform);
Transform renderTransform = transform; Transform renderTransform = transform;
if (useDualQuaternionSkinning) {
/* if (useDualQuaternionSkinning) {
if (state.clusterDualQuaternions.size() == 1) { if (state.clusterDualQuaternions.size() == 1) {
const auto& dq = state.clusterDualQuaternions[0]; const auto& dq = state.clusterDualQuaternions[0];
Transform transform(dq.getRotation(), Transform transform(dq.getRotation(),
@ -235,6 +237,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in
renderTransform = transform.worldTransform(Transform(state.clusterMatrices[0])); renderTransform = transform.worldTransform(Transform(state.clusterMatrices[0]));
} }
} }
*/
const Model::ShapeState& shapeState = model->getShapeState(shapeIndex);
renderTransform = transform.worldTransform(shapeState._rootFromJointTransform);
updateTransformForSkinnedMesh(renderTransform, transform); updateTransformForSkinnedMesh(renderTransform, transform);
initCache(model); initCache(model);
@ -320,7 +326,8 @@ void ModelMeshPartPayload::updateClusterBuffer(const std::vector<Model::Transfor
void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform) { void ModelMeshPartPayload::updateTransformForSkinnedMesh(const Transform& renderTransform, const Transform& boundTransform) {
_transform = renderTransform; _transform = renderTransform;
_worldBound = _adjustedLocalBound; _worldBound = _adjustedLocalBound;
_worldBound.transform(boundTransform); // _worldBound.transform(boundTransform);
_worldBound.transform(renderTransform);
} }
// Note that this method is called for models but not for shapes // Note that this method is called for models but not for shapes

View file

@ -232,12 +232,13 @@ void Model::updateRenderItems() {
auto itemID = self->_modelMeshRenderItemIDs[i]; auto itemID = self->_modelMeshRenderItemIDs[i];
auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex; auto meshIndex = self->_modelMeshRenderItemShapes[i].meshIndex;
const auto& shapeState = self->getShapeState(i);
const auto& meshState = self->getMeshState(meshIndex); const auto& meshState = self->getMeshState(meshIndex);
bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex);
bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning();
transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, meshState, useDualQuaternionSkinning, transaction.updateItem<ModelMeshPartPayload>(itemID, [modelTransform, shapeState, meshState, useDualQuaternionSkinning,
invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) { invalidatePayloadShapeKey, primitiveMode, renderItemKeyGlobalFlags, cauterized](ModelMeshPartPayload& data) {
if (useDualQuaternionSkinning) { if (useDualQuaternionSkinning) {
data.updateClusterBuffer(meshState.clusterDualQuaternions); data.updateClusterBuffer(meshState.clusterDualQuaternions);
@ -249,7 +250,7 @@ void Model::updateRenderItems() {
Transform renderTransform = modelTransform; Transform renderTransform = modelTransform;
if (useDualQuaternionSkinning) { /*if (useDualQuaternionSkinning) {
if (meshState.clusterDualQuaternions.size() == 1 || meshState.clusterDualQuaternions.size() == 2) { if (meshState.clusterDualQuaternions.size() == 1 || meshState.clusterDualQuaternions.size() == 2) {
const auto& dq = meshState.clusterDualQuaternions[0]; const auto& dq = meshState.clusterDualQuaternions[0];
Transform transform(dq.getRotation(), Transform transform(dq.getRotation(),
@ -261,6 +262,9 @@ void Model::updateRenderItems() {
if (meshState.clusterMatrices.size() == 1 || meshState.clusterMatrices.size() == 2) { if (meshState.clusterMatrices.size() == 1 || meshState.clusterMatrices.size() == 2) {
renderTransform = modelTransform.worldTransform(Transform(meshState.clusterMatrices[0])); renderTransform = modelTransform.worldTransform(Transform(meshState.clusterMatrices[0]));
} }
}*/
if (meshState.clusterMatrices.size() <= 1) {
renderTransform = modelTransform.worldTransform(shapeState._rootFromJointTransform);
} }
data.updateTransformForSkinnedMesh(renderTransform, modelTransform); 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 Model::updateGeometry() {
bool needFullUpdate = false; bool needFullUpdate = false;
@ -307,6 +326,8 @@ bool Model::updateGeometry() {
initJointStates(); initJointStates();
assert(_meshStates.empty()); assert(_meshStates.empty());
updateShapeStatesFromRig();
const HFMModel& hfmModel = getHFMModel(); const HFMModel& hfmModel = getHFMModel();
int i = 0; int i = 0;
foreach (const HFMMesh& mesh, hfmModel.meshes) { foreach (const HFMMesh& mesh, hfmModel.meshes) {
@ -1385,6 +1406,8 @@ void Model::updateClusterMatrices() {
return; return;
} }
updateShapeStatesFromRig();
_needsUpdateClusterMatrices = false; _needsUpdateClusterMatrices = false;
const HFMModel& hfmModel = getHFMModel(); const HFMModel& hfmModel = getHFMModel();
for (int i = 0; i < (int) _meshStates.size(); i++) { for (int i = 0; i < (int) _meshStates.size(); i++) {
@ -1418,6 +1441,7 @@ void Model::updateClusterMatrices() {
void Model::deleteGeometry() { void Model::deleteGeometry() {
_deleteGeometryCounter++; _deleteGeometryCounter++;
_shapeStates.clear();
_meshStates.clear(); _meshStates.clear();
_rig.destroyAnimGraph(); _rig.destroyAnimGraph();
_blendedBlendshapeCoefficients.clear(); _blendedBlendshapeCoefficients.clear();
@ -1496,7 +1520,7 @@ void Model::createRenderItemSet() {
} }
bool Model::isRenderable() const { bool Model::isRenderable() const {
return !_meshStates.empty() || (isLoaded() && _renderGeometry->getMeshes().empty()); return (!_shapeStates.empty() && !_meshStates.empty()) || (isLoaded() && _renderGeometry->getMeshes().empty());
} }
std::set<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialName) { std::set<unsigned int> Model::getMeshIDsFromMaterialID(QString parentMaterialName) {

View file

@ -343,6 +343,12 @@ public:
const MeshState& getMeshState(int index) { return _meshStates.at(index); } 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; } uint32_t getGeometryCounter() const { return _deleteGeometryCounter; }
const QMap<render::ItemID, render::PayloadPointer>& getRenderItems() const { return _modelMeshRenderItemsMap; } const QMap<render::ItemID, render::PayloadPointer>& getRenderItems() const { return _modelMeshRenderItemsMap; }
BlendShapeOperator getModelBlendshapeOperator() const { return _modelBlendshapeOperator; } 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 glm::vec3 _registrationPoint = glm::vec3(0.5f); /// the point in model space our center is snapped to
std::vector<MeshState> _meshStates; std::vector<MeshState> _meshStates;
std::vector<ShapeState> _shapeStates;
void updateShapeStatesFromRig();
virtual void initJointStates(); virtual void initJointStates();