From 6f8f15018c26db4a78a54521fccb034ba05cb753 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 21 Feb 2014 17:52:20 -0800 Subject: [PATCH] Allow setting the combined head orientation, which changes the body yaw and applies the rest to the head. Closes #2050. --- examples/editVoxels.js | 2 +- interface/src/avatar/Avatar.cpp | 1 - interface/src/avatar/Head.cpp | 7 +------ interface/src/avatar/Head.h | 3 --- interface/src/avatar/MyAvatar.cpp | 1 - libraries/avatars/src/AvatarData.h | 4 ++++ libraries/avatars/src/HeadData.cpp | 23 +++++++++++++++++++++++ libraries/avatars/src/HeadData.h | 4 ++++ 8 files changed, 33 insertions(+), 12 deletions(-) diff --git a/examples/editVoxels.js b/examples/editVoxels.js index 81e3000566..393dd52fef 100644 --- a/examples/editVoxels.js +++ b/examples/editVoxels.js @@ -866,7 +866,7 @@ function mouseReleaseEvent(event) { var cameraOrientation = Camera.getOrientation(); var eulers = Quat.safeEulerAngles(cameraOrientation); MyAvatar.position = Camera.getPosition(); - MyAvatar.orientation = cameraOrientation; + MyAvatar.headOrientation = cameraOrientation; Camera.stopLooking(); Camera.setMode(oldMode); Camera.setOrientation(cameraOrientation); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index dcecd0258d..0f820f871a 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -118,7 +118,6 @@ void Avatar::simulate(float deltaTime) { getHand()->simulate(deltaTime, false); _skeletonModel.simulate(deltaTime); Head* head = getHead(); - head->setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); glm::vec3 headPosition; if (!_skeletonModel.getHeadPosition(headPosition)) { headPosition = _position; diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 5c6100764a..f6c8fabc0d 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -28,7 +28,6 @@ Head::Head(Avatar* owningAvatar) : _gravity(0.0f, -1.0f, 0.0f), _lastLoudness(0.0f), _audioAttack(0.0f), - _bodyRotation(0.0f, 0.0f, 0.0f), _angularVelocity(0,0,0), _renderLookatVectors(false), _saccade(0.0f, 0.0f, 0.0f), @@ -180,12 +179,8 @@ void Head::setScale (float scale) { _scale = scale; } -glm::quat Head::getOrientation() const { - return glm::quat(glm::radians(_bodyRotation)) * glm::quat(glm::radians(glm::vec3(_pitch, _yaw, _roll))); -} - glm::quat Head::getTweakedOrientation() const { - return glm::quat(glm::radians(_bodyRotation)) * glm::quat(glm::radians(glm::vec3(getTweakedPitch(), getTweakedYaw(), getTweakedRoll() ))); + return _owningAvatar->getOrientation() * glm::quat(glm::radians(glm::vec3(getTweakedPitch(), getTweakedYaw(), getTweakedRoll() ))); } glm::quat Head::getCameraOrientation () const { diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index c88e654d95..39a2f4eeb6 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -40,13 +40,11 @@ public: void render(float alpha); void setScale(float scale); void setPosition(glm::vec3 position) { _position = position; } - void setBodyRotation(glm::vec3 bodyRotation) { _bodyRotation = bodyRotation; } void setGravity(glm::vec3 gravity) { _gravity = gravity; } void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } void setRenderLookatVectors(bool onOff) { _renderLookatVectors = onOff; } - glm::quat getOrientation() const; glm::quat getTweakedOrientation() const; glm::quat getCameraOrientation () const; const glm::vec3& getAngularVelocity() const { return _angularVelocity; } @@ -97,7 +95,6 @@ private: glm::vec3 _gravity; float _lastLoudness; float _audioAttack; - glm::vec3 _bodyRotation; glm::vec3 _angularVelocity; bool _renderLookatVectors; glm::vec3 _saccade; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 90ef18848b..60af1560ce 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -321,7 +321,6 @@ void MyAvatar::simulate(float deltaTime) { _skeletonModel.simulate(deltaTime); Head* head = getHead(); - head->setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); glm::vec3 headPosition; if (!_skeletonModel.getHeadPosition(headPosition)) { headPosition = _position; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 07c774d5e6..8f6ce850a6 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -78,6 +78,7 @@ class AvatarData : public NodeData { Q_PROPERTY(QString chatMessage READ getQStringChatMessage WRITE setChatMessage) Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation) + Q_PROPERTY(glm::quat headOrientation READ getHeadOrientation WRITE setHeadOrientation) Q_PROPERTY(float headPitch READ getHeadPitch WRITE setHeadPitch) Q_PROPERTY(float audioLoudness READ getAudioLoudness WRITE setAudioLoudness) @@ -109,6 +110,9 @@ public: glm::quat getOrientation() const { return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); } void setOrientation(const glm::quat& orientation); + glm::quat getHeadOrientation() const { return _headData->getOrientation(); } + void setHeadOrientation(const glm::quat& orientation) { _headData->setOrientation(orientation); } + // access to Head().set/getMousePitch float getHeadPitch() const { return _headData->getPitch(); } void setHeadPitch(float value) { _headData->setPitch(value); }; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index 62e8276bd3..68a5c2c826 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -6,6 +6,11 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // +#include + +#include + +#include "AvatarData.h" #include "HeadData.h" HeadData::HeadData(AvatarData* owningAvatar) : @@ -26,6 +31,24 @@ HeadData::HeadData(AvatarData* owningAvatar) : } +glm::quat HeadData::getOrientation() const { + return _owningAvatar->getOrientation() * glm::quat(glm::radians(glm::vec3(_pitch, _yaw, _roll))); +} + +void HeadData::setOrientation(const glm::quat& orientation) { + // rotate body about vertical axis + glm::quat bodyOrientation = _owningAvatar->getOrientation(); + glm::vec3 newFront = glm::inverse(bodyOrientation) * (orientation * IDENTITY_FRONT); + bodyOrientation = bodyOrientation * glm::angleAxis(glm::degrees(atan2f(-newFront.x, -newFront.z)), 0.0f, 1.0f, 0.0f); + _owningAvatar->setOrientation(bodyOrientation); + + // the rest goes to the head + glm::vec3 eulers = safeEulerAngles(glm::inverse(bodyOrientation) * orientation); + _pitch = eulers.x; + _yaw = eulers.y; + _roll = eulers.z; +} + void HeadData::addYaw(float yaw) { setYaw(_yaw + yaw); } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index 04d5fe5b46..618de89b31 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -13,6 +13,7 @@ #include #include +#include const float MIN_HEAD_YAW = -110; const float MAX_HEAD_YAW = 110; @@ -42,6 +43,9 @@ public: float getRoll() const { return _roll; } void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } + glm::quat getOrientation() const; + void setOrientation(const glm::quat& orientation); + float getAudioLoudness() const { return _audioLoudness; } void setAudioLoudness(float audioLoudness) { _audioLoudness = audioLoudness; }