From 13f11e1056a80f2d3b1e6c4fd86ac36d1398b021 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 28 May 2014 14:53:32 -0700 Subject: [PATCH 1/4] Remove "fromBind" arg in Model::setJointRotation It was always set 'true'. --- interface/src/avatar/SkeletonModel.cpp | 10 +++++----- interface/src/renderer/Model.cpp | 5 ++--- interface/src/renderer/Model.h | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 7333bfc395..2001802524 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -45,7 +45,7 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { } int jointIndex = geometry.humanIKJointIndices.at(humanIKJointIndex); if (jointIndex != -1) { - setJointRotation(jointIndex, _rotation * prioVR->getJointRotations().at(i), true, PALM_PRIORITY); + setJointRotation(jointIndex, _rotation * prioVR->getJointRotations().at(i), PALM_PRIORITY); } } return; @@ -188,7 +188,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { setJointPosition(parentJointIndex, palm.getPosition() + forearmVector * geometry.joints.at(jointIndex).distanceToParent * extractUniformScale(_scale), glm::quat(), false, -1, false, glm::vec3(0.0f, -1.0f, 0.0f), PALM_PRIORITY); - setJointRotation(parentJointIndex, palmRotation, true, PALM_PRIORITY); + setJointRotation(parentJointIndex, palmRotation, PALM_PRIORITY); _jointStates[jointIndex].rotation = glm::quat(); } else { @@ -355,12 +355,12 @@ void SkeletonModel::setHandPosition(int jointIndex, const glm::vec3& position, c glm::vec3 forwardVector(rightHand ? -1.0f : 1.0f, 0.0f, 0.0f); glm::quat shoulderRotation = rotationBetween(forwardVector, elbowPosition - shoulderPosition); - setJointRotation(shoulderJointIndex, shoulderRotation, true, PALM_PRIORITY); + setJointRotation(shoulderJointIndex, shoulderRotation, PALM_PRIORITY); setJointRotation(elbowJointIndex, rotationBetween(shoulderRotation * forwardVector, - wristPosition - elbowPosition) * shoulderRotation, true, PALM_PRIORITY); + wristPosition - elbowPosition) * shoulderRotation, PALM_PRIORITY); - setJointRotation(jointIndex, rotation, true, PALM_PRIORITY); + setJointRotation(jointIndex, rotation, PALM_PRIORITY); } bool SkeletonModel::getLeftHandPosition(glm::vec3& position) const { diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 5a93dbcf25..7fff554498 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1231,15 +1231,14 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const return true; } -bool Model::setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind, float priority) { +bool Model::setJointRotation(int jointIndex, const glm::quat& rotation, float priority) { if (jointIndex == -1 || _jointStates.isEmpty()) { return false; } JointState& state = _jointStates[jointIndex]; if (priority >= state.animationPriority) { state.rotation = state.rotation * glm::inverse(state.combinedRotation) * rotation * - glm::inverse(fromBind ? _geometry->getFBXGeometry().joints.at(jointIndex).inverseBindRotation : - _geometry->getFBXGeometry().joints.at(jointIndex).inverseDefaultRotation); + glm::inverse(_geometry->getFBXGeometry().joints.at(jointIndex).inverseBindRotation); state.animationPriority = priority; } return true; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index a4e45287dd..75e80fdaa8 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -221,7 +221,7 @@ protected: bool setJointPosition(int jointIndex, const glm::vec3& translation, const glm::quat& rotation = glm::quat(), bool useRotation = false, int lastFreeIndex = -1, bool allIntermediatesFree = false, const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f), float priority = 1.0f); - bool setJointRotation(int jointIndex, const glm::quat& rotation, bool fromBind = false, float priority = 1.0f); + bool setJointRotation(int jointIndex, const glm::quat& rotation, float priority = 1.0f); void setJointTranslation(int jointIndex, const glm::vec3& translation); From 9f2a4ae6260b0f24a43ab3137a246166f10175e8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 28 May 2014 16:49:39 -0700 Subject: [PATCH 2/4] Make JointState a proper class JointState gets a pointer to its corresponding FBXJoint --- interface/src/avatar/FaceModel.cpp | 12 +- interface/src/avatar/SkeletonModel.cpp | 22 ++-- interface/src/renderer/Model.cpp | 157 +++++++++++++------------ interface/src/renderer/Model.h | 25 ++-- 4 files changed, 115 insertions(+), 101 deletions(-) diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 2cf2f70068..6ecc45e1e3 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -49,9 +49,9 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) { void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { // get the rotation axes in joint space and use them to adjust the rotation glm::mat3 axes = glm::mat3_cast(_rotation); - glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * + glm::mat3 inverse = glm::mat3(glm::inverse(parentState._transform * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(joint.preRotation))); - state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2])) + state._rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2])) * glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getFinalYaw(), glm::normalize(inverse * axes[1])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalPitch(), glm::normalize(inverse * axes[0])) * joint.rotation; @@ -59,23 +59,23 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { // likewise with the eye joints - glm::mat4 inverse = glm::inverse(parentState.transform * glm::translate(state.translation) * + glm::mat4 inverse = glm::inverse(parentState._transform * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)); glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientation() * IDENTITY_FRONT, 0.0f)); glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() + _owningHead->getSaccade() - _translation, 1.0f)); glm::quat between = rotationBetween(front, lookAt); const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE; - state.rotation = glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * + state._rotation = glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) * joint.rotation; } void FaceModel::updateJointState(int index) { JointState& state = _jointStates[index]; - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const FBXJoint& joint = geometry.joints.at(index); + const FBXJoint& joint = state.getFBXJoint(); if (joint.parentIndex != -1) { const JointState& parentState = _jointStates.at(joint.parentIndex); + const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (index == geometry.neckJointIndex) { maybeUpdateNeckRotation(parentState, joint, state); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2001802524..3586e525ae 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -189,7 +189,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { geometry.joints.at(jointIndex).distanceToParent * extractUniformScale(_scale), glm::quat(), false, -1, false, glm::vec3(0.0f, -1.0f, 0.0f), PALM_PRIORITY); setJointRotation(parentJointIndex, palmRotation, PALM_PRIORITY); - _jointStates[jointIndex].rotation = glm::quat(); + _jointStates[jointIndex]._rotation = glm::quat(); } else { setJointPosition(jointIndex, palm.getPosition(), palmRotation, @@ -199,10 +199,10 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { void SkeletonModel::updateJointState(int index) { JointState& state = _jointStates[index]; - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const FBXJoint& joint = geometry.joints.at(index); + const FBXJoint& joint = state.getFBXJoint(); if (joint.parentIndex != -1) { const JointState& parentState = _jointStates.at(joint.parentIndex); + const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (index == geometry.leanJointIndex) { maybeUpdateLeanRotation(parentState, joint, state); @@ -217,9 +217,9 @@ void SkeletonModel::updateJointState(int index) { Model::updateJointState(index); if (index == _geometry->getFBXGeometry().rootJointIndex) { - state.transform[3][0] = 0.0f; - state.transform[3][1] = 0.0f; - state.transform[3][2] = 0.0f; + state._transform[3][0] = 0.0f; + state._transform[3][1] = 0.0f; + state._transform[3][2] = 0.0f; } } @@ -229,9 +229,9 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const } // get the rotation axes in joint space and use them to adjust the rotation glm::mat3 axes = glm::mat3_cast(_rotation); - glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * + glm::mat3 inverse = glm::mat3(glm::inverse(parentState._transform * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation))); - state.rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), + state._rotation = glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation; } @@ -255,11 +255,11 @@ void SkeletonModel::renderJointConstraints(int jointIndex) { do { const FBXJoint& joint = geometry.joints.at(jointIndex); const JointState& jointState = _jointStates.at(jointIndex); - glm::vec3 position = extractTranslation(jointState.transform) + _translation; + glm::vec3 position = extractTranslation(jointState._transform) + _translation; glPushMatrix(); glTranslatef(position.x, position.y, position.z); - glm::quat parentRotation = (joint.parentIndex == -1) ? _rotation : _jointStates.at(joint.parentIndex).combinedRotation; + glm::quat parentRotation = (joint.parentIndex == -1) ? _rotation : _jointStates.at(joint.parentIndex)._combinedRotation; glm::vec3 rotationAxis = glm::axis(parentRotation); glRotatef(glm::degrees(glm::angle(parentRotation)), rotationAxis.x, rotationAxis.y, rotationAxis.z); float fanScale = directionSize * 0.75f; @@ -292,7 +292,7 @@ void SkeletonModel::renderJointConstraints(int jointIndex) { } glPopMatrix(); - renderOrientationDirections(position, jointState.combinedRotation, directionSize); + renderOrientationDirections(position, jointState._combinedRotation, directionSize); jointIndex = joint.parentIndex; } while (jointIndex != -1 && geometry.joints.at(jointIndex).isFree); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index a8914feb79..648a748f01 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -135,13 +135,14 @@ void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locati program.release(); } -QVector Model::createJointStates(const FBXGeometry& geometry) { +QVector Model::createJointStates(const FBXGeometry& geometry) { QVector jointStates; foreach (const FBXJoint& joint, geometry.joints) { JointState state; - state.translation = joint.translation; - state.rotation = joint.rotation; - state.animationPriority = 0.0f; + state._translation = joint.translation; + state._rotation = joint.rotation; + state._animationPriority = 0.0f; + state.setFBXJoint(joint); jointStates.append(state); } @@ -160,23 +161,23 @@ QVector Model::createJointStates(const FBXGeometry& geometry) continue; } JointState& state = jointStates[i]; - const FBXJoint& joint = geometry.joints[i]; + const FBXJoint& joint = state.getFBXJoint(); int parentIndex = joint.parentIndex; if (parentIndex == -1) { _rootIndex = i; glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset); - glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation; - state.transform = baseTransform * geometry.offset * glm::translate(state.translation) * joint.preTransform * + glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; + state._transform = baseTransform * geometry.offset * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; - state.combinedRotation = _rotation * combinedRotation; + state._combinedRotation = _rotation * combinedRotation; ++numJointsSet; jointIsSet[i] = true; } else if (jointIsSet[parentIndex]) { const JointState& parentState = jointStates.at(parentIndex); - glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation; - state.transform = parentState.transform * glm::translate(state.translation) * joint.preTransform * + glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; + state._transform = parentState._transform * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; - state.combinedRotation = parentState.combinedRotation * combinedRotation; + state._combinedRotation = parentState._combinedRotation * combinedRotation; ++numJointsSet; jointIsSet[i] = true; } @@ -372,7 +373,7 @@ void Model::reset() { } const FBXGeometry& geometry = _geometry->getFBXGeometry(); for (int i = 0; i < _jointStates.size(); i++) { - _jointStates[i].rotation = geometry.joints.at(i).rotation; + _jointStates[i]._rotation = geometry.joints.at(i).rotation; } } @@ -582,7 +583,7 @@ bool Model::getJointState(int index, glm::quat& rotation) const { if (index == -1 || index >= _jointStates.size()) { return false; } - rotation = _jointStates.at(index).rotation; + rotation = _jointStates.at(index)._rotation; const glm::quat& defaultRotation = _geometry->getFBXGeometry().joints.at(index).rotation; return glm::abs(rotation.x - defaultRotation.x) >= EPSILON || glm::abs(rotation.y - defaultRotation.y) >= EPSILON || @@ -593,13 +594,13 @@ bool Model::getJointState(int index, glm::quat& rotation) const { void Model::setJointState(int index, bool valid, const glm::quat& rotation, float priority) { if (index != -1 && index < _jointStates.size()) { JointState& state = _jointStates[index]; - if (priority >= state.animationPriority) { + if (priority >= state._animationPriority) { if (valid) { - state.rotation = rotation; - state.animationPriority = priority; - } else if (priority == state.animationPriority) { - state.rotation = _geometry->getFBXGeometry().joints.at(index).rotation; - state.animationPriority = 0.0f; + state._rotation = rotation; + state._animationPriority = priority; + } else if (priority == state._animationPriority) { + state._rotation = _geometry->getFBXGeometry().joints.at(index).rotation; + state._animationPriority = 0.0f; } } } @@ -632,7 +633,7 @@ bool Model::getJointPosition(int jointIndex, glm::vec3& position) const { if (jointIndex == -1 || _jointStates.isEmpty()) { return false; } - position = _translation + extractTranslation(_jointStates[jointIndex].transform); + position = _translation + extractTranslation(_jointStates[jointIndex]._transform); return true; } @@ -640,7 +641,7 @@ bool Model::getJointRotation(int jointIndex, glm::quat& rotation, bool fromBind) if (jointIndex == -1 || _jointStates.isEmpty()) { return false; } - rotation = _jointStates[jointIndex].combinedRotation * + rotation = _jointStates[jointIndex]._combinedRotation * (fromBind ? _geometry->getFBXGeometry().joints[jointIndex].inverseBindRotation : _geometry->getFBXGeometry().joints[jointIndex].inverseDefaultRotation); return true; @@ -858,11 +859,11 @@ void Model::updateShapePositions() { for (int i = 0; i < _jointStates.size(); i++) { const FBXJoint& joint = geometry.joints[i]; // shape position and rotation need to be in world-frame - glm::vec3 jointToShapeOffset = uniformScale * (_jointStates[i].combinedRotation * joint.shapePosition); - glm::vec3 worldPosition = extractTranslation(_jointStates[i].transform) + jointToShapeOffset + _translation; + glm::vec3 jointToShapeOffset = uniformScale * (_jointStates[i]._combinedRotation * joint.shapePosition); + glm::vec3 worldPosition = extractTranslation(_jointStates[i]._transform) + jointToShapeOffset + _translation; Shape* shape = _jointShapes[i]; shape->setPosition(worldPosition); - shape->setRotation(_jointStates[i].combinedRotation * joint.shapeRotation); + shape->setRotation(_jointStates[i]._combinedRotation * joint.shapeRotation); float distance = glm::distance(worldPosition, _translation) + shape->getBoundingRadius(); if (distance > _boundingRadius) { _boundingRadius = distance; @@ -884,12 +885,12 @@ bool Model::findRayIntersection(const glm::vec3& origin, const glm::vec3& direct float radiusScale = extractUniformScale(_scale); for (int i = 0; i < _jointStates.size(); i++) { const FBXJoint& joint = geometry.joints[i]; - glm::vec3 end = extractTranslation(_jointStates[i].transform); + glm::vec3 end = extractTranslation(_jointStates[i]._transform); float endRadius = joint.boneRadius * radiusScale; glm::vec3 start = end; float startRadius = joint.boneRadius * radiusScale; if (joint.parentIndex != -1) { - start = extractTranslation(_jointStates[joint.parentIndex].transform); + start = extractTranslation(_jointStates[joint.parentIndex]._transform); startRadius = geometry.joints[joint.parentIndex].boneRadius * radiusScale; } // for now, use average of start and end radii @@ -1115,7 +1116,7 @@ void Model::simulateInternal(float deltaTime) { const FBXMesh& mesh = geometry.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { const FBXCluster& cluster = mesh.clusters.at(j); - state.clusterMatrices[j] = _jointStates[cluster.jointIndex].transform * cluster.inverseBindMatrix; + state.clusterMatrices[j] = _jointStates[cluster.jointIndex]._transform * cluster.inverseBindMatrix; } } @@ -1127,21 +1128,21 @@ void Model::simulateInternal(float deltaTime) { void Model::updateJointState(int index) { JointState& state = _jointStates[index]; - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const FBXJoint& joint = geometry.joints.at(index); + const FBXJoint& joint = state.getFBXJoint(); if (joint.parentIndex == -1) { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset); - glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation; - state.transform = baseTransform * geometry.offset * glm::translate(state.translation) * joint.preTransform * + glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; + state._transform = baseTransform * geometry.offset * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; - state.combinedRotation = _rotation * combinedRotation; + state._combinedRotation = _rotation * combinedRotation; } else { const JointState& parentState = _jointStates.at(joint.parentIndex); - glm::quat combinedRotation = joint.preRotation * state.rotation * joint.postRotation; - state.transform = parentState.transform * glm::translate(state.translation) * joint.preTransform * + glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; + state._transform = parentState._transform * glm::translate(state._translation) * joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; - state.combinedRotation = parentState.combinedRotation * combinedRotation; + state._combinedRotation = parentState._combinedRotation * combinedRotation; } } @@ -1174,17 +1175,17 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const } // then, we go from the joint upwards, rotating the end as close as possible to the target - glm::vec3 endPosition = extractTranslation(_jointStates[jointIndex].transform); + glm::vec3 endPosition = extractTranslation(_jointStates[jointIndex]._transform); for (int j = 1; freeLineage.at(j - 1) != lastFreeIndex; j++) { int index = freeLineage.at(j); - const FBXJoint& joint = geometry.joints.at(index); + JointState& state = _jointStates[index]; + const FBXJoint& joint = state.getFBXJoint(); if (!(joint.isFree || allIntermediatesFree)) { continue; } - JointState& state = _jointStates[index]; - glm::vec3 jointPosition = extractTranslation(state.transform); + glm::vec3 jointPosition = extractTranslation(state._transform); glm::vec3 jointVector = endPosition - jointPosition; - glm::quat oldCombinedRotation = state.combinedRotation; + glm::quat oldCombinedRotation = state._combinedRotation; glm::quat combinedDelta; float combinedWeight; if (useRotation) { @@ -1202,7 +1203,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const for (int k = j - 1; k > 0; k--) { int index = freeLineage.at(k); updateJointState(index); - positionSum += extractTranslation(_jointStates.at(index).transform); + positionSum += extractTranslation(_jointStates.at(index)._transform); } glm::vec3 projectedCenterOfMass = glm::cross(jointVector, glm::cross(positionSum / (j - 1.0f) - jointPosition, jointVector)); @@ -1214,7 +1215,7 @@ bool Model::setJointPosition(int jointIndex, const glm::vec3& translation, const } } applyRotationDelta(index, combinedDelta, true, priority); - glm::quat actualDelta = state.combinedRotation * glm::inverse(oldCombinedRotation); + glm::quat actualDelta = state._combinedRotation * glm::inverse(oldCombinedRotation); endPosition = actualDelta * jointVector + jointPosition; if (useRotation) { endRotation = actualDelta * endRotation; @@ -1236,29 +1237,29 @@ bool Model::setJointRotation(int jointIndex, const glm::quat& rotation, float pr return false; } JointState& state = _jointStates[jointIndex]; - if (priority >= state.animationPriority) { - state.rotation = state.rotation * glm::inverse(state.combinedRotation) * rotation * + if (priority >= state._animationPriority) { + state._rotation = state._rotation * glm::inverse(state._combinedRotation) * rotation * glm::inverse(_geometry->getFBXGeometry().joints.at(jointIndex).inverseBindRotation); - state.animationPriority = priority; + state._animationPriority = priority; } return true; } void Model::setJointTranslation(int jointIndex, const glm::vec3& translation) { - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const FBXJoint& joint = geometry.joints.at(jointIndex); + JointState& state = _jointStates[jointIndex]; + const FBXJoint& joint = state.getFBXJoint(); glm::mat4 parentTransform; if (joint.parentIndex == -1) { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); parentTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometry.offset; } else { - parentTransform = _jointStates.at(joint.parentIndex).transform; + parentTransform = _jointStates.at(joint.parentIndex)._transform; } - JointState& state = _jointStates[jointIndex]; glm::vec3 preTranslation = extractTranslation(joint.preTransform * glm::mat4_cast(joint.preRotation * - state.rotation * joint.postRotation) * joint.postTransform); - state.translation = glm::vec3(glm::inverse(parentTransform) * glm::vec4(translation, 1.0f)) - preTranslation; + state._rotation * joint.postRotation) * joint.postTransform); + state._translation = glm::vec3(glm::inverse(parentTransform) * glm::vec4(translation, 1.0f)) - preTranslation; } bool Model::restoreJointPosition(int jointIndex, float percent, float priority) { @@ -1270,11 +1271,11 @@ bool Model::restoreJointPosition(int jointIndex, float percent, float priority) foreach (int index, freeLineage) { JointState& state = _jointStates[index]; - if (priority == state.animationPriority) { + if (priority == state._animationPriority) { const FBXJoint& joint = geometry.joints.at(index); - state.rotation = safeMix(state.rotation, joint.rotation, percent); - state.translation = glm::mix(state.translation, joint.translation, percent); - state.animationPriority = 0.0f; + state._rotation = safeMix(state._rotation, joint.rotation, percent); + state._translation = glm::mix(state._translation, joint.translation, percent); + state._animationPriority = 0.0f; } } return true; @@ -1296,23 +1297,23 @@ float Model::getLimbLength(int jointIndex) const { void Model::applyRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority) { JointState& state = _jointStates[jointIndex]; - if (priority < state.animationPriority) { + if (priority < state._animationPriority) { return; } - state.animationPriority = priority; - const FBXJoint& joint = _geometry->getFBXGeometry().joints[jointIndex]; + state._animationPriority = priority; + const FBXJoint& joint = state.getFBXJoint(); if (!constrain || (joint.rotationMin == glm::vec3(-PI, -PI, -PI) && joint.rotationMax == glm::vec3(PI, PI, PI))) { // no constraints - state.rotation = state.rotation * glm::inverse(state.combinedRotation) * delta * state.combinedRotation; - state.combinedRotation = delta * state.combinedRotation; + state._rotation = state._rotation * glm::inverse(state._combinedRotation) * delta * state._combinedRotation; + state._combinedRotation = delta * state._combinedRotation; return; } - glm::quat targetRotation = delta * state.combinedRotation; - glm::vec3 eulers = safeEulerAngles(state.rotation * glm::inverse(state.combinedRotation) * targetRotation); + glm::quat targetRotation = delta * state._combinedRotation; + glm::vec3 eulers = safeEulerAngles(state._rotation * glm::inverse(state._combinedRotation) * targetRotation); glm::quat newRotation = glm::quat(glm::clamp(eulers, joint.rotationMin, joint.rotationMax)); - state.combinedRotation = state.combinedRotation * glm::inverse(state.rotation) * newRotation; - state.rotation = newRotation; + state._combinedRotation = state._combinedRotation * glm::inverse(state._rotation) * newRotation; + state._rotation = newRotation; } const int BALL_SUBDIVISIONS = 10; @@ -1850,10 +1851,10 @@ void AnimationHandle::simulate(float deltaTime) { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - Model::JointState& state = _model->_jointStates[mapping]; - if (_priority >= state.animationPriority) { - state.rotation = frame.rotations.at(i); - state.animationPriority = _priority; + JointState& state = _model->_jointStates[mapping]; + if (_priority >= state._animationPriority) { + state._rotation = frame.rotations.at(i); + state._animationPriority = _priority; } } } @@ -1874,10 +1875,10 @@ void AnimationHandle::simulate(float deltaTime) { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - Model::JointState& state = _model->_jointStates[mapping]; - if (_priority >= state.animationPriority) { - state.rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); - state.animationPriority = _priority; + JointState& state = _model->_jointStates[mapping]; + if (_priority >= state._animationPriority) { + state._rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + state._animationPriority = _priority; } } } @@ -1887,10 +1888,16 @@ void AnimationHandle::replaceMatchingPriorities(float newPriority) { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - Model::JointState& state = _model->_jointStates[mapping]; - if (_priority == state.animationPriority) { - state.animationPriority = newPriority; + JointState& state = _model->_jointStates[mapping]; + if (_priority == state._animationPriority) { + state._animationPriority = newPriority; } } } } + +JointState::JointState() : + _translation(0.0f), + _animationPriority(0.0f), + _fbxJoint(NULL) { +} diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 75e80fdaa8..69d584f267 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -30,6 +30,22 @@ class Shape; typedef QSharedPointer AnimationHandlePointer; typedef QWeakPointer WeakAnimationHandlePointer; + +class JointState { +public: + JointState(); + glm::vec3 _translation; // translation relative to parent + glm::quat _rotation; // rotation relative to parent + glm::mat4 _transform; // rotation to world frame + translation in model frame + glm::quat _combinedRotation; // rotation from joint local to world frame + float _animationPriority; // the priority of the animation affecting this joint + + void setFBXJoint(const FBXJoint& joint) { _fbxJoint = &joint; } + const FBXJoint& getFBXJoint() const { return *_fbxJoint; } + +private: + const FBXJoint* _fbxJoint; // JointState does not own its FBXJoint +}; /// A generic 3D model displaying geometry loaded from a URL. class Model : public QObject { @@ -182,15 +198,6 @@ protected: bool _snappedToCenter; /// are we currently snapped to center int _rootIndex; - class JointState { - public: - glm::vec3 translation; // translation relative to parent - glm::quat rotation; // rotation relative to parent - glm::mat4 transform; // rotation to world frame + translation in model frame - glm::quat combinedRotation; // rotation from joint local to world frame - float animationPriority; // the priority of the animation affecting this joint - }; - bool _shapesAreDirty; QVector _jointStates; QVector _jointShapes; From b15b0fd96cb30c199715673d972c7394a13529f7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 28 May 2014 17:31:07 -0700 Subject: [PATCH 3/4] cleaner initialization of JointState --- interface/src/renderer/Model.cpp | 13 ++++++++++--- interface/src/renderer/Model.h | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 648a748f01..7e21bbb90f 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -139,9 +139,6 @@ QVector Model::createJointStates(const FBXGeometry& geometry) { QVector jointStates; foreach (const FBXJoint& joint, geometry.joints) { JointState state; - state._translation = joint.translation; - state._rotation = joint.rotation; - state._animationPriority = 0.0f; state.setFBXJoint(joint); jointStates.append(state); } @@ -1896,8 +1893,18 @@ void AnimationHandle::replaceMatchingPriorities(float newPriority) { } } +// ---------------------------------------------------------------------------- +// JointState TODO: move this class to its own files +// ---------------------------------------------------------------------------- JointState::JointState() : _translation(0.0f), _animationPriority(0.0f), _fbxJoint(NULL) { } + +void JointState::setFBXJoint(const FBXJoint& joint) { + assert(&joint != NULL); + _translation = joint.translation; + _rotation = joint.rotation; + _fbxJoint = &joint; +} diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 69d584f267..be58a1d7f2 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -40,7 +40,7 @@ public: glm::quat _combinedRotation; // rotation from joint local to world frame float _animationPriority; // the priority of the animation affecting this joint - void setFBXJoint(const FBXJoint& joint) { _fbxJoint = &joint; } + void setFBXJoint(const FBXJoint& joint); const FBXJoint& getFBXJoint() const { return *_fbxJoint; } private: From ec25982a58256442dda8b434710cdd297d002888 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 28 May 2014 17:51:17 -0700 Subject: [PATCH 4/4] add JointState::updateWorldTransform() --- interface/src/renderer/Model.cpp | 30 ++++++++++++------------------ interface/src/renderer/Model.h | 9 ++++++--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 7e21bbb90f..215678dedc 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -162,19 +162,13 @@ QVector Model::createJointStates(const FBXGeometry& geometry) { int parentIndex = joint.parentIndex; if (parentIndex == -1) { _rootIndex = i; - glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset); - glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; - state._transform = baseTransform * geometry.offset * glm::translate(state._translation) * joint.preTransform * - glm::mat4_cast(combinedRotation) * joint.postTransform; - state._combinedRotation = _rotation * combinedRotation; + glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometry.offset; + state.updateWorldTransform(baseTransform, _rotation); ++numJointsSet; jointIsSet[i] = true; } else if (jointIsSet[parentIndex]) { const JointState& parentState = jointStates.at(parentIndex); - glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; - state._transform = parentState._transform * glm::translate(state._translation) * joint.preTransform * - glm::mat4_cast(combinedRotation) * joint.postTransform; - state._combinedRotation = parentState._combinedRotation * combinedRotation; + state.updateWorldTransform(parentState._transform, parentState._combinedRotation); ++numJointsSet; jointIsSet[i] = true; } @@ -1129,17 +1123,11 @@ void Model::updateJointState(int index) { if (joint.parentIndex == -1) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); - glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset); - glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; - state._transform = baseTransform * geometry.offset * glm::translate(state._translation) * joint.preTransform * - glm::mat4_cast(combinedRotation) * joint.postTransform; - state._combinedRotation = _rotation * combinedRotation; + glm::mat4 baseTransform = glm::mat4_cast(_rotation) * glm::scale(_scale) * glm::translate(_offset) * geometry.offset; + state.updateWorldTransform(baseTransform, _rotation); } else { const JointState& parentState = _jointStates.at(joint.parentIndex); - glm::quat combinedRotation = joint.preRotation * state._rotation * joint.postRotation; - state._transform = parentState._transform * glm::translate(state._translation) * joint.preTransform * - glm::mat4_cast(combinedRotation) * joint.postTransform; - state._combinedRotation = parentState._combinedRotation * combinedRotation; + state.updateWorldTransform(parentState._transform, parentState._combinedRotation); } } @@ -1908,3 +1896,9 @@ void JointState::setFBXJoint(const FBXJoint& joint) { _rotation = joint.rotation; _fbxJoint = &joint; } + +void JointState::updateWorldTransform(const glm::mat4& baseTransform, const glm::quat& parentRotation) { + glm::quat combinedRotation = _fbxJoint->preRotation * _rotation * _fbxJoint->postRotation; + _transform = baseTransform * glm::translate(_translation) * _fbxJoint->preTransform * glm::mat4_cast(combinedRotation) * _fbxJoint->postTransform; + _combinedRotation = parentRotation * combinedRotation; +} diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index be58a1d7f2..349e8305c4 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -34,15 +34,18 @@ typedef QWeakPointer WeakAnimationHandlePointer; class JointState { public: JointState(); + + void setFBXJoint(const FBXJoint& joint); + const FBXJoint& getFBXJoint() const { return *_fbxJoint; } + + void updateWorldTransform(const glm::mat4& baseTransform, const glm::quat& parentRotation); + glm::vec3 _translation; // translation relative to parent glm::quat _rotation; // rotation relative to parent glm::mat4 _transform; // rotation to world frame + translation in model frame glm::quat _combinedRotation; // rotation from joint local to world frame float _animationPriority; // the priority of the animation affecting this joint - void setFBXJoint(const FBXJoint& joint); - const FBXJoint& getFBXJoint() const { return *_fbxJoint; } - private: const FBXJoint* _fbxJoint; // JointState does not own its FBXJoint };