From 257a1d1f2e0013c50bb3a47a3a9e638ba6aa7380 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 15:21:02 -0700 Subject: [PATCH 1/4] move head rotations to new HeadData class to be used for transmission --- interface/src/Application.cpp | 11 +++--- interface/src/Avatar.cpp | 54 +++++++++++++--------------- interface/src/Avatar.h | 1 + interface/src/Head.cpp | 12 ++----- interface/src/Head.h | 7 ++-- libraries/avatars/src/AvatarData.cpp | 37 +++++++++---------- libraries/avatars/src/AvatarData.h | 24 ++++--------- libraries/avatars/src/HeadData.cpp | 53 +++++++++++++++++++++++++++ libraries/avatars/src/HeadData.h | 36 +++++++++++++++++++ 9 files changed, 151 insertions(+), 84 deletions(-) create mode 100644 libraries/avatars/src/HeadData.cpp create mode 100644 libraries/avatars/src/HeadData.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a3e91e023b..7c577589f9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -297,8 +297,9 @@ void Application::paintGL() { _myCamera.setDistance (0.0f); _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); - _myCamera.setTargetRotation(_myAvatar.getBodyYaw() + _myAvatar.getHeadYaw(), - -_myAvatar.getHeadPitch(), _myAvatar.getHeadRoll()); + _myCamera.setTargetRotation(_myAvatar.getBodyYaw() + _myAvatar.getHead().getYaw(), + -_myAvatar.getHead().getPitch(), + _myAvatar.getHead().getRoll()); } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { _myCamera.setTightness (100.0f); @@ -1375,9 +1376,9 @@ void Application::updateAvatar(float deltaTime) { float yaw, pitch, roll; OculusManager::getEulerAngles(yaw, pitch, roll); - _myAvatar.setHeadYaw(-yaw); - _myAvatar.setHeadPitch(pitch); - _myAvatar.setHeadRoll(roll); + _myAvatar.getHead().setYaw(-yaw); + _myAvatar.getHead().setPitch(pitch); + _myAvatar.getHead().setRoll(roll); } // Get audio loudness data from audio input device diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index befedcf524..589c99e462 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -59,8 +59,11 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.45; - -Avatar::Avatar(bool isMine) { +Avatar::Avatar(bool isMine) : _head() { + + // give the pointer to our head to inherited _headData variable from AvatarData + _headData = &_head; + _orientation.setToIdentity(); _velocity = glm::vec3(0.0f, 0.0f, 0.0f); @@ -109,7 +112,9 @@ Avatar::Avatar(bool isMine) { } void Avatar::reset() { - _headPitch = _headYaw = _headRoll = 0; + _head.setYaw(0.0f); + _head.setRoll(0.0f); + _head.setPitch(0.0f); _head.leanForward = _head.leanSideways = 0; } @@ -124,23 +129,16 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa measuredRollRate = serialInterface->getLastRollRate(); // Update avatar head position based on measured gyro rates - const float MAX_YAW = 85; - const float MIN_YAW = -85; - const float MAX_ROLL = 50; - const float MIN_ROLL = -50; - addHeadPitch(measuredPitchRate * deltaTime); - addHeadYaw(measuredYawRate * deltaTime); - addHeadRoll(measuredRollRate * deltaTime); - - setHeadYaw(glm::clamp(getHeadYaw(), MIN_YAW, MAX_YAW)); - setHeadRoll(glm::clamp(getHeadRoll(), MIN_ROLL, MAX_ROLL)); + _head.addPitch(measuredPitchRate * deltaTime); + _head.addYaw(measuredYawRate * deltaTime); + _head.addRoll(measuredRollRate * deltaTime); // Update head lean distance based on accelerometer data const float LEAN_SENSITIVITY = 0.15; const float LEAN_MAX = 0.45; const float LEAN_AVERAGING = 10.0; - glm::vec3 headRotationRates(getHeadPitch(), getHeadYaw(), getHeadRoll()); + glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll()); float headRateMax = 50.f; @@ -159,11 +157,11 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa } float Avatar::getAbsoluteHeadYaw() const { - return _bodyYaw + _headYaw; + return _bodyYaw + _head.getYaw(); } float Avatar::getAbsoluteHeadPitch() const { - return _bodyPitch + _headPitch; + return _bodyPitch + _head.getPitch(); } void Avatar::addLean(float x, float z) { @@ -221,7 +219,7 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree if (fabs(mouseLocationY) > MOUSE_MOVE_RADIUS) { float mousePitchAdd = (fabs(mouseLocationY) - MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_PITCH_SPEED; bool downPitching = (mouseLocationY > 0.f); - setHeadPitch(getHeadPitch() + (downPitching ? mousePitchAdd : -mousePitchAdd)); + _head.setPitch(_head.getPitch() + (downPitching ? mousePitchAdd : -mousePitchAdd)); } } @@ -354,7 +352,7 @@ void Avatar::simulate(float deltaTime) { // Decay HeadPitch as a function of acceleration, so that you look straight ahead when // you start moving, but don't do this with an HMD like the Oculus. if (!OculusManager::isConnected()) { - setHeadPitch(getHeadPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); + _head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime)); } // Get head position data from network for other people @@ -389,11 +387,7 @@ void Avatar::simulate(float deltaTime) { } // update head state - _head.setPositionRotationAndScale( - _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, - glm::vec3(_headYaw, _headPitch, _headRoll), - _joint[ AVATAR_JOINT_HEAD_BASE ].radius - ); + _head.setPositionAndScale(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition, _joint[AVATAR_JOINT_HEAD_BASE].radius); setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 @@ -1343,18 +1337,18 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity if (deltaTime == 0.f) { // On first sample, set head to absolute position - setHeadYaw(eulerAngles->x); - setHeadPitch(eulerAngles->y); - setHeadRoll(eulerAngles->z); + _head.setYaw(eulerAngles->x); + _head.setPitch(eulerAngles->y); + _head.setRoll(eulerAngles->z); } else { - glm::vec3 angles(getHeadYaw(), getHeadPitch(), getHeadRoll()); + glm::vec3 angles(_head.getYaw(), _head.getPitch(), _head.getRoll()); // Increment by detected velocity angles += (*angularVelocity) * deltaTime; // Smooth to slowly follow absolute values angles = ((1.f - deltaTime / smoothingTime) * angles) + (deltaTime / smoothingTime) * (*eulerAngles); - setHeadYaw(fmin(fmax(angles.x, MIN_YAW), MAX_YAW)); - setHeadPitch(fmin(fmax(angles.y, MIN_PITCH), MAX_PITCH)); - setHeadRoll(fmin(fmax(angles.z, MIN_ROLL), MAX_ROLL)); + _head.setYaw(angles.x); + _head.setPitch(angles.y); + _head.setRoll(angles.z); //printLog("Y/P/R: %3.1f, %3.1f, %3.1f\n", angles.x, angles.y, angles.z); } } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 61fda4edda..3845b9cb60 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -106,6 +106,7 @@ public: float getHeight() const { return _height; } AvatarMode getMode() const { return _mode; } + Head getHead() const { return _head; } void setMousePressed(bool pressed); void render(bool lookingInMirror, glm::vec3 cameraPosition); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 3b751651b2..587e6279af 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -46,9 +46,6 @@ Head::Head() : _position(0.0f, 0.0f, 0.0f), _rotation(0.0f, 0.0f, 0.0f), _lookatPosition(0.0f, 0.0f, 0.0f), - _yaw(0.0f), - _pitch(0.0f), - _roll(0.0f), _eyeballPitch(), _eyeballYaw(), _interBrowDistance(0.75f), @@ -77,12 +74,9 @@ Head::Head() : } -void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { - _position = p; - _scale = s; - _yaw = r.x; - _pitch = r.y; - _roll = r.z; +void Head::setPositionAndScale(glm::vec3 position, float scale) { + _position = position; + _scale = scale; } void Head::setNewTarget(float pitch, float yaw) { diff --git a/interface/src/Head.h b/interface/src/Head.h index 4ee20e3cfd..49f67e6dab 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -23,7 +23,7 @@ enum eyeContactTargets MOUTH }; -class Head { +class Head : public HeadData { public: Head(); @@ -31,7 +31,7 @@ public: void render(bool lookingInMirror); void setLooking(bool looking); - void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale); + void setPositionAndScale(glm::vec3 position, float scale); void setNewTarget(float, float); void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } @@ -63,9 +63,6 @@ private: glm::vec3 _lookatPosition; glm::vec3 _leftEyePosition; glm::vec3 _rightEyePosition; - float _yaw; - float _pitch; - float _roll; float _eyeballPitch[2]; float _eyeballYaw [2]; float _eyebrowPitch[2]; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 56218c61ad..b0fb963984 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 4/9/13. -// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // #include @@ -39,9 +39,6 @@ AvatarData::AvatarData() : _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), - _headYaw(0), - _headPitch(0), - _headRoll(0), _headLeanSideways(0), _headLeanForward(0), _audioLoudness(0), @@ -57,11 +54,16 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _wantResIn(false), _wantColor(true), - _wantDelta(false) + _wantDelta(false), + _headData(NULL) { } +AvatarData::~AvatarData() { + delete _headData; +} + int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { unsigned char* bufferStart = destinationBuffer; @@ -79,9 +81,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headYaw); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headPitch); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headRoll); + printf("Current values are %f,%f,%f\n", _headData->getYaw(), _headData->getPitch(), _headData->getRoll()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getYaw()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getPitch()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getRoll()); // Head lean X,Z (head lateral and fwd/back motion relative to torso) memcpy(destinationBuffer, &_headLeanSideways, sizeof(float)); @@ -165,9 +168,14 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headRoll); + float headYaw, headPitch, headRoll; + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headRoll); + + _headData->setYaw(headYaw); + _headData->setPitch(headPitch); + _headData->setRoll(headRoll); // Head position relative to pelvis memcpy(&_headLeanSideways, sourceBuffer, sizeof(float)); @@ -226,11 +234,4 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { _wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT); return sourceBuffer - startPosition; -} - -void AvatarData::setHeadPitch(float p) { - // Set head pitch and apply limits - const float MAX_PITCH = 60; - const float MIN_PITCH = -60; - _headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH); } \ No newline at end of file diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 2c676d6120..19a2332c8b 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -3,7 +3,7 @@ // hifi // // Created by Stephen Birarda on 4/9/13. -// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // #ifndef __hifi__AvatarData__ @@ -14,6 +14,7 @@ #include #include +#include "HeadData.h" const int WANT_RESIN_AT_BIT = 0; const int WANT_COLOR_AT_BIT = 1; @@ -29,6 +30,7 @@ enum KeyState class AvatarData : public AgentData { public: AvatarData(); + ~AvatarData(); const glm::vec3& getPosition() const { return _position; } @@ -47,17 +49,6 @@ public: float getBodyRoll() const {return _bodyRoll; } void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; } - // Head Rotation - void setHeadPitch(float p); - void setHeadYaw(float y) {_headYaw = y; } - void setHeadRoll(float r) {_headRoll = r; }; - float getHeadPitch() const { return _headPitch; }; - float getHeadYaw() const { return _headYaw; }; - float getHeadRoll() const { return _headRoll; }; - void addHeadPitch(float p) { setHeadPitch(_headPitch - p); } - void addHeadYaw(float y){_headYaw -= y; } - void addHeadRoll(float r){_headRoll += r; } - // Head vector deflection from pelvix in X,Z void setHeadLeanSideways(float s) {_headLeanSideways = s; }; float getHeadLeanSideways() const { return _headLeanSideways; }; @@ -108,6 +99,8 @@ public: void setWantColor(bool wantColor) { _wantColor = wantColor; } void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; } + void setHeadData(HeadData* headData) { _headData = headData; } + protected: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); @@ -122,11 +115,6 @@ protected: float _bodyPitch; float _bodyRoll; - // Head rotation (relative to body) - float _headYaw; - float _headPitch; - float _headRoll; - float _headLeanSideways; float _headLeanForward; @@ -158,6 +146,8 @@ protected: bool _wantResIn; bool _wantColor; bool _wantDelta; + + HeadData* _headData; }; #endif /* defined(__hifi__AvatarData__) */ diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp new file mode 100644 index 0000000000..e806fe0b6b --- /dev/null +++ b/libraries/avatars/src/HeadData.cpp @@ -0,0 +1,53 @@ +// +// HeadData.cpp +// hifi +// +// Created by Stephen Birarda on 5/20/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#include "HeadData.h" + +#include + +HeadData::HeadData() : + _yaw(0.0f), + _pitch(0.0f), + _roll(0.0f) +{ + +} + +void HeadData::setYaw(float yaw) { + const float MAX_YAW = 85; + const float MIN_YAW = -85; + + _yaw = glm::clamp(yaw, MIN_YAW, MAX_YAW); +} + +void HeadData::setPitch(float pitch) { + // set head pitch and apply limits + const float MAX_PITCH = 60; + const float MIN_PITCH = -60; + + _pitch = glm::clamp(pitch, MIN_PITCH, MAX_PITCH); +} + +void HeadData::setRoll(float roll) { + const float MAX_ROLL = 50; + const float MIN_ROLL = -50; + + _roll = glm::clamp(roll, MIN_ROLL, MAX_ROLL); +} + +void HeadData::addYaw(float yaw) { + setYaw(_yaw + yaw); +} + +void HeadData::addPitch(float pitch) { + setPitch(_pitch + pitch); +} + +void HeadData::addRoll(float roll) { + setRoll(_roll + roll); +} \ No newline at end of file diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h new file mode 100644 index 0000000000..d5647f0275 --- /dev/null +++ b/libraries/avatars/src/HeadData.h @@ -0,0 +1,36 @@ +// +// HeadData.h +// hifi +// +// Created by Stephen Birarda on 5/20/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__HeadData__ +#define __hifi__HeadData__ + +#include + +class HeadData { +public: + HeadData(); + + float getYaw() const { return _yaw; } + void setYaw(float yaw); + + float getPitch() const { return _pitch; } + void setPitch(float pitch); + + float getRoll() const { return _roll; } + void setRoll(float roll); + + void addYaw(float yaw); + void addPitch(float pitch); + void addRoll(float roll); +protected: + float _yaw; + float _pitch; + float _roll; +}; + +#endif /* defined(__hifi__HeadData__) */ From de84b7803f14e304a25258ea36ab95d1e0de48be Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 15:51:40 -0700 Subject: [PATCH 2/4] move _lookAtPosition to HeadData class --- interface/src/Avatar.cpp | 16 +++++++--------- interface/src/Avatar.h | 1 + interface/src/Head.cpp | 7 +++---- interface/src/Head.h | 2 -- libraries/avatars/src/AvatarData.cpp | 14 ++++++++------ libraries/avatars/src/AvatarData.h | 2 -- libraries/avatars/src/HeadData.cpp | 5 ++--- libraries/avatars/src/HeadData.h | 8 ++++++++ 8 files changed, 29 insertions(+), 26 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 589c99e462..cc41e0d585 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -111,6 +111,11 @@ Avatar::Avatar(bool isMine) : _head() { else { _balls = NULL; } } +Avatar::~Avatar() { + // if _balls is something that's sticking around other than Philip playing around it needs to be delete here too + _headData = NULL; +} + void Avatar::reset() { _head.setYaw(0.0f); _head.setRoll(0.0f); @@ -389,20 +394,19 @@ void Avatar::simulate(float deltaTime) { // update head state _head.setPositionAndScale(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition, _joint[AVATAR_JOINT_HEAD_BASE].radius); - setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 + _head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 if (_interactingOther) { _head.setLooking(true); if (_isMine) { - setLookatPosition(_interactingOther->getSpringyHeadPosition()); + _head.setLookAtPosition(_interactingOther->getSpringyHeadPosition()); } } else { _head.setLooking(false); } _head.setBodyYaw(_bodyYaw); - _head.setLookatPosition(_lookatPosition); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, _isMine); @@ -1328,12 +1332,6 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity // absolute eulerAngles passed. // // - float const MAX_YAW = 90.f; - float const MIN_YAW = -90.f; - float const MAX_PITCH = 85.f; - float const MIN_PITCH = -85.f; - float const MAX_ROLL = 90.f; - float const MIN_ROLL = -90.f; if (deltaTime == 0.f) { // On first sample, set head to absolute position diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 3845b9cb60..90735c5876 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -77,6 +77,7 @@ enum AvatarJointID class Avatar : public AvatarData { public: Avatar(bool isMine); + ~Avatar(); void reset(); void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 587e6279af..c59dd9ac1d 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -45,7 +45,6 @@ Head::Head() : _skinColor(0.0f, 0.0f, 0.0f), _position(0.0f, 0.0f, 0.0f), _rotation(0.0f, 0.0f, 0.0f), - _lookatPosition(0.0f, 0.0f, 0.0f), _eyeballPitch(), _eyeballYaw(), _interBrowDistance(0.75f), @@ -224,7 +223,7 @@ void Head::setLooking(bool looking) { _lookingAtSomething = looking; glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - averageEyePosition); + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - averageEyePosition); float dot = glm::dot(targetLookatAxis, _orientation.getFront()); if (dot < MINIMUM_EYE_ROTATION) { @@ -370,7 +369,7 @@ void Head::renderEyeBalls() { if (_lookingAtSomething) { //rotate the eyeball to aim towards the lookat position - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _leftEyePosition); // the lookat direction + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _leftEyePosition); // the lookat direction glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); @@ -414,7 +413,7 @@ void Head::renderEyeBalls() { if (_lookingAtSomething) { //rotate the eyeball to aim towards the lookat position - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _rightEyePosition); + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _rightEyePosition); glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP); float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); diff --git a/interface/src/Head.h b/interface/src/Head.h index 49f67e6dab..a731a7b87e 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -34,7 +34,6 @@ public: void setPositionAndScale(glm::vec3 position, float scale); void setNewTarget(float, float); - void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } void setGravity (glm::vec3 gravity ) { _gravity = gravity; } void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; } void setBodyYaw (float bodyYaw ) { _bodyYaw = bodyYaw; } @@ -60,7 +59,6 @@ private: glm::vec3 _skinColor; glm::vec3 _position; glm::vec3 _rotation; - glm::vec3 _lookatPosition; glm::vec3 _leftEyePosition; glm::vec3 _rightEyePosition; float _eyeballPitch[2]; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b0fb963984..27f4286bbd 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -35,7 +35,6 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo AvatarData::AvatarData() : _handPosition(0,0,0), - _lookatPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), @@ -97,8 +96,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(float) * 3; // Lookat Position - memcpy(destinationBuffer, &_lookatPosition, sizeof(_lookatPosition)); - destinationBuffer += sizeof(_lookatPosition); + memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition)); + destinationBuffer += sizeof(_headData->_lookAtPosition); // Hand State (0 = not grabbing, 1 = grabbing) memcpy(destinationBuffer, &_handState, sizeof(char)); @@ -148,7 +147,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // called on the other agents - assigns it to my views of the others int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { -//printf("AvatarData::parseData()\n"); + // lazily allocate memory for HeadData in case we're not an Avatar instance + if (!_headData) { + _headData = new HeadData(); + } // increment to push past the packet header sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA); @@ -188,8 +190,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Lookat Position - memcpy(&_lookatPosition, sourceBuffer, sizeof(_lookatPosition)); - sourceBuffer += sizeof(_lookatPosition); + memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition)); + sourceBuffer += sizeof(_headData->_lookAtPosition); // Hand State memcpy(&_handState, sourceBuffer, sizeof(char)); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 19a2332c8b..e3621095d3 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -36,7 +36,6 @@ public: void setPosition (const glm::vec3 position ) { _position = position; } void setHandPosition (const glm::vec3 handPosition ) { _handPosition = handPosition; } - void setLookatPosition(const glm::vec3 lookatPosition) { _lookatPosition = lookatPosition; } int getBroadcastData(unsigned char* destinationBuffer); int parseData(unsigned char* sourceBuffer, int numBytes); @@ -108,7 +107,6 @@ protected: glm::vec3 _position; glm::vec3 _handPosition; - glm::vec3 _lookatPosition; // Body rotation float _bodyYaw; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index e806fe0b6b..c95f1b68e9 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -8,12 +8,11 @@ #include "HeadData.h" -#include - HeadData::HeadData() : _yaw(0.0f), _pitch(0.0f), - _roll(0.0f) + _roll(0.0f), + _lookAtPosition(0.0f, 0.0f, 0.0f) { } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index d5647f0275..eca16ef6b0 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -11,6 +11,8 @@ #include +#include + class HeadData { public: HeadData(); @@ -27,10 +29,16 @@ public: void addYaw(float yaw); void addPitch(float pitch); void addRoll(float roll); + + const glm::vec3& getLookAtPosition() const { return _lookAtPosition; } + void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; } + + friend class AvatarData; protected: float _yaw; float _pitch; float _roll; + glm::vec3 _lookAtPosition; }; #endif /* defined(__hifi__HeadData__) */ From 570dfba934fccdbe349d5371cdcda6a4efd24114 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 16:12:38 -0700 Subject: [PATCH 3/4] code review comments, cleanup Avatar constructor --- interface/src/Application.cpp | 16 ------ interface/src/Avatar.cpp | 85 +++++++++++++++--------------- interface/src/Avatar.h | 4 +- libraries/avatars/src/HeadData.cpp | 22 -------- libraries/avatars/src/HeadData.h | 13 +++-- 5 files changed, 54 insertions(+), 86 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7c577589f9..88c41665ee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1356,22 +1356,6 @@ void Application::updateAvatar(float deltaTime) { _headMouseY = max(_headMouseY, 0); _headMouseY = min(_headMouseY, _glWidget->height()); - // Update head and body pitch and yaw based on measured gyro rates - if (_gyroLook->isChecked()) { - // Render Yaw - /* NOTE: PER - Leave here until I get back and can modify to couple gyros to head pitch, yaw - float renderYawSpring = fabs(_headMouseX - _glWidget->width() / 2.f) / (_glWidget->width() / 2.f); - const float RENDER_YAW_MULTIPLY = 4.f; - _myAvatar.setRenderYaw((1.f - renderYawSpring * deltaTime) * _myAvatar.getRenderYaw() + - renderYawSpring * deltaTime * -_myAvatar.getHeadYaw() * RENDER_YAW_MULTIPLY); - // Render Pitch - float renderPitchSpring = fabs(_headMouseY - _glWidget->height() / 2.f) / (_glWidget->height() / 2.f); - const float RENDER_PITCH_MULTIPLY = 4.f; - _myAvatar.setRenderPitch((1.f - renderPitchSpring * deltaTime) * _myAvatar.getRenderPitch() + - renderPitchSpring * deltaTime * -_myAvatar.getHeadPitch() * RENDER_PITCH_MULTIPLY); - */ - } - if (OculusManager::isConnected()) { float yaw, pitch, roll; OculusManager::getEulerAngles(yaw, pitch, roll); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index cc41e0d585..d4e6ae0a8b 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -59,61 +59,62 @@ bool usingBigSphereCollisionTest = true; float chatMessageScale = 0.0015; float chatMessageHeight = 0.45; -Avatar::Avatar(bool isMine) : _head() { +Avatar::Avatar(bool isMine) : + _isMine(isMine), + _TEST_bigSphereRadius(0.4f), + _TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f), + _mousePressed(false), + _bodyPitchDelta(0.0f), + _bodyYawDelta(0.0f), + _bodyRollDelta(0.0f), + _movedHandOffset(0.0f, 0.0f, 0.0f), + _rotation(0.0f, 0.0f, 0.0f, 0.0f), + _mode(AVATAR_MODE_STANDING), + _handHoldingPosition(0.0f, 0.0f, 0.0f), + _velocity(0.0f, 0.0f, 0.0f), + _thrust(0.0f, 0.0f, 0.0f), + _speed(0.0f), + _maxArmLength(0.0f), + _orientation(), + _transmitterIsFirstData(true), + _transmitterHz(0.0f), + _transmitterPackets(0), + _transmitterInitialReading(0.0f, 0.0f, 0.0f), + _isTransmitterV2Connected(false), + _pelvisStandingHeight(0.0f), + _displayingHead(true), + _distanceToNearestAvatar(std::numeric_limits::max()), + _gravity(0.0f, -1.0f, 0.0f), + _mouseRayOrigin(0.0f, 0.0f, 0.0f), + _mouseRayDirection(0.0f, 0.0f, 0.0f), + _cameraPosition(0.0f, 0.0f, 0.0f), + _interactingOther(NULL), + _cumulativeMouseYaw(0.0f), + _isMouseTurningRight(false) +{ // give the pointer to our head to inherited _headData variable from AvatarData _headData = &_head; - - _orientation.setToIdentity(); - - _velocity = glm::vec3(0.0f, 0.0f, 0.0f); - _thrust = glm::vec3(0.0f, 0.0f, 0.0f); - _rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f); - _bodyYaw = -90.0; - _bodyPitch = 0.0; - _bodyRoll = 0.0; - _bodyPitchDelta = 0.0; - _bodyYawDelta = 0.0; - _bodyRollDelta = 0.0; - _mousePressed = false; - _mode = AVATAR_MODE_STANDING; - _isMine = isMine; - _maxArmLength = 0.0; - _transmitterHz = 0.0; - _transmitterPackets = 0; - _transmitterIsFirstData = true; - _transmitterInitialReading = glm::vec3(0.f, 0.f, 0.f); - _isTransmitterV2Connected = false; - _speed = 0.0; - _pelvisStandingHeight = 0.0f; - _displayingHead = true; - _TEST_bigSphereRadius = 0.4f; - _TEST_bigSpherePosition = glm::vec3(5.0f, _TEST_bigSphereRadius, 5.0f); - _mouseRayOrigin = glm::vec3(0.0f, 0.0f, 0.0f); - _mouseRayDirection = glm::vec3(0.0f, 0.0f, 0.0f); - _cameraPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _interactingOther = NULL; - for (int i = 0; i < MAX_DRIVE_KEYS; i++) _driveKeys[i] = false; - - _movedHandOffset = glm::vec3(0.0f, 0.0f, 0.0f); - _handHoldingPosition = glm::vec3(0.0f, 0.0f, 0.0f); - _distanceToNearestAvatar = std::numeric_limits::max(); - _gravity = glm::vec3(0.0f, -1.0f, 0.0f); - _cumulativeMouseYaw = 0.f; - _isMouseTurningRight = false; + + for (int i = 0; i < MAX_DRIVE_KEYS; i++) { + _driveKeys[i] = false; + } initializeSkeleton(); _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); - if (BALLS_ON) { _balls = new Balls(100); } - else { _balls = NULL; } + if (BALLS_ON) { + _balls = new Balls(100); + } else { + _balls = NULL; + } } Avatar::~Avatar() { - // if _balls is something that's sticking around other than Philip playing around it needs to be delete here too _headData = NULL; + delete _balls; } void Avatar::reset() { diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 90735c5876..5e2ce0fd47 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -165,8 +165,8 @@ private: Head _head; bool _isMine; - glm::vec3 _TEST_bigSpherePosition; float _TEST_bigSphereRadius; + glm::vec3 _TEST_bigSpherePosition; bool _mousePressed; float _bodyPitchDelta; float _bodyYawDelta; @@ -182,8 +182,6 @@ private: float _maxArmLength; Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; - float _renderYaw; - float _renderPitch; // Pitch from view frustum when this is own head bool _transmitterIsFirstData; timeval _transmitterTimeLastReceived; timeval _transmitterTimer; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index c95f1b68e9..bc400b96bb 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -17,28 +17,6 @@ HeadData::HeadData() : } -void HeadData::setYaw(float yaw) { - const float MAX_YAW = 85; - const float MIN_YAW = -85; - - _yaw = glm::clamp(yaw, MIN_YAW, MAX_YAW); -} - -void HeadData::setPitch(float pitch) { - // set head pitch and apply limits - const float MAX_PITCH = 60; - const float MIN_PITCH = -60; - - _pitch = glm::clamp(pitch, MIN_PITCH, MAX_PITCH); -} - -void HeadData::setRoll(float roll) { - const float MAX_ROLL = 50; - const float MIN_ROLL = -50; - - _roll = glm::clamp(roll, MIN_ROLL, MAX_ROLL); -} - void HeadData::addYaw(float yaw) { setYaw(_yaw + yaw); } diff --git a/libraries/avatars/src/HeadData.h b/libraries/avatars/src/HeadData.h index eca16ef6b0..7da3085fe7 100644 --- a/libraries/avatars/src/HeadData.h +++ b/libraries/avatars/src/HeadData.h @@ -13,18 +13,25 @@ #include +const float MIN_HEAD_YAW = -85; +const float MAX_HEAD_YAW = 85; +const float MIN_HEAD_PITCH = -60; +const float MAX_HEAD_PITCH = 60; +const float MIN_HEAD_ROLL = -50; +const float MAX_HEAD_ROLL = 50; + class HeadData { public: HeadData(); float getYaw() const { return _yaw; } - void setYaw(float yaw); + void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); } float getPitch() const { return _pitch; } - void setPitch(float pitch); + void setPitch(float pitch) { _pitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); } float getRoll() const { return _roll; } - void setRoll(float roll); + void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); } void addYaw(float yaw); void addPitch(float pitch); From 28bab24e7046d58e28f184e7df52fafb89a85d39 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 May 2013 16:17:49 -0700 Subject: [PATCH 4/4] type squishes in AvatarData --- libraries/avatars/src/AvatarData.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 27f4286bbd..8c6f4fb894 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -80,10 +80,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - printf("Current values are %f,%f,%f\n", _headData->getYaw(), _headData->getPitch(), _headData->getRoll()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getYaw()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getPitch()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getRoll()); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_roll); // Head lean X,Z (head lateral and fwd/back motion relative to torso) memcpy(destinationBuffer, &_headLeanSideways, sizeof(float)); @@ -165,15 +164,15 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(float) * 3; // Body rotation (NOTE: This needs to become a quaternion to save two bytes) - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll); // Head rotation (NOTE: This needs to become a quaternion to save two bytes) float headYaw, headPitch, headRoll; - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &headRoll); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll); _headData->setYaw(headYaw); _headData->setPitch(headPitch);