From aa9511c263bbb8cd046392fce30589ede794788d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 25 Sep 2014 22:49:12 -0700 Subject: [PATCH] Position Rift camera at avatar model's mid-eye location --- interface/src/Application.cpp | 2 +- interface/src/avatar/Avatar.cpp | 4 +++ interface/src/avatar/Avatar.h | 1 + interface/src/avatar/MyAvatar.cpp | 6 ++++- interface/src/avatar/MyAvatar.h | 1 + interface/src/avatar/SkeletonModel.cpp | 34 ++++++++++++++++++-------- interface/src/avatar/SkeletonModel.h | 8 +++--- interface/src/renderer/Model.cpp | 8 ++++++ interface/src/renderer/Model.h | 5 ++++ 9 files changed, 54 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 00cf3b9d01..03743c5f69 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -682,7 +682,7 @@ void Application::paintGL() { if (whichCamera.getMode() == CAMERA_MODE_MIRROR) { OculusManager::display(whichCamera.getRotation(), whichCamera.getPosition(), whichCamera); } else { - OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getUprightHeadPosition(), whichCamera); + OculusManager::display(_myAvatar->getWorldAlignedOrientation(), _myAvatar->getDefaultEyePosition(), whichCamera); } } else if (TV3DManager::isConnected()) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 22e7697b40..6f421965db 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -1028,6 +1028,10 @@ float Avatar::getPelvisFloatingHeight() const { return -_skeletonModel.getBindExtents().minimum.y; } +float Avatar::getPelvisToHeadLength() const { + return glm::distance(_position, getHead()->getPosition()); +} + void Avatar::setShowDisplayName(bool showDisplayName) { if (!Menu::getInstance()->isOptionChecked(MenuOption::NamesAboveHeads)) { _displayNameAlpha = 0.0f; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 58add5aecd..c449a0d1b9 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -223,6 +223,7 @@ protected: float getSkeletonHeight() const; float getHeadHeight() const; float getPelvisFloatingHeight() const; + float getPelvisToHeadLength() const; glm::vec3 getDisplayNamePosition(); void renderDisplayName(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e59de3628a..2f6b728a24 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -977,7 +977,11 @@ void MyAvatar::clearLookAtTargetAvatar() { } glm::vec3 MyAvatar::getUprightHeadPosition() const { - return _position + getWorldAlignedOrientation() * _skeletonModel.getDefaultHeadModelPosition(); + return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, getPelvisToHeadLength(), 0.0f); +} + +glm::vec3 MyAvatar::getDefaultEyePosition() const { + return _position + getWorldAlignedOrientation() * _skeletonModel.getDefaultEyeModelPosition(); } const float SCRIPT_PRIORITY = DEFAULT_PRIORITY + 1.0f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d553d4f367..249e1f91b0 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -66,6 +66,7 @@ public: const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; } glm::vec3 getGravity() const { return _gravity; } glm::vec3 getUprightHeadPosition() const; + glm::vec3 getDefaultEyePosition() const; bool getShouldRenderLocally() const { return _shouldRender; } const QList& getAnimationHandles() const { return _animationHandles; } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 9522e54e26..ca60ff8ac0 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -470,23 +470,23 @@ bool SkeletonModel::getNeckParentRotationFromDefaultOrientation(glm::quat& neckP return success; } -bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const { +bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const { if (!isActive()) { return false; - } + } const FBXGeometry& geometry = _geometry->getFBXGeometry(); - if (getJointPositionInWorldFrame(geometry.leftEyeJointIndex, firstEyePosition) && - getJointPositionInWorldFrame(geometry.rightEyeJointIndex, secondEyePosition)) { + if (getJointPosition(geometry.leftEyeJointIndex, firstEyePosition) && + getJointPosition(geometry.rightEyeJointIndex, secondEyePosition)) { return true; } // no eye joints; try to estimate based on head/neck joints glm::vec3 neckPosition, headPosition; - if (getJointPositionInWorldFrame(geometry.neckJointIndex, neckPosition) && - getJointPositionInWorldFrame(geometry.headJointIndex, headPosition)) { + if (getJointPosition(geometry.neckJointIndex, neckPosition) && + getJointPosition(geometry.headJointIndex, headPosition)) { const float EYE_PROPORTION = 0.6f; glm::vec3 baseEyePosition = glm::mix(neckPosition, headPosition, EYE_PROPORTION); glm::quat headRotation; - getJointRotationInWorldFrame(geometry.headJointIndex, headRotation); + getJointRotation(geometry.headJointIndex, headRotation); const float EYES_FORWARD = 0.25f; const float EYE_SEPARATION = 0.1f; float headHeight = glm::distance(neckPosition, headPosition); @@ -497,6 +497,15 @@ bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& seco return false; } +bool SkeletonModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const { + if (getEyeModelPositions(firstEyePosition, secondEyePosition)) { + firstEyePosition = _translation + _rotation * firstEyePosition; + secondEyePosition = _translation + _rotation * secondEyePosition; + return true; + } + return false; +} + void SkeletonModel::renderRagdoll() { if (!_ragdoll) { return; @@ -658,13 +667,18 @@ void SkeletonModel::buildShapes() { int headJointIndex = _geometry->getFBXGeometry().headJointIndex; if (0 <= headJointIndex && headJointIndex < _jointStates.size()) { + glm::vec3 leftEyePosition, rightEyePosition; + getEyeModelPositions(leftEyePosition, rightEyePosition); + glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.f; + int rootJointIndex = _geometry->getFBXGeometry().rootJointIndex; glm::vec3 rootModelPosition; - getJointPosition(headJointIndex, _defaultHeadModelPosition); getJointPosition(rootJointIndex, rootModelPosition); - _defaultHeadModelPosition = _defaultHeadModelPosition - rootModelPosition; + + _defaultEyeModelPosition = midEyePosition - rootModelPosition; + _defaultEyeModelPosition.z = -_defaultEyeModelPosition.z; } else { - _defaultHeadModelPosition = glm::vec3(0.f, 0.f, 0.f); + _defaultEyeModelPosition = glm::vec3(0.f, 0.f, 0.f); } // While the shapes are in their default position we disable collisions between diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 036811a926..35122d5e18 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -97,9 +97,9 @@ public: /// \return whether or not both eye meshes were found bool getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const; - /// Gets the default position of the head in model frame coordinates. + /// Gets the default position of the mid eye point in model frame coordinates. /// \return whether or not the head was found. - glm::vec3 getDefaultHeadModelPosition() const { return _defaultHeadModelPosition; } + glm::vec3 getDefaultEyeModelPosition() const { return _defaultEyeModelPosition; } virtual void updateVisibleJointStates(); @@ -144,6 +144,8 @@ private: /// \param position position of joint in model-frame /// \param rotation rotation of joint in model-frame void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation); + + bool getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const; Avatar* _owningAvatar; @@ -151,7 +153,7 @@ private: glm::vec3 _boundingShapeLocalOffset; SkeletonRagdoll* _ragdoll; - glm::vec3 _defaultHeadModelPosition; + glm::vec3 _defaultEyeModelPosition; }; #endif // hifi_SkeletonModel_h diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 19d711a69d..e4ab8b24d9 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -768,6 +768,14 @@ bool Model::getJointRotationInWorldFrame(int jointIndex, glm::quat& rotation) co return true; } +bool Model::getJointRotation(int jointIndex, glm::quat& rotation) const { + if (jointIndex == -1 || jointIndex >= _jointStates.size()) { + return false; + } + rotation = _jointStates[jointIndex].getRotation(); + return true; +} + bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 63b2058a20..2361133878 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -153,6 +153,11 @@ public: /// \return true if joint exists bool getJointPosition(int jointIndex, glm::vec3& position) const; + /// \param jointIndex index of joint in model structure + /// \param rotation[out] rotation of joint in model-frame + /// \return true if joint exists + bool getJointRotation(int jointIndex, glm::quat& rotation) const; + QStringList getJointNames() const; AnimationHandlePointer createAnimationHandle();