Merge pull request #6205 from hyperlogic/tony/eye-lookat-fix

Fixes locally rendered eye gaze
This commit is contained in:
Howard Stearns 2015-10-28 21:39:54 -07:00
commit 697b9fb60b
3 changed files with 47 additions and 57 deletions

View file

@ -114,15 +114,12 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
if (_owningAvatar->isMyAvatar()) { if (_owningAvatar->isMyAvatar()) {
_rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation()); _rig->computeMotionAnimationState(deltaTime, _owningAvatar->getPosition(), _owningAvatar->getVelocity(), _owningAvatar->getOrientation());
} }
Model::updateRig(deltaTime, parentTransform);
Head* head = _owningAvatar->getHead(); Head* head = _owningAvatar->getHead();
if (_owningAvatar->isMyAvatar()) { if (_owningAvatar->isMyAvatar()) {
MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar); MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
const FBXGeometry& geometry = _geometry->getFBXGeometry(); const FBXGeometry& geometry = _geometry->getFBXGeometry();
Rig::HeadParameters headParams; Rig::HeadParameters headParams;
headParams.modelRotation = getRotation();
headParams.modelTranslation = getTranslation();
headParams.enableLean = qApp->getAvatarUpdater()->isHMDMode(); headParams.enableLean = qApp->getAvatarUpdater()->isHMDMode();
headParams.leanSideways = head->getFinalLeanSideways(); headParams.leanSideways = head->getFinalLeanSideways();
headParams.leanForward = head->getFinalLeanForward(); headParams.leanForward = head->getFinalLeanForward();
@ -156,19 +153,13 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame(); headParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame();
} }
headParams.eyeLookAt = head->getLookAtPosition();
headParams.eyeSaccade = head->getSaccade();
headParams.leanJointIndex = geometry.leanJointIndex; headParams.leanJointIndex = geometry.leanJointIndex;
headParams.neckJointIndex = geometry.neckJointIndex; headParams.neckJointIndex = geometry.neckJointIndex;
headParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
headParams.rightEyeJointIndex = geometry.rightEyeJointIndex;
headParams.isTalking = head->getTimeWithoutTalking() <= 1.5f; headParams.isTalking = head->getTimeWithoutTalking() <= 1.5f;
_rig->updateFromHeadParameters(headParams, deltaTime); _rig->updateFromHeadParameters(headParams, deltaTime);
Rig::HandParameters handParams; Rig::HandParameters handParams;
const PalmData* leftPalm = getPalmWithIndex(myAvatar->getHand(), LEFT_HAND_INDEX); const PalmData* leftPalm = getPalmWithIndex(myAvatar->getHand(), LEFT_HAND_INDEX);
if (leftPalm && leftPalm->isActive()) { if (leftPalm && leftPalm->isActive()) {
handParams.isLeftEnabled = true; handParams.isLeftEnabled = true;
@ -191,7 +182,28 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
_rig->updateFromHandParameters(handParams, deltaTime); _rig->updateFromHandParameters(handParams, deltaTime);
// evaluate AnimGraph animation and update jointStates.
Model::updateRig(deltaTime, parentTransform);
Rig::EyeParameters eyeParams;
eyeParams.worldHeadOrientation = headParams.worldHeadOrientation;
eyeParams.eyeLookAt = head->getLookAtPosition();
eyeParams.eyeSaccade = head->getSaccade();
eyeParams.modelRotation = getRotation();
eyeParams.modelTranslation = getTranslation();
eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex;
_rig->updateFromEyeParameters(eyeParams);
// rebuild the jointState transform for the eyes only
_rig->updateJointState(eyeParams.leftEyeJointIndex, parentTransform);
_rig->updateJointState(eyeParams.rightEyeJointIndex, parentTransform);
} else { } else {
Model::updateRig(deltaTime, parentTransform);
// This is a little more work than we really want. // This is a little more work than we really want.
// //
// Other avatars joint, including their eyes, should already be set just like any other joints // Other avatars joint, including their eyes, should already be set just like any other joints
@ -208,9 +220,16 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
head->setBasePitch(glm::degrees(-eulers.x)); head->setBasePitch(glm::degrees(-eulers.x));
head->setBaseYaw(glm::degrees(eulers.y)); head->setBaseYaw(glm::degrees(eulers.y));
head->setBaseRoll(glm::degrees(-eulers.z)); head->setBaseRoll(glm::degrees(-eulers.z));
_rig->updateEyeJoints(geometry.leftEyeJointIndex, geometry.rightEyeJointIndex,
getTranslation(), getRotation(), Rig::EyeParameters eyeParams;
head->getFinalOrientationInWorldFrame(), head->getCorrectedLookAtPosition()); eyeParams.worldHeadOrientation = head->getFinalOrientationInWorldFrame();
eyeParams.eyeLookAt = head->getCorrectedLookAtPosition();
eyeParams.eyeSaccade = glm::vec3();
eyeParams.modelRotation = getRotation();
eyeParams.modelTranslation = getTranslation();
eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex;
_rig->updateFromEyeParameters(eyeParams);
} }
} }

View file

@ -22,34 +22,6 @@
#include "AnimSkeleton.h" #include "AnimSkeleton.h"
#include "IKTarget.h" #include "IKTarget.h"
void Rig::HeadParameters::dump() const {
qCDebug(animation, "HeadParameters =");
qCDebug(animation, " leanSideways = %0.5f", (double)leanSideways);
qCDebug(animation, " leanForward = %0.5f", (double)leanForward);
qCDebug(animation, " torsoTwist = %0.5f", (double)torsoTwist);
glm::vec3 axis = glm::axis(localHeadOrientation);
float theta = glm::angle(localHeadOrientation);
qCDebug(animation, " localHeadOrientation axis = (%.5f, %.5f, %.5f), theta = %0.5f", (double)axis.x, (double)axis.y, (double)axis.z, (double)theta);
axis = glm::axis(worldHeadOrientation);
theta = glm::angle(worldHeadOrientation);
qCDebug(animation, " localHead pitch = %.5f, yaw = %.5f, roll = %.5f", (double)localHeadPitch, (double)localHeadYaw, (double)localHeadRoll);
qCDebug(animation, " localHeadPosition = (%.5f, %.5f, %.5f)", (double)localHeadPosition.x, (double)localHeadPosition.y, (double)localHeadPosition.z);
qCDebug(animation, " isInHMD = %s", isInHMD ? "true" : "false");
qCDebug(animation, " worldHeadOrientation axis = (%.5f, %.5f, %.5f), theta = %0.5f", (double)axis.x, (double)axis.y, (double)axis.z, (double)theta);
axis = glm::axis(modelRotation);
theta = glm::angle(modelRotation);
qCDebug(animation, " modelRotation axis = (%.5f, %.5f, %.5f), theta = %0.5f", (double)axis.x, (double)axis.y, (double)axis.z, (double)theta);
qCDebug(animation, " modelTranslation = (%.5f, %.5f, %.5f)", (double)modelTranslation.x, (double)modelTranslation.y, (double)modelTranslation.z);
qCDebug(animation, " eyeLookAt = (%.5f, %.5f, %.5f)", (double)eyeLookAt.x, (double)eyeLookAt.y, (double)eyeLookAt.z);
qCDebug(animation, " eyeSaccade = (%.5f, %.5f, %.5f)", (double)eyeSaccade.x, (double)eyeSaccade.y, (double)eyeSaccade.z);
qCDebug(animation, " leanJointIndex = %.d", leanJointIndex);
qCDebug(animation, " neckJointIndex = %.d", neckJointIndex);
qCDebug(animation, " leftEyeJointIndex = %.d", leftEyeJointIndex);
qCDebug(animation, " rightEyeJointIndex = %.d", rightEyeJointIndex);
qCDebug(animation, " isTalking = %s", isTalking ? "true" : "false");
}
void insertSorted(QList<AnimationHandlePointer>& handles, const AnimationHandlePointer& handle) { void insertSorted(QList<AnimationHandlePointer>& handles, const AnimationHandlePointer& handle) {
for (QList<AnimationHandlePointer>::iterator it = handles.begin(); it != handles.end(); it++) { for (QList<AnimationHandlePointer>::iterator it = handles.begin(); it != handles.end(); it++) {
if (handle->getPriority() > (*it)->getPriority()) { if (handle->getPriority() > (*it)->getPriority()) {
@ -981,8 +953,6 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) {
_animVars.unset("lean"); _animVars.unset("lean");
} }
updateNeckJoint(params.neckJointIndex, params); updateNeckJoint(params.neckJointIndex, params);
updateEyeJoints(params.leftEyeJointIndex, params.rightEyeJointIndex, params.modelTranslation, params.modelRotation,
params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
if (_enableAnimGraph) { if (_enableAnimGraph) {
_animVars.set("isTalking", params.isTalking); _animVars.set("isTalking", params.isTalking);
@ -990,6 +960,13 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) {
} }
} }
void Rig::updateFromEyeParameters(const EyeParameters& params) {
updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation,
params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation,
params.worldHeadOrientation, params.eyeLookAt, params.eyeSaccade);
}
static const glm::vec3 X_AXIS(1.0f, 0.0f, 0.0f); static const glm::vec3 X_AXIS(1.0f, 0.0f, 0.0f);
static const glm::vec3 Y_AXIS(0.0f, 1.0f, 0.0f); static const glm::vec3 Y_AXIS(0.0f, 1.0f, 0.0f);
static const glm::vec3 Z_AXIS(0.0f, 0.0f, 1.0f); static const glm::vec3 Z_AXIS(0.0f, 0.0f, 1.0f);
@ -1145,12 +1122,6 @@ void Rig::updateNeckJoint(int index, const HeadParameters& params) {
} }
} }
void Rig::updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation,
const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) {
updateEyeJoint(leftEyeIndex, modelTranslation, modelRotation, worldHeadOrientation, lookAtSpot, saccade);
updateEyeJoint(rightEyeIndex, modelTranslation, modelRotation, worldHeadOrientation, lookAtSpot, saccade);
}
void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) { void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade) {
if (index >= 0 && _jointStates[index].getParentIndex() >= 0) { if (index >= 0 && _jointStates[index].getParentIndex() >= 0) {
auto& state = _jointStates[index]; auto& state = _jointStates[index];

View file

@ -57,24 +57,26 @@ public:
float leanForward = 0.0f; // degrees float leanForward = 0.0f; // degrees
float torsoTwist = 0.0f; // degrees float torsoTwist = 0.0f; // degrees
bool enableLean = false; bool enableLean = false;
glm::quat modelRotation = glm::quat(); glm::quat worldHeadOrientation = glm::quat();
glm::quat localHeadOrientation = glm::quat(); glm::quat localHeadOrientation = glm::quat();
float localHeadPitch = 0.0f; // degrees float localHeadPitch = 0.0f; // degrees
float localHeadYaw = 0.0f; // degrees float localHeadYaw = 0.0f; // degrees
float localHeadRoll = 0.0f; // degrees float localHeadRoll = 0.0f; // degrees
glm::vec3 localHeadPosition = glm::vec3(); glm::vec3 localHeadPosition = glm::vec3();
bool isInHMD = false; bool isInHMD = false;
int leanJointIndex = -1;
int neckJointIndex = -1;
bool isTalking = false;
};
struct EyeParameters {
glm::quat worldHeadOrientation = glm::quat(); glm::quat worldHeadOrientation = glm::quat();
glm::vec3 eyeLookAt = glm::vec3(); // world space glm::vec3 eyeLookAt = glm::vec3(); // world space
glm::vec3 eyeSaccade = glm::vec3(); // world space glm::vec3 eyeSaccade = glm::vec3(); // world space
glm::vec3 modelTranslation = glm::vec3(); glm::vec3 modelTranslation = glm::vec3();
int leanJointIndex = -1; glm::quat modelRotation = glm::quat();
int neckJointIndex = -1;
int leftEyeJointIndex = -1; int leftEyeJointIndex = -1;
int rightEyeJointIndex = -1; int rightEyeJointIndex = -1;
bool isTalking = false;
void dump() const;
}; };
struct HandParameters { struct HandParameters {
@ -185,9 +187,7 @@ public:
bool getEnableAnimGraph() const { return _enableAnimGraph; } bool getEnableAnimGraph() const { return _enableAnimGraph; }
void updateFromHeadParameters(const HeadParameters& params, float dt); void updateFromHeadParameters(const HeadParameters& params, float dt);
void updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation, void updateFromEyeParameters(const EyeParameters& params);
const glm::quat& worldHeadOrientation, const glm::vec3& lookAtSpot, const glm::vec3& saccade = glm::vec3(0.0f));
void updateFromHandParameters(const HandParameters& params, float dt); void updateFromHandParameters(const HandParameters& params, float dt);
virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation,