Avatar eye look at fixes for HMDs

There were three things that were causing issues with eye look at vectors while wearing an HMD.

1) The matrix returned by AvatarUpdate->getHeadPose() was in the wrong space, it should be in avatar space.
   it was actually returning a matrix in sensor/room space.
2) The lookAtPosition was incorrect while wearing an HMD and with no avatars to look at.
3) The eye rotation limits in Rig::updateEyeJoint were relative to the model's zero orientation, NOT relative to the head.
   this was causing the eyes to hit limits when the avatar head turned.
This commit is contained in:
Anthony J. Thibault 2016-02-29 18:02:50 -08:00
parent 99bd0f3d13
commit 460582239a
3 changed files with 20 additions and 6 deletions

View file

@ -2946,9 +2946,9 @@ void Application::updateMyAvatarLookAtPosition() {
} else {
// I am not looking at anyone else, so just look forward
if (isHMD) {
glm::mat4 headPose = _avatarUpdate->getHeadPose() ;
glm::mat4 headPose = _avatarUpdate->getHeadPose();
glm::quat headRotation = glm::quat_cast(headPose);
lookAtSpot = _myCamera.getPosition() +
lookAtSpot = myAvatar->getPosition() +
myAvatar->getOrientation() * (headRotation * glm::vec3(0.0f, 0.0f, -TREE_SCALE));
} else {
lookAtSpot = myAvatar->getHead()->getEyePosition() +

View file

@ -31,7 +31,14 @@ void AvatarUpdate::synchronousProcess() {
// Keep our own updated value, so that our asynchronous code can consult it.
_isHMDMode = qApp->isHMDMode();
auto frameCount = qApp->getFrameCount();
_headPose = qApp->getActiveDisplayPlugin()->getHeadPose(frameCount);
QSharedPointer<AvatarManager> manager = DependencyManager::get<AvatarManager>();
MyAvatar* myAvatar = manager->getMyAvatar();
assert(myAvatar);
// transform the head pose from the displayPlugin into avatar coordinates.
glm::mat4 invAvatarMat = glm::inverse(createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()));
_headPose = invAvatarMat * (myAvatar->getSensorToWorldMatrix() * qApp->getActiveDisplayPlugin()->getHeadPose(frameCount));
if (!isThreaded()) {
process();

View file

@ -1067,14 +1067,21 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm
glm::mat4 rigToWorld = createMatFromQuatAndPos(modelRotation, modelTranslation);
glm::mat4 worldToRig = glm::inverse(rigToWorld);
glm::vec3 zAxis = glm::normalize(_internalPoseSet._absolutePoses[index].trans - transformPoint(worldToRig, lookAtSpot));
glm::quat q = rotationBetween(IDENTITY_FRONT, zAxis);
glm::quat desiredQuat = rotationBetween(IDENTITY_FRONT, zAxis);
glm::quat headQuat;
int headIndex = _animSkeleton->nameToJointIndex("Head");
if (headIndex >= 0) {
headQuat = _internalPoseSet._absolutePoses[headIndex].rot;
}
glm::quat deltaQuat = desiredQuat * glm::inverse(headQuat);
// limit rotation
const float MAX_ANGLE = 30.0f * RADIANS_PER_DEGREE;
q = glm::angleAxis(glm::clamp(glm::angle(q), -MAX_ANGLE, MAX_ANGLE), glm::axis(q));
deltaQuat = glm::angleAxis(glm::clamp(glm::angle(deltaQuat), -MAX_ANGLE, MAX_ANGLE), glm::axis(deltaQuat));
// directly set absolutePose rotation
_internalPoseSet._absolutePoses[index].rot = q;
_internalPoseSet._absolutePoses[index].rot = deltaQuat * headQuat;
}
}