From c32d621d5fec4ffc2201600720b1b0b5b28e5794 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 21 May 2013 17:38:17 -0700 Subject: [PATCH] improving lookat behavior --- interface/src/Avatar.cpp | 45 +++++++++++++++++++++--------- interface/src/Head.cpp | 40 ++++++++++++++++++++++++++ interface/src/Head.h | 4 ++- libraries/avatars/src/HeadData.cpp | 1 + 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 9ca648a44a..a83d8f44c2 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -20,6 +20,10 @@ #include #include +//test +static glm::vec3 headLean(0.0f, 0.0f, 0.0f); + + using namespace std; const bool BALLS_ON = false; @@ -51,6 +55,11 @@ const float PERIPERSONAL_RADIUS = 1.0f; const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; +const float LEAN_SENSITIVITY = 0.15; +const float LEAN_MAX = 0.45; +const float LEAN_AVERAGING = 10.0; +const float HEAD_RATE_MAX = 50.f; + float skinColor [] = {1.0, 0.84, 0.66}; float darkSkinColor[] = {0.9, 0.78, 0.63}; float lightBlue [] = {0.7, 0.8, 1.0 }; @@ -134,16 +143,12 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa _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(_head.getPitch(), _head.getYaw(), _head.getRoll()); - float headRateMax = 50.f; glm::vec3 leaning = (serialInterface->getLastAcceleration() - serialInterface->getGravity()) * LEAN_SENSITIVITY - * (1.f - fminf(glm::length(headRotationRates), headRateMax) / headRateMax); + * (1.f - fminf(glm::length(headRotationRates), HEAD_RATE_MAX) / HEAD_RATE_MAX); leaning.y = 0.f; if (glm::length(leaning) < LEAN_MAX) { _head.setLeanForward(_head.getLeanForward() * (1.f - LEAN_AVERAGING * deltaTime) + @@ -364,11 +369,27 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { //apply the head lean values to the springy position... if (fabs(_head.getLeanSideways() + _head.getLeanForward()) > 0.0f) { + glm::vec3 headLean = _orientation.getRight() * _head.getLeanSideways() + _orientation.getFront() * _head.getLeanForward(); + + /* + glm::vec3 leanForce = + _orientation.getRight() * _head.getLeanSideways() + + _orientation.getFront() * _head.getLeanForward() * 10.0f; + + float magnitude = 1.0f * deltaTime; + if (magnitude > 1.0f ) { + headLean = leanForce; + } else { + headLean += (leanForce - headLean ) * magnitude; + } + */ + // this is not a long-term solution, but it works ok for initial purposes of making the avatar lean + _joint[ AVATAR_JOINT_TORSO ].springyPosition += headLean * 0.1f; _joint[ AVATAR_JOINT_CHEST ].springyPosition += headLean * 0.4f; _joint[ AVATAR_JOINT_NECK_BASE ].springyPosition += headLean * 0.7f; @@ -385,17 +406,15 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _joint[ AVATAR_JOINT_RIGHT_ELBOW ].springyPosition += headLean * 0.2f; _joint[ AVATAR_JOINT_RIGHT_WRIST ].springyPosition += headLean * 0.1f; _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; - } + } // set head lookat position - if (_interactingOther) { - _head.setLooking(true); - - if (_isMine) { - _head.setLookAtPosition(_interactingOther->getSpringyHeadPosition()); - } + if ((_interactingOther) + && (_isMine)) { + _head.setLookAtPosition(_interactingOther->getSpringyHeadPosition()); } else { - _head.setLooking(false); + _head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); + //_head.setLooking(false); } _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 4e224bad03..989299a474 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -46,6 +46,7 @@ Head::Head() : _returnSpringScale(1.0f), _bodyRotation(0.0f, 0.0f, 0.0f), _headRotation(0.0f, 0.0f, 0.0f) { + _lookingAtSomething = false; } void Head::reset() { @@ -99,6 +100,7 @@ void Head::simulate(float deltaTime, bool isMine) { } +/* void Head::setLooking(bool looking) { _lookingAtSomething = looking; @@ -111,8 +113,45 @@ void Head::setLooking(bool looking) { _lookingAtSomething = false; } } + */ +void Head::setLookAtPosition(const glm::vec3& lookAtPosition) { + + _lookAtPosition = lookAtPosition; + + if ( fabs(lookAtPosition.x + lookAtPosition.y + lookAtPosition.z) == 0.0 ) { // a lookatPosition of 0,0,0 signifies NOT looking + _lookingAtSomething = false; + } else { + _lookingAtSomething = true; + } + + glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - averageEyePosition); + float dot = glm::dot(targetLookatAxis, _orientation.getFront()); + if (dot < MINIMUM_EYE_ROTATION) { + _lookingAtSomething = false; + } + + +/* + if ( fabs(lookAtPosition.x + lookAtPosition.y + lookAtPosition.z) == 0.0 ) { // a lookatPosition of 0,0,0 signifies NOT looking + _lookingAtSomething = false; + } else { + glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; + glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - averageEyePosition); + float dot = glm::dot(targetLookatAxis, _orientation.getFront()); + if (dot < MINIMUM_EYE_ROTATION) { + _lookingAtSomething = false; + } else { + _lookAtPosition = lookAtPosition; + _lookingAtSomething = true; + } + } + */ + +} + void Head::calculateGeometry(bool lookingInMirror) { @@ -405,6 +444,7 @@ void Head::renderEyeBalls() { float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP); glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations + } else { //rotate the eyeball to aim straight ahead diff --git a/interface/src/Head.h b/interface/src/Head.h index 35f8c8e083..11843f0b15 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -31,7 +31,7 @@ public: void simulate(float deltaTime, bool isMine); void render(bool lookingInMirror); - void setLooking(bool looking); + //void setLooking(bool looking); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } @@ -43,6 +43,8 @@ public: void setAverageLoudness(float averageLoudness ) { _averageLoudness = averageLoudness; } void setAudioLoudness (float audioLoudness ) { _audioLoudness = audioLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } + + void setLookAtPosition (const glm::vec3& lookAtPosition); // overrides method in HeadData const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) float getAverageLoudness() {return _averageLoudness;}; diff --git a/libraries/avatars/src/HeadData.cpp b/libraries/avatars/src/HeadData.cpp index e7d6cee46a..9c01346152 100644 --- a/libraries/avatars/src/HeadData.cpp +++ b/libraries/avatars/src/HeadData.cpp @@ -31,6 +31,7 @@ void HeadData::addRoll(float roll) { setRoll(_roll + roll); } + void HeadData::addLean(float sideways, float forwards) { // Add lean as impulse _leanSideways += sideways;