mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 16:14:35 +02:00
getting the transform right for the rigid bodies
This commit is contained in:
parent
76bb720e12
commit
1f3993c308
6 changed files with 62 additions and 17 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue