mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 08:13:13 +02:00
Encapsulate AnimPose members for easier optimizations
This commit is contained in:
parent
b56a15b60a
commit
e5e9ab42ea
14 changed files with 179 additions and 149 deletions
|
@ -503,8 +503,8 @@ void AvatarActionHold::lateAvatarUpdate(const AnimPose& prePhysicsRoomPose, cons
|
|||
// then transform it back into world uisng the postAvatarUpdate sensor-to-world matrix.
|
||||
AnimPose newWorldBodyPose = postAvatarUpdateRoomPose * prePhysicsRoomPose.inverse() * worldBodyPose;
|
||||
|
||||
worldTrans.setOrigin(glmToBullet(newWorldBodyPose.trans));
|
||||
worldTrans.setRotation(glmToBullet(newWorldBodyPose.rot));
|
||||
worldTrans.setOrigin(glmToBullet(newWorldBodyPose.trans()));
|
||||
worldTrans.setRotation(glmToBullet(newWorldBodyPose.rot()));
|
||||
rigidBody->setWorldTransform(worldTrans);
|
||||
|
||||
bool positionSuccess;
|
||||
|
|
|
@ -2091,10 +2091,10 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const {
|
|||
|
||||
glm::vec3 rigMiddleEyePos = DEFAULT_RIG_MIDDLE_EYE_POS;
|
||||
if (leftEyeIndex >= 0 && rightEyeIndex >= 0) {
|
||||
rigMiddleEyePos = (_rig->getAbsoluteDefaultPose(leftEyeIndex).trans + _rig->getAbsoluteDefaultPose(rightEyeIndex).trans) / 2.0f;
|
||||
rigMiddleEyePos = (_rig->getAbsoluteDefaultPose(leftEyeIndex).trans() + _rig->getAbsoluteDefaultPose(rightEyeIndex).trans()) / 2.0f;
|
||||
}
|
||||
glm::vec3 rigNeckPos = neckIndex != -1 ? _rig->getAbsoluteDefaultPose(neckIndex).trans : DEFAULT_RIG_NECK_POS;
|
||||
glm::vec3 rigHipsPos = hipsIndex != -1 ? _rig->getAbsoluteDefaultPose(hipsIndex).trans : DEFAULT_RIG_HIPS_POS;
|
||||
glm::vec3 rigNeckPos = neckIndex != -1 ? _rig->getAbsoluteDefaultPose(neckIndex).trans() : DEFAULT_RIG_NECK_POS;
|
||||
glm::vec3 rigHipsPos = hipsIndex != -1 ? _rig->getAbsoluteDefaultPose(hipsIndex).trans() : DEFAULT_RIG_HIPS_POS;
|
||||
|
||||
glm::vec3 localEyes = (rigMiddleEyePos - rigHipsPos);
|
||||
glm::vec3 localNeck = (rigNeckPos - rigHipsPos);
|
||||
|
@ -2274,16 +2274,16 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat
|
|||
|
||||
AnimPose followWorldPose(currentWorldMatrix);
|
||||
if (isActive(Rotation)) {
|
||||
followWorldPose.rot = glmExtractRotation(desiredWorldMatrix);
|
||||
followWorldPose.rot() = glmExtractRotation(desiredWorldMatrix);
|
||||
}
|
||||
if (isActive(Horizontal)) {
|
||||
glm::vec3 desiredTranslation = extractTranslation(desiredWorldMatrix);
|
||||
followWorldPose.trans.x = desiredTranslation.x;
|
||||
followWorldPose.trans.z = desiredTranslation.z;
|
||||
followWorldPose.trans().x = desiredTranslation.x;
|
||||
followWorldPose.trans().z = desiredTranslation.z;
|
||||
}
|
||||
if (isActive(Vertical)) {
|
||||
glm::vec3 desiredTranslation = extractTranslation(desiredWorldMatrix);
|
||||
followWorldPose.trans.y = desiredTranslation.y;
|
||||
followWorldPose.trans().y = desiredTranslation.y;
|
||||
}
|
||||
|
||||
myAvatar.getCharacterController()->setFollowParameters(followWorldPose, getMaxTimeRemaining());
|
||||
|
|
|
@ -143,13 +143,13 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
postRot = animSkeleton.getPostRotationPose(animJoint);
|
||||
} else {
|
||||
// In order to support Blender, which does not have preRotation FBX support, we use the models defaultPose as the reference frame for the animations.
|
||||
preRot = AnimPose(glm::vec3(1.0f), _skeleton->getRelativeBindPose(skeletonJoint).rot, glm::vec3());
|
||||
preRot = AnimPose(glm::vec3(1.0f), _skeleton->getRelativeBindPose(skeletonJoint).rot(), glm::vec3());
|
||||
postRot = AnimPose::identity;
|
||||
}
|
||||
|
||||
// cancel out scale
|
||||
preRot.scale = glm::vec3(1.0f);
|
||||
postRot.scale = glm::vec3(1.0f);
|
||||
preRot.scale() = glm::vec3(1.0f);
|
||||
postRot.scale() = glm::vec3(1.0f);
|
||||
|
||||
AnimPose rot(glm::vec3(1.0f), fbxAnimRot, glm::vec3());
|
||||
|
||||
|
@ -160,10 +160,10 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
float boneLengthScale = 1.0f;
|
||||
const float EPSILON = 0.0001f;
|
||||
if (fabsf(glm::length(fbxZeroTrans)) > EPSILON) {
|
||||
boneLengthScale = glm::length(relDefaultPose.trans) / glm::length(fbxZeroTrans);
|
||||
boneLengthScale = glm::length(relDefaultPose.trans()) / glm::length(fbxZeroTrans);
|
||||
}
|
||||
|
||||
AnimPose trans = AnimPose(glm::vec3(1.0f), glm::quat(), relDefaultPose.trans + boneLengthScale * (fbxAnimTrans - fbxZeroTrans));
|
||||
AnimPose trans = AnimPose(glm::vec3(1.0f), glm::quat(), relDefaultPose.trans() + boneLengthScale * (fbxAnimTrans - fbxZeroTrans));
|
||||
|
||||
_anim[frame][skeletonJoint] = trans * preRot * rot * postRot;
|
||||
}
|
||||
|
|
|
@ -101,8 +101,8 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::
|
|||
target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition));
|
||||
if (target.getType() != IKTarget::Type::Unknown) {
|
||||
AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses);
|
||||
glm::quat rotation = animVars.lookupRigToGeometry(targetVar.rotationVar, defaultPose.rot);
|
||||
glm::vec3 translation = animVars.lookupRigToGeometry(targetVar.positionVar, defaultPose.trans);
|
||||
glm::quat rotation = animVars.lookupRigToGeometry(targetVar.rotationVar, defaultPose.rot());
|
||||
glm::vec3 translation = animVars.lookupRigToGeometry(targetVar.positionVar, defaultPose.trans());
|
||||
if (target.getType() == IKTarget::Type::HipsRelativeRotationAndPosition) {
|
||||
translation += _hipsOffset;
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
|
|||
// harvest accumulated rotations and apply the average
|
||||
for (int i = lowestMovedIndex; i < _maxTargetIndex; ++i) {
|
||||
if (_accumulators[i].size() > 0) {
|
||||
_relativePoses[i].rot = _accumulators[i].getAverage();
|
||||
_relativePoses[i].rot() = _accumulators[i].getAverage();
|
||||
_accumulators[i].clear();
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
|
|||
for (size_t i = 0; i < targets.size(); i++) {
|
||||
if (targets[i].getType() == IKTarget::Type::RotationAndPosition || targets[i].getType() == IKTarget::Type::HmdHead ||
|
||||
targets[i].getType() == IKTarget::Type::HipsRelativeRotationAndPosition) {
|
||||
float error = glm::length(absolutePoses[targets[i].getIndex()].trans - targets[i].getTranslation());
|
||||
float error = glm::length(absolutePoses[targets[i].getIndex()].trans() - targets[i].getTranslation());
|
||||
if (error > maxError) {
|
||||
maxError = error;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
|
|||
const glm::quat& targetRotation = target.getRotation();
|
||||
// compute tip's new parent-relative rotation
|
||||
// Q = Qp * q --> q' = Qp^ * Q
|
||||
glm::quat newRelativeRotation = glm::inverse(absolutePoses[parentIndex].rot) * targetRotation;
|
||||
glm::quat newRelativeRotation = glm::inverse(absolutePoses[parentIndex].rot()) * targetRotation;
|
||||
RotationConstraint* constraint = getConstraint(tipIndex);
|
||||
if (constraint) {
|
||||
constraint->apply(newRelativeRotation);
|
||||
|
@ -206,8 +206,8 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vector<I
|
|||
// feedback to the IK system so that it can adjust the bones up the skeleton
|
||||
// to help this rotation target get met.
|
||||
}
|
||||
_relativePoses[tipIndex].rot = newRelativeRotation;
|
||||
absolutePoses[tipIndex].rot = targetRotation;
|
||||
_relativePoses[tipIndex].rot() = newRelativeRotation;
|
||||
absolutePoses[tipIndex].rot() = targetRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,11 +233,11 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe
|
|||
}
|
||||
|
||||
// cache tip's absolute orientation
|
||||
glm::quat tipOrientation = absolutePoses[tipIndex].rot;
|
||||
glm::quat tipOrientation = absolutePoses[tipIndex].rot();
|
||||
|
||||
// also cache tip's parent's absolute orientation so we can recompute
|
||||
// the tip's parent-relative as we proceed up the chain
|
||||
glm::quat tipParentOrientation = absolutePoses[pivotIndex].rot;
|
||||
glm::quat tipParentOrientation = absolutePoses[pivotIndex].rot();
|
||||
|
||||
if (targetType == IKTarget::Type::HmdHead) {
|
||||
// rotate tip directly to target orientation
|
||||
|
@ -258,12 +258,12 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe
|
|||
}
|
||||
|
||||
// cache tip absolute position
|
||||
glm::vec3 tipPosition = absolutePoses[tipIndex].trans;
|
||||
glm::vec3 tipPosition = absolutePoses[tipIndex].trans();
|
||||
|
||||
// descend toward root, pivoting each joint to get tip closer to target position
|
||||
while (pivotIndex != _hipsIndex && pivotsParentIndex != -1) {
|
||||
// compute the two lines that should be aligned
|
||||
glm::vec3 jointPosition = absolutePoses[pivotIndex].trans;
|
||||
glm::vec3 jointPosition = absolutePoses[pivotIndex].trans();
|
||||
glm::vec3 leverArm = tipPosition - jointPosition;
|
||||
|
||||
glm::quat deltaRotation;
|
||||
|
@ -277,7 +277,7 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe
|
|||
if (constraint && constraint->isLowerSpine()) {
|
||||
// for these types of targets we only allow twist at the lower-spine
|
||||
// (this prevents the hand targets from bending the spine too much and thereby driving the hips too far)
|
||||
glm::vec3 twistAxis = absolutePoses[pivotIndex].trans - absolutePoses[pivotsParentIndex].trans;
|
||||
glm::vec3 twistAxis = absolutePoses[pivotIndex].trans() - absolutePoses[pivotsParentIndex].trans();
|
||||
float twistAxisLength = glm::length(twistAxis);
|
||||
if (twistAxisLength > MIN_AXIS_LENGTH) {
|
||||
// project leverArm and targetLine to the plane
|
||||
|
@ -340,9 +340,9 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe
|
|||
// compute joint's new parent-relative rotation after swing
|
||||
// Q' = dQ * Q and Q = Qp * q --> q' = Qp^ * dQ * Q
|
||||
glm::quat newRot = glm::normalize(glm::inverse(
|
||||
absolutePoses[pivotsParentIndex].rot) *
|
||||
absolutePoses[pivotsParentIndex].rot()) *
|
||||
deltaRotation *
|
||||
absolutePoses[pivotIndex].rot);
|
||||
absolutePoses[pivotIndex].rot());
|
||||
|
||||
// enforce pivot's constraint
|
||||
RotationConstraint* constraint = getConstraint(pivotIndex);
|
||||
|
@ -352,7 +352,7 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe
|
|||
// the constraint will modify the local rotation of the tip so we must
|
||||
// compute the corresponding model-frame deltaRotation
|
||||
// Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^
|
||||
deltaRotation = absolutePoses[pivotsParentIndex].rot * newRot * glm::inverse(absolutePoses[pivotIndex].rot);
|
||||
deltaRotation = absolutePoses[pivotsParentIndex].rot() * newRot * glm::inverse(absolutePoses[pivotIndex].rot());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,15 +405,15 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
const float blend = (1.0f / 60.0f) / (0.25f); // effectively: dt / RELAXATION_TIMESCALE
|
||||
int numJoints = (int)_relativePoses.size();
|
||||
for (int i = 0; i < numJoints; ++i) {
|
||||
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot, underPoses[i].rot));
|
||||
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot(), underPoses[i].rot()));
|
||||
if (_accumulators[i].isDirty()) {
|
||||
// this joint is affected by IK --> blend toward underPose rotation
|
||||
_relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, blend));
|
||||
_relativePoses[i].rot() = glm::normalize(glm::lerp(_relativePoses[i].rot(), dotSign * underPoses[i].rot(), blend));
|
||||
} else {
|
||||
// this joint is NOT affected by IK --> slam to underPose rotation
|
||||
_relativePoses[i].rot = underPoses[i].rot;
|
||||
_relativePoses[i].rot() = underPoses[i].rot();
|
||||
}
|
||||
_relativePoses[i].trans = underPoses[i].trans;
|
||||
_relativePoses[i].trans() = underPoses[i].trans();
|
||||
}
|
||||
|
||||
if (!_relativePoses.empty()) {
|
||||
|
@ -422,7 +422,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
std::map<int, RotationConstraint*>::iterator constraintItr = _constraints.begin();
|
||||
while (constraintItr != _constraints.end()) {
|
||||
int index = constraintItr->first;
|
||||
constraintItr->second->dynamicallyAdjustLimits(_relativePoses[index].rot);
|
||||
constraintItr->second->dynamicallyAdjustLimits(_relativePoses[index].rot());
|
||||
++constraintItr;
|
||||
}
|
||||
}
|
||||
|
@ -442,9 +442,9 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
std::map<int, RotationConstraint*>::iterator constraintItr = _constraints.begin();
|
||||
while (constraintItr != _constraints.end()) {
|
||||
int index = constraintItr->first;
|
||||
glm::quat rotation = _relativePoses[index].rot;
|
||||
glm::quat rotation = _relativePoses[index].rot();
|
||||
constraintItr->second->apply(rotation);
|
||||
_relativePoses[index].rot = rotation;
|
||||
_relativePoses[index].rot() = rotation;
|
||||
++constraintItr;
|
||||
}
|
||||
} else {
|
||||
|
@ -460,16 +460,16 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
float scaleFactor = ((offsetLength - MIN_HIPS_OFFSET_LENGTH) / offsetLength);
|
||||
if (_hipsParentIndex == -1) {
|
||||
// the hips are the root so _hipsOffset is in the correct frame
|
||||
_relativePoses[_hipsIndex].trans = underPoses[_hipsIndex].trans + scaleFactor * _hipsOffset;
|
||||
_relativePoses[_hipsIndex].trans() = underPoses[_hipsIndex].trans() + scaleFactor * _hipsOffset;
|
||||
} else {
|
||||
// the hips are NOT the root so we need to transform _hipsOffset into hips local-frame
|
||||
glm::quat hipsFrameRotation = _relativePoses[_hipsParentIndex].rot;
|
||||
glm::quat hipsFrameRotation = _relativePoses[_hipsParentIndex].rot();
|
||||
int index = _skeleton->getParentIndex(_hipsParentIndex);
|
||||
while (index != -1) {
|
||||
hipsFrameRotation *= _relativePoses[index].rot;
|
||||
hipsFrameRotation *= _relativePoses[index].rot();
|
||||
index = _skeleton->getParentIndex(index);
|
||||
}
|
||||
_relativePoses[_hipsIndex].trans = underPoses[_hipsIndex].trans
|
||||
_relativePoses[_hipsIndex].trans() = underPoses[_hipsIndex].trans()
|
||||
+ glm::inverse(glm::normalize(hipsFrameRotation)) * (scaleFactor * _hipsOffset);
|
||||
}
|
||||
}
|
||||
|
@ -494,20 +494,20 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
|||
if (target.getType() == IKTarget::Type::RotationOnly) {
|
||||
// we want to shift the hips to bring the underPose closer
|
||||
// to where the head happens to be (overpose)
|
||||
glm::vec3 under = _skeleton->getAbsolutePose(_headIndex, underPoses).trans;
|
||||
glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans;
|
||||
glm::vec3 under = _skeleton->getAbsolutePose(_headIndex, underPoses).trans();
|
||||
glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans();
|
||||
const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f;
|
||||
newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (actual - under);
|
||||
} else if (target.getType() == IKTarget::Type::HmdHead) {
|
||||
// we want to shift the hips to bring the head to its designated position
|
||||
glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans;
|
||||
glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans();
|
||||
_hipsOffset += target.getTranslation() - actual;
|
||||
// and ignore all other targets
|
||||
newHipsOffset = _hipsOffset;
|
||||
break;
|
||||
}
|
||||
} else if (target.getType() == IKTarget::Type::RotationAndPosition) {
|
||||
glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans;
|
||||
glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans();
|
||||
glm::vec3 targetPosition = target.getTranslation();
|
||||
newHipsOffset += targetPosition - actualPosition;
|
||||
}
|
||||
|
@ -613,7 +613,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
RotationConstraint* constraint = nullptr;
|
||||
if (0 == baseName.compare("Arm", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
stConstraint->setTwistLimits(-PI / 2.0f, PI / 2.0f);
|
||||
|
||||
/* KEEP THIS CODE for future experimentation
|
||||
|
@ -647,7 +647,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (0 == baseName.compare("UpLeg", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
stConstraint->setTwistLimits(-PI / 4.0f, PI / 4.0f);
|
||||
|
||||
std::vector<glm::vec3> swungDirections;
|
||||
|
@ -670,7 +670,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
swungDirections.push_back(glm::vec3(mirror * cosf(theta), 0.5f, sinf(theta)));
|
||||
|
||||
// rotate directions into joint-frame
|
||||
glm::quat invAbsoluteRotation = glm::inverse(absolutePoses[i].rot);
|
||||
glm::quat invAbsoluteRotation = glm::inverse(absolutePoses[i].rot());
|
||||
int numDirections = (int)swungDirections.size();
|
||||
for (int j = 0; j < numDirections; ++j) {
|
||||
swungDirections[j] = invAbsoluteRotation * swungDirections[j];
|
||||
|
@ -680,7 +680,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (0 == baseName.compare("Hand", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
stConstraint->setTwistLimits(0.0f, 0.0f); // max == min, disables twist limits
|
||||
|
||||
/* KEEP THIS CODE for future experimentation -- twist limits for hands
|
||||
|
@ -723,7 +723,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (baseName.startsWith("Shoulder", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
const float MAX_SHOULDER_TWIST = PI / 20.0f;
|
||||
stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST);
|
||||
|
||||
|
@ -735,7 +735,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (baseName.startsWith("Spine", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
const float MAX_SPINE_TWIST = PI / 12.0f;
|
||||
stConstraint->setTwistLimits(-MAX_SPINE_TWIST, MAX_SPINE_TWIST);
|
||||
|
||||
|
@ -751,7 +751,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (baseName.startsWith("Hips2", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
const float MAX_SPINE_TWIST = PI / 8.0f;
|
||||
stConstraint->setTwistLimits(-MAX_SPINE_TWIST, MAX_SPINE_TWIST);
|
||||
|
||||
|
@ -763,7 +763,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (0 == baseName.compare("Neck", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
const float MAX_NECK_TWIST = PI / 9.0f;
|
||||
stConstraint->setTwistLimits(-MAX_NECK_TWIST, MAX_NECK_TWIST);
|
||||
|
||||
|
@ -775,7 +775,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(stConstraint);
|
||||
} else if (0 == baseName.compare("Head", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
const float MAX_HEAD_TWIST = PI / 9.0f;
|
||||
stConstraint->setTwistLimits(-MAX_HEAD_TWIST, MAX_HEAD_TWIST);
|
||||
|
||||
|
@ -788,7 +788,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
} else if (0 == baseName.compare("ForeArm", Qt::CaseSensitive)) {
|
||||
// The elbow joint rotates about the parent-frame's zAxis (-zAxis) for the Right (Left) arm.
|
||||
ElbowConstraint* eConstraint = new ElbowConstraint();
|
||||
glm::quat referenceRotation = _defaultRelativePoses[i].rot;
|
||||
glm::quat referenceRotation = _defaultRelativePoses[i].rot();
|
||||
eConstraint->setReferenceRotation(referenceRotation);
|
||||
|
||||
// we determine the max/min angles by rotating the swing limit lines from parent- to child-frame
|
||||
|
@ -819,7 +819,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
} else if (0 == baseName.compare("Leg", Qt::CaseSensitive)) {
|
||||
// The knee joint rotates about the parent-frame's -xAxis.
|
||||
ElbowConstraint* eConstraint = new ElbowConstraint();
|
||||
glm::quat referenceRotation = _defaultRelativePoses[i].rot;
|
||||
glm::quat referenceRotation = _defaultRelativePoses[i].rot();
|
||||
eConstraint->setReferenceRotation(referenceRotation);
|
||||
glm::vec3 hingeAxis = -1.0f * Vectors::UNIT_X;
|
||||
|
||||
|
@ -849,7 +849,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
constraint = static_cast<RotationConstraint*>(eConstraint);
|
||||
} else if (0 == baseName.compare("Foot", Qt::CaseSensitive)) {
|
||||
SwingTwistConstraint* stConstraint = new SwingTwistConstraint();
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot);
|
||||
stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());
|
||||
stConstraint->setTwistLimits(-PI / 4.0f, PI / 4.0f);
|
||||
|
||||
// these directions are approximate swing limits in parent-frame
|
||||
|
@ -861,7 +861,7 @@ void AnimInverseKinematics::initConstraints() {
|
|||
swungDirections.push_back(glm::vec3(1.0f, 1.0f, -1.0f));
|
||||
|
||||
// rotate directions into joint-frame
|
||||
glm::quat invRelativeRotation = glm::inverse(_defaultRelativePoses[i].rot);
|
||||
glm::quat invRelativeRotation = glm::inverse(_defaultRelativePoses[i].rot());
|
||||
int numDirections = (int)swungDirections.size();
|
||||
for (int j = 0; j < numDirections; ++j) {
|
||||
swungDirections[j] = invRelativeRotation * swungDirections[j];
|
||||
|
|
|
@ -103,9 +103,9 @@ AnimPose AnimManipulator::computeRelativePoseFromJointVar(const AnimVariantMap&
|
|||
if (jointVar.type == JointVar::Type::AbsoluteRotation || jointVar.type == JointVar::Type::AbsolutePosition) {
|
||||
|
||||
if (jointVar.type == JointVar::Type::AbsoluteRotation) {
|
||||
defaultAbsPose.rot = animVars.lookupRigToGeometry(jointVar.var, defaultAbsPose.rot);
|
||||
defaultAbsPose.rot() = animVars.lookupRigToGeometry(jointVar.var, defaultAbsPose.rot());
|
||||
} else if (jointVar.type == JointVar::Type::AbsolutePosition) {
|
||||
defaultAbsPose.trans = animVars.lookupRigToGeometry(jointVar.var, defaultAbsPose.trans);
|
||||
defaultAbsPose.trans() = animVars.lookupRigToGeometry(jointVar.var, defaultAbsPose.trans());
|
||||
}
|
||||
|
||||
// because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose.
|
||||
|
@ -123,9 +123,9 @@ AnimPose AnimManipulator::computeRelativePoseFromJointVar(const AnimVariantMap&
|
|||
// override the default rel pose
|
||||
AnimPose relPose = defaultRelPose;
|
||||
if (jointVar.type == JointVar::Type::RelativeRotation) {
|
||||
relPose.rot = animVars.lookupRigToGeometry(jointVar.var, defaultRelPose.rot);
|
||||
relPose.rot() = animVars.lookupRigToGeometry(jointVar.var, defaultRelPose.rot());
|
||||
} else if (jointVar.type == JointVar::Type::RelativePosition) {
|
||||
relPose.trans = animVars.lookupRigToGeometry(jointVar.var, defaultRelPose.trans);
|
||||
relPose.trans() = animVars.lookupRigToGeometry(jointVar.var, defaultRelPose.trans());
|
||||
}
|
||||
|
||||
return relPose;
|
||||
|
|
|
@ -17,16 +17,17 @@ const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f),
|
|||
glm::quat(),
|
||||
glm::vec3(0.0f));
|
||||
|
||||
AnimPose::AnimPose(const glm::mat4& mat) {
|
||||
scale = extractScale(mat);
|
||||
AnimPose::AnimPose(const glm::mat4& mat) : _dirty(false) {
|
||||
_mat = mat;
|
||||
_scale = extractScale(mat);
|
||||
// quat_cast doesn't work so well with scaled matrices, so cancel it out.
|
||||
glm::mat4 tmp = glm::scale(mat, 1.0f / scale);
|
||||
rot = glm::normalize(glm::quat_cast(tmp));
|
||||
trans = extractTranslation(mat);
|
||||
glm::mat4 tmp = glm::scale(mat, 1.0f / _scale);
|
||||
_rot = glm::normalize(glm::quat_cast(tmp));
|
||||
_trans = extractTranslation(mat);
|
||||
}
|
||||
|
||||
glm::vec3 AnimPose::operator*(const glm::vec3& rhs) const {
|
||||
return trans + (rot * (scale * rhs));
|
||||
return _trans + (_rot * (_scale * rhs));
|
||||
}
|
||||
|
||||
glm::vec3 AnimPose::xformPoint(const glm::vec3& rhs) const {
|
||||
|
@ -35,16 +36,25 @@ glm::vec3 AnimPose::xformPoint(const glm::vec3& rhs) const {
|
|||
|
||||
// really slow
|
||||
glm::vec3 AnimPose::xformVector(const glm::vec3& rhs) const {
|
||||
glm::vec3 xAxis = rot * glm::vec3(scale.x, 0.0f, 0.0f);
|
||||
glm::vec3 yAxis = rot * glm::vec3(0.0f, scale.y, 0.0f);
|
||||
glm::vec3 zAxis = rot * glm::vec3(0.0f, 0.0f, scale.z);
|
||||
glm::vec3 xAxis = _rot * glm::vec3(_scale.x, 0.0f, 0.0f);
|
||||
glm::vec3 yAxis = _rot * glm::vec3(0.0f, _scale.y, 0.0f);
|
||||
glm::vec3 zAxis = _rot * glm::vec3(0.0f, 0.0f, _scale.z);
|
||||
glm::mat3 mat(xAxis, yAxis, zAxis);
|
||||
glm::mat3 transInvMat = glm::inverse(glm::transpose(mat));
|
||||
return transInvMat * rhs;
|
||||
}
|
||||
|
||||
AnimPose AnimPose::operator*(const AnimPose& rhs) const {
|
||||
#if GLM_ARCH & GLM_ARCH_SSE2
|
||||
glm::mat4 result;
|
||||
glm::mat4 lhsMat = *this;
|
||||
glm::mat4 rhsMat = rhs;
|
||||
glm_mat4_mul((glm_vec4*)&lhsMat, (glm_vec4*)&rhsMat, (glm_vec4*)&result);
|
||||
return AnimPose(result);
|
||||
#else
|
||||
return AnimPose(static_cast<glm::mat4>(*this) * static_cast<glm::mat4>(rhs));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
AnimPose AnimPose::inverse() const {
|
||||
|
@ -53,13 +63,17 @@ AnimPose AnimPose::inverse() const {
|
|||
|
||||
// mirror about x-axis without applying negative scale.
|
||||
AnimPose AnimPose::mirror() const {
|
||||
return AnimPose(scale, glm::quat(rot.w, rot.x, -rot.y, -rot.z), glm::vec3(-trans.x, trans.y, trans.z));
|
||||
return AnimPose(_scale, glm::quat(_rot.w, _rot.x, -_rot.y, -_rot.z), glm::vec3(-_trans.x, _trans.y, _trans.z));
|
||||
}
|
||||
|
||||
AnimPose::operator glm::mat4() const {
|
||||
glm::vec3 xAxis = rot * glm::vec3(scale.x, 0.0f, 0.0f);
|
||||
glm::vec3 yAxis = rot * glm::vec3(0.0f, scale.y, 0.0f);
|
||||
glm::vec3 zAxis = rot * glm::vec3(0.0f, 0.0f, scale.z);
|
||||
return glm::mat4(glm::vec4(xAxis, 0.0f), glm::vec4(yAxis, 0.0f),
|
||||
glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f));
|
||||
AnimPose::operator const glm::mat4&() const {
|
||||
if (_dirty) {
|
||||
glm::vec3 xAxis = _rot * glm::vec3(_scale.x, 0.0f, 0.0f);
|
||||
glm::vec3 yAxis = _rot * glm::vec3(0.0f, _scale.y, 0.0f);
|
||||
glm::vec3 zAxis = _rot * glm::vec3(0.0f, 0.0f, _scale.z);
|
||||
_mat = glm::mat4(glm::vec4(xAxis, 0.0f), glm::vec4(yAxis, 0.0f),
|
||||
glm::vec4(zAxis, 0.0f), glm::vec4(_trans, 1.0f));
|
||||
_dirty = false;
|
||||
}
|
||||
return _mat;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
struct AnimPose {
|
||||
class AnimPose {
|
||||
public:
|
||||
AnimPose() {}
|
||||
explicit AnimPose(const glm::mat4& mat);
|
||||
AnimPose(const glm::vec3& scaleIn, const glm::quat& rotIn, const glm::vec3& transIn) : scale(scaleIn), rot(rotIn), trans(transIn) {}
|
||||
AnimPose(const glm::vec3& scaleIn, const glm::quat& rotIn, const glm::vec3& transIn) : _scale(scaleIn), _rot(rotIn), _trans(transIn) {}
|
||||
static const AnimPose identity;
|
||||
|
||||
glm::vec3 xformPoint(const glm::vec3& rhs) const;
|
||||
|
@ -31,15 +32,29 @@ struct AnimPose {
|
|||
|
||||
AnimPose inverse() const;
|
||||
AnimPose mirror() const;
|
||||
operator glm::mat4() const;
|
||||
operator const glm::mat4&() const;
|
||||
|
||||
glm::vec3 scale;
|
||||
glm::quat rot;
|
||||
glm::vec3 trans;
|
||||
const glm::vec3& scale() const { return _scale; }
|
||||
glm::vec3& scale() { _dirty = true; return _scale; }
|
||||
|
||||
const glm::quat& rot() const { return _rot; }
|
||||
glm::quat& rot() { _dirty = true; return _rot; }
|
||||
|
||||
const glm::vec3& trans() const { return _trans; }
|
||||
glm::vec3& trans() { _dirty = true; return _trans; }
|
||||
|
||||
private:
|
||||
friend QDebug operator<<(QDebug debug, const AnimPose& pose);
|
||||
|
||||
mutable bool _dirty { true };
|
||||
mutable glm::mat4 _mat;
|
||||
glm::vec3 _scale { 1.0f };
|
||||
glm::quat _rot;
|
||||
glm::vec3 _trans;
|
||||
};
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const AnimPose& pose) {
|
||||
debug << "AnimPose, trans = (" << pose.trans.x << pose.trans.y << pose.trans.z << "), rot = (" << pose.rot.x << pose.rot.y << pose.rot.z << pose.rot.w << "), scale = (" << pose.scale.x << pose.scale.y << pose.scale.z << ")";
|
||||
debug << "AnimPose, trans = (" << pose.trans().x << pose.trans().y << pose.trans().z << "), rot = (" << pose.rot().x << pose.rot().y << pose.rot().z << pose.rot().w << "), scale = (" << pose.scale().x << pose.scale().y << pose.scale().z << ")";
|
||||
return debug;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,16 +20,16 @@ void blend(size_t numPoses, const AnimPose* a, const AnimPose* b, float alpha, A
|
|||
const AnimPose& bPose = b[i];
|
||||
|
||||
// adjust signs if necessary
|
||||
const glm::quat& q1 = aPose.rot;
|
||||
glm::quat q2 = bPose.rot;
|
||||
const glm::quat& q1 = aPose.rot();
|
||||
glm::quat q2 = bPose.rot();
|
||||
float dot = glm::dot(q1, q2);
|
||||
if (dot < 0.0f) {
|
||||
q2 = -q2;
|
||||
}
|
||||
|
||||
result[i].scale = lerp(aPose.scale, bPose.scale, alpha);
|
||||
result[i].rot = glm::normalize(glm::lerp(aPose.rot, q2, alpha));
|
||||
result[i].trans = lerp(aPose.trans, bPose.trans, alpha);
|
||||
result[i].scale() = lerp(aPose.scale(), bPose.scale(), alpha);
|
||||
result[i].rot() = glm::normalize(glm::lerp(aPose.rot(), q2, alpha));
|
||||
result[i].trans() = lerp(aPose.trans(), bPose.trans(), alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#include "IKTarget.h"
|
||||
|
||||
void IKTarget::setPose(const glm::quat& rotation, const glm::vec3& translation) {
|
||||
_pose.rot = rotation;
|
||||
_pose.trans = translation;
|
||||
_pose.rot() = rotation;
|
||||
_pose.trans() = translation;
|
||||
}
|
||||
|
||||
void IKTarget::setType(int type) {
|
||||
|
|
|
@ -26,8 +26,8 @@ public:
|
|||
|
||||
IKTarget() {}
|
||||
|
||||
const glm::vec3& getTranslation() const { return _pose.trans; }
|
||||
const glm::quat& getRotation() const { return _pose.rot; }
|
||||
const glm::vec3& getTranslation() const { return _pose.trans(); }
|
||||
const glm::quat& getRotation() const { return _pose.rot(); }
|
||||
int getIndex() const { return _index; }
|
||||
Type getType() const { return _type; }
|
||||
|
||||
|
|
|
@ -262,9 +262,9 @@ QString Rig::nameOfJoint(int jointIndex) const {
|
|||
|
||||
void Rig::setModelOffset(const glm::mat4& modelOffsetMat) {
|
||||
AnimPose newModelOffset = AnimPose(modelOffsetMat);
|
||||
if (!isEqual(_modelOffset.trans, newModelOffset.trans) ||
|
||||
!isEqual(_modelOffset.rot, newModelOffset.rot) ||
|
||||
!isEqual(_modelOffset.scale, newModelOffset.scale)) {
|
||||
if (!isEqual(_modelOffset.trans(), newModelOffset.trans()) ||
|
||||
!isEqual(_modelOffset.rot(), newModelOffset.rot()) ||
|
||||
!isEqual(_modelOffset.scale(), newModelOffset.scale())) {
|
||||
|
||||
_modelOffset = newModelOffset;
|
||||
|
||||
|
@ -334,7 +334,7 @@ void Rig::setJointTranslation(int index, bool valid, const glm::vec3& translatio
|
|||
_internalPoseSet._overrideFlags[index] = true;
|
||||
++_numOverrides;
|
||||
}
|
||||
_internalPoseSet._overridePoses[index].trans = translation;
|
||||
_internalPoseSet._overridePoses[index].trans() = translation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,8 +346,8 @@ void Rig::setJointState(int index, bool valid, const glm::quat& rotation, const
|
|||
_internalPoseSet._overrideFlags[index] = true;
|
||||
++_numOverrides;
|
||||
}
|
||||
_internalPoseSet._overridePoses[index].rot = rotation;
|
||||
_internalPoseSet._overridePoses[index].trans = translation;
|
||||
_internalPoseSet._overridePoses[index].rot() = rotation;
|
||||
_internalPoseSet._overridePoses[index].trans() = translation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,7 @@ void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, flo
|
|||
_internalPoseSet._overrideFlags[index] = true;
|
||||
++_numOverrides;
|
||||
}
|
||||
_internalPoseSet._overridePoses[index].rot = rotation;
|
||||
_internalPoseSet._overridePoses[index].rot() = rotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ void Rig::restoreJointTranslation(int index, float fraction, float priority) {
|
|||
|
||||
bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const {
|
||||
if (isIndexValid(jointIndex)) {
|
||||
position = (rotation * _internalPoseSet._absolutePoses[jointIndex].trans) + translation;
|
||||
position = (rotation * _internalPoseSet._absolutePoses[jointIndex].trans()) + translation;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -385,7 +385,7 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm:
|
|||
|
||||
bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const {
|
||||
if (isIndexValid(jointIndex)) {
|
||||
position = _internalPoseSet._absolutePoses[jointIndex].trans;
|
||||
position = _internalPoseSet._absolutePoses[jointIndex].trans();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -394,7 +394,7 @@ bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const {
|
|||
|
||||
bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const glm::quat& rotation) const {
|
||||
if (isIndexValid(jointIndex)) {
|
||||
result = rotation * _internalPoseSet._absolutePoses[jointIndex].rot;
|
||||
result = rotation * _internalPoseSet._absolutePoses[jointIndex].rot();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -404,7 +404,7 @@ bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const
|
|||
bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const {
|
||||
QReadLocker readLock(&_externalPoseSetLock);
|
||||
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._relativePoses.size()) {
|
||||
rotation = _externalPoseSet._relativePoses[jointIndex].rot;
|
||||
rotation = _externalPoseSet._relativePoses[jointIndex].rot();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -414,7 +414,7 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const {
|
|||
bool Rig::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const {
|
||||
QReadLocker readLock(&_externalPoseSetLock);
|
||||
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) {
|
||||
rotation = _externalPoseSet._absolutePoses[jointIndex].rot;
|
||||
rotation = _externalPoseSet._absolutePoses[jointIndex].rot();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -424,7 +424,7 @@ bool Rig::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation
|
|||
bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const {
|
||||
QReadLocker readLock(&_externalPoseSetLock);
|
||||
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._relativePoses.size()) {
|
||||
translation = _externalPoseSet._relativePoses[jointIndex].trans;
|
||||
translation = _externalPoseSet._relativePoses[jointIndex].trans();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -434,7 +434,7 @@ bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const {
|
|||
bool Rig::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const {
|
||||
QReadLocker readLock(&_externalPoseSetLock);
|
||||
if (jointIndex >= 0 && jointIndex < (int)_externalPoseSet._absolutePoses.size()) {
|
||||
translation = _externalPoseSet._absolutePoses[jointIndex].trans;
|
||||
translation = _externalPoseSet._absolutePoses[jointIndex].trans();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -498,7 +498,7 @@ const AnimPoseVec& Rig::getAbsoluteDefaultPoses() const {
|
|||
|
||||
bool Rig::getRelativeDefaultJointRotation(int index, glm::quat& rotationOut) const {
|
||||
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
|
||||
rotationOut = _animSkeleton->getRelativeDefaultPose(index).rot;
|
||||
rotationOut = _animSkeleton->getRelativeDefaultPose(index).rot();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -507,7 +507,7 @@ bool Rig::getRelativeDefaultJointRotation(int index, glm::quat& rotationOut) con
|
|||
|
||||
bool Rig::getRelativeDefaultJointTranslation(int index, glm::vec3& translationOut) const {
|
||||
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
|
||||
translationOut = _animSkeleton->getRelativeDefaultPose(index).trans;
|
||||
translationOut = _animSkeleton->getRelativeDefaultPose(index).trans();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -998,8 +998,8 @@ void Rig::computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositi
|
|||
glm::vec3& neckPositionOut, glm::quat& neckOrientationOut) const {
|
||||
|
||||
// the input hmd values are in avatar/rig space
|
||||
const glm::vec3 hmdPosition = hmdPose.trans;
|
||||
const glm::quat hmdOrientation = hmdPose.rot;
|
||||
const glm::vec3& hmdPosition = hmdPose.trans();
|
||||
const glm::quat& hmdOrientation = hmdPose.rot();
|
||||
|
||||
// TODO: cache jointIndices
|
||||
int rightEyeIndex = indexOfJoint("RightEye");
|
||||
|
@ -1007,10 +1007,10 @@ void Rig::computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositi
|
|||
int headIndex = indexOfJoint("Head");
|
||||
int neckIndex = indexOfJoint("Neck");
|
||||
|
||||
glm::vec3 absRightEyePos = rightEyeIndex != -1 ? getAbsoluteDefaultPose(rightEyeIndex).trans : DEFAULT_RIGHT_EYE_POS;
|
||||
glm::vec3 absLeftEyePos = leftEyeIndex != -1 ? getAbsoluteDefaultPose(leftEyeIndex).trans : DEFAULT_LEFT_EYE_POS;
|
||||
glm::vec3 absHeadPos = headIndex != -1 ? getAbsoluteDefaultPose(headIndex).trans : DEFAULT_HEAD_POS;
|
||||
glm::vec3 absNeckPos = neckIndex != -1 ? getAbsoluteDefaultPose(neckIndex).trans : DEFAULT_NECK_POS;
|
||||
glm::vec3 absRightEyePos = rightEyeIndex != -1 ? getAbsoluteDefaultPose(rightEyeIndex).trans() : DEFAULT_RIGHT_EYE_POS;
|
||||
glm::vec3 absLeftEyePos = leftEyeIndex != -1 ? getAbsoluteDefaultPose(leftEyeIndex).trans() : DEFAULT_LEFT_EYE_POS;
|
||||
glm::vec3 absHeadPos = headIndex != -1 ? getAbsoluteDefaultPose(headIndex).trans() : DEFAULT_HEAD_POS;
|
||||
glm::vec3 absNeckPos = neckIndex != -1 ? getAbsoluteDefaultPose(neckIndex).trans() : DEFAULT_NECK_POS;
|
||||
|
||||
glm::vec3 absCenterEyePos = (absRightEyePos + absLeftEyePos) / 2.0f;
|
||||
glm::vec3 eyeOffset = absCenterEyePos - absHeadPos;
|
||||
|
@ -1026,7 +1026,7 @@ void Rig::computeHeadNeckAnimVars(const AnimPose& hmdPose, glm::vec3& headPositi
|
|||
neckPositionOut = hmdPosition - hmdOrientation * (headOffset + eyeOffset);
|
||||
|
||||
// slerp between default orientation and hmdOrientation
|
||||
neckOrientationOut = safeMix(hmdOrientation, _animSkeleton->getRelativeDefaultPose(neckIndex).rot, 0.5f);
|
||||
neckOrientationOut = safeMix(hmdOrientation, _animSkeleton->getRelativeDefaultPose(neckIndex).rot(), 0.5f);
|
||||
}
|
||||
|
||||
void Rig::updateNeckJoint(int index, const HeadParameters& params) {
|
||||
|
@ -1077,14 +1077,14 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm
|
|||
// TODO: does not properly handle avatar scale.
|
||||
|
||||
if (isIndexValid(index)) {
|
||||
glm::mat4 rigToWorld = createMatFromQuatAndPos(modelRotation, modelTranslation);
|
||||
glm::mat4 worldToRig = glm::inverse(rigToWorld);
|
||||
glm::vec3 lookAtVector = glm::normalize(transformPoint(worldToRig, lookAtSpot) - _internalPoseSet._absolutePoses[index].trans);
|
||||
const glm::mat4 rigToWorld = createMatFromQuatAndPos(modelRotation, modelTranslation);
|
||||
const glm::mat4 worldToRig = glm::inverse(rigToWorld);
|
||||
const glm::vec3 lookAtVector = glm::normalize(transformPoint(worldToRig, lookAtSpot) - _internalPoseSet._absolutePoses[index].trans());
|
||||
|
||||
int headIndex = indexOfJoint("Head");
|
||||
glm::quat headQuat;
|
||||
if (headIndex >= 0) {
|
||||
headQuat = _internalPoseSet._absolutePoses[headIndex].rot;
|
||||
headQuat = _internalPoseSet._absolutePoses[headIndex].rot();
|
||||
}
|
||||
|
||||
glm::vec3 headUp = headQuat * Vectors::UNIT_Y;
|
||||
|
@ -1103,7 +1103,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm
|
|||
}
|
||||
|
||||
// directly set absolutePose rotation
|
||||
_internalPoseSet._absolutePoses[index].rot = deltaQuat * headQuat;
|
||||
_internalPoseSet._absolutePoses[index].rot() = deltaQuat * headQuat;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1114,7 +1114,7 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) {
|
|||
int hipsIndex = indexOfJoint("Hips");
|
||||
glm::vec3 hipsTrans;
|
||||
if (hipsIndex >= 0) {
|
||||
hipsTrans = _internalPoseSet._absolutePoses[hipsIndex].trans;
|
||||
hipsTrans = _internalPoseSet._absolutePoses[hipsIndex].trans();
|
||||
}
|
||||
|
||||
// Use this capsule to represent the avatar body.
|
||||
|
@ -1188,7 +1188,7 @@ void Rig::initAnimGraph(const QUrl& url) {
|
|||
|
||||
bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const {
|
||||
if (_animSkeleton && _rootJointIndex >= 0) {
|
||||
modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans;
|
||||
modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -1233,11 +1233,12 @@ void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& a
|
|||
}
|
||||
}
|
||||
|
||||
glm::mat4 Rig::getJointTransform(int jointIndex) const {
|
||||
const glm::mat4& Rig::getJointTransform(int jointIndex) const {
|
||||
static const glm::mat4 IDENTITY;
|
||||
if (isIndexValid(jointIndex)) {
|
||||
return _internalPoseSet._absolutePoses[jointIndex];
|
||||
} else {
|
||||
return glm::mat4();
|
||||
return IDENTITY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1250,14 +1251,14 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
|
|||
JointData& data = jointDataVec[i];
|
||||
if (isIndexValid(i)) {
|
||||
// rotations are in absolute rig frame.
|
||||
glm::quat defaultAbsRot = geometryToRigPose.rot * _animSkeleton->getAbsoluteDefaultPose(i).rot;
|
||||
data.rotation = _internalPoseSet._absolutePoses[i].rot;
|
||||
glm::quat defaultAbsRot = geometryToRigPose.rot() * _animSkeleton->getAbsoluteDefaultPose(i).rot();
|
||||
data.rotation = _internalPoseSet._absolutePoses[i].rot();
|
||||
data.rotationSet = !isEqual(data.rotation, defaultAbsRot);
|
||||
|
||||
// translations are in relative frame but scaled so that they are in meters,
|
||||
// instead of geometry units.
|
||||
glm::vec3 defaultRelTrans = _geometryOffset.scale * _animSkeleton->getRelativeDefaultPose(i).trans;
|
||||
data.translation = _geometryOffset.scale * _internalPoseSet._relativePoses[i].trans;
|
||||
glm::vec3 defaultRelTrans = _geometryOffset.scale() * _animSkeleton->getRelativeDefaultPose(i).trans();
|
||||
data.translation = _geometryOffset.scale() * _internalPoseSet._relativePoses[i].trans();
|
||||
data.translationSet = !isEqual(data.translation, defaultRelTrans);
|
||||
} else {
|
||||
data.translationSet = false;
|
||||
|
@ -1272,7 +1273,7 @@ void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
|||
// make a vector of rotations in absolute-geometry-frame
|
||||
const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses();
|
||||
std::vector<glm::quat> rotations;
|
||||
rotations.reserve(_animSkeleton->getAbsoluteDefaultPoses().size());
|
||||
rotations.reserve(absoluteDefaultPoses.size());
|
||||
const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform));
|
||||
for (int i = 0; i < jointDataVec.size(); i++) {
|
||||
const JointData& data = jointDataVec.at(i);
|
||||
|
@ -1280,7 +1281,7 @@ void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
|||
// JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame
|
||||
rotations.push_back(rigToGeometryRot * data.rotation);
|
||||
} else {
|
||||
rotations.push_back(absoluteDefaultPoses[i].rot);
|
||||
rotations.push_back(absoluteDefaultPoses[i].rot());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1291,13 +1292,13 @@ void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
|||
const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses();
|
||||
for (int i = 0; i < jointDataVec.size(); i++) {
|
||||
const JointData& data = jointDataVec.at(i);
|
||||
_internalPoseSet._relativePoses[i].scale = Vectors::ONE;
|
||||
_internalPoseSet._relativePoses[i].rot = rotations[i];
|
||||
_internalPoseSet._relativePoses[i].scale() = Vectors::ONE;
|
||||
_internalPoseSet._relativePoses[i].rot() = rotations[i];
|
||||
if (data.translationSet) {
|
||||
// JointData translations are in scaled relative-frame so we scale back to regular relative-frame
|
||||
_internalPoseSet._relativePoses[i].trans = _invGeometryOffset.scale * data.translation;
|
||||
_internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation;
|
||||
} else {
|
||||
_internalPoseSet._relativePoses[i].trans = relativeDefaultPoses[i].trans;
|
||||
_internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1346,10 +1347,10 @@ void Rig::computeAvatarBoundingCapsule(
|
|||
}
|
||||
AnimVariantMap animVars;
|
||||
glm::quat handRotation = glm::angleAxis(PI, Vectors::UNIT_X);
|
||||
animVars.set("leftHandPosition", hips.trans);
|
||||
animVars.set("leftHandPosition", hips.trans());
|
||||
animVars.set("leftHandRotation", handRotation);
|
||||
animVars.set("leftHandType", (int)IKTarget::Type::RotationAndPosition);
|
||||
animVars.set("rightHandPosition", hips.trans);
|
||||
animVars.set("rightHandPosition", hips.trans());
|
||||
animVars.set("rightHandRotation", handRotation);
|
||||
animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition);
|
||||
|
||||
|
@ -1405,7 +1406,7 @@ void Rig::computeAvatarBoundingCapsule(
|
|||
radiusOut = 0.5f * sqrtf(0.5f * (diagonal.x * diagonal.x + diagonal.z * diagonal.z));
|
||||
heightOut = diagonal.y - 2.0f * radiusOut;
|
||||
|
||||
glm::vec3 rootPosition = finalPoses[geometry.rootJointIndex].trans;
|
||||
glm::vec3 rootPosition = finalPoses[geometry.rootJointIndex].trans();
|
||||
glm::vec3 rigCenter = (geometryToRig * (0.5f * (totalExtents.maximum + totalExtents.minimum)));
|
||||
localOffsetOut = rigCenter - (geometryToRig * rootPosition);
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ public:
|
|||
bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const;
|
||||
|
||||
// rig space
|
||||
glm::mat4 getJointTransform(int jointIndex) const;
|
||||
const glm::mat4& getJointTransform(int jointIndex) const;
|
||||
|
||||
// Start or stop animations as needed.
|
||||
void computeMotionAnimationState(float deltaTime, const glm::vec3& worldPosition, const glm::vec3& worldVelocity, const glm::quat& worldRotation, CharacterControllerState ccState);
|
||||
|
|
|
@ -1055,10 +1055,10 @@ bool RenderableModelEntityItem::setAbsoluteJointRotationInObjectFrame(int index,
|
|||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
jointAbsolutePose.rot = rotation;
|
||||
jointAbsolutePose.rot() = rotation;
|
||||
|
||||
AnimPose jointRelativePose = jointParentInversePose * jointAbsolutePose;
|
||||
return setLocalJointRotation(index, jointRelativePose.rot);
|
||||
return setLocalJointRotation(index, jointRelativePose.rot());
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {
|
||||
|
@ -1088,10 +1088,10 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind
|
|||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
jointAbsolutePose.trans = translation;
|
||||
jointAbsolutePose.trans() = translation;
|
||||
|
||||
AnimPose jointRelativePose = jointParentInversePose * jointAbsolutePose;
|
||||
return setLocalJointTranslation(index, jointRelativePose.trans);
|
||||
return setLocalJointTranslation(index, jointRelativePose.trans());
|
||||
}
|
||||
|
||||
glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const {
|
||||
|
|
|
@ -168,7 +168,7 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius
|
|||
const uint32_t color = toRGBA(vecColor);
|
||||
|
||||
AnimPose finalPose = rootPose * pose;
|
||||
glm::vec3 base = rootPose * pose.trans;
|
||||
glm::vec3 base = rootPose * pose.trans();
|
||||
|
||||
glm::vec3 xRing[NUM_CIRCLE_SLICES + 1]; // one extra for last index.
|
||||
glm::vec3 yRing[NUM_CIRCLE_SLICES + 1];
|
||||
|
@ -245,7 +245,7 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPo
|
|||
AnimPose pose0 = rootPose * parentPose;
|
||||
AnimPose pose1 = rootPose * pose;
|
||||
|
||||
glm::vec3 boneAxisWorld = glm::normalize(pose1.trans - pose0.trans);
|
||||
glm::vec3 boneAxisWorld = glm::normalize(pose1.trans() - pose0.trans());
|
||||
glm::vec3 boneAxis0 = glm::normalize(pose0.inverse().xformVector(boneAxisWorld));
|
||||
glm::vec3 boneAxis1 = glm::normalize(pose1.inverse().xformVector(boneAxisWorld));
|
||||
|
||||
|
@ -255,7 +255,7 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPo
|
|||
const int NUM_BASE_CORNERS = 4;
|
||||
|
||||
// make sure there's room between the two bones to draw a nice bone link.
|
||||
if (glm::dot(boneTip - pose0.trans, boneAxisWorld) > glm::dot(boneBase - pose0.trans, boneAxisWorld)) {
|
||||
if (glm::dot(boneTip - pose0.trans(), boneAxisWorld) > glm::dot(boneBase - pose0.trans(), boneAxisWorld)) {
|
||||
|
||||
// there is room, so lets draw a nice bone
|
||||
|
||||
|
@ -290,10 +290,10 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPo
|
|||
// just draw a line between the two bone centers.
|
||||
// We add the same line multiple times, so the vertex count is correct.
|
||||
for (int i = 0; i < NUM_BASE_CORNERS * 2; i++) {
|
||||
v->pos = pose0.trans;
|
||||
v->pos = pose0.trans();
|
||||
v->rgba = color;
|
||||
v++;
|
||||
v->pos = pose1.trans;
|
||||
v->pos = pose1.trans();
|
||||
v->rgba = color;
|
||||
v++;
|
||||
}
|
||||
|
@ -365,7 +365,7 @@ void AnimDebugDraw::update() {
|
|||
glm::vec4 color = std::get<3>(iter.second);
|
||||
|
||||
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
||||
const float radius = BONE_RADIUS / (absPoses[i].scale.x * rootPose.scale.x);
|
||||
const float radius = BONE_RADIUS / (absPoses[i].scale().x * rootPose.scale().x);
|
||||
|
||||
// draw bone
|
||||
addBone(rootPose, absPoses[i], radius, color, v);
|
||||
|
|
Loading…
Reference in a new issue