diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7d21cdcaa0..5f6de04180 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -297,6 +297,7 @@ void Application::paintGL() { -_myAvatar.getHeadPitch(), _myAvatar.getHeadRoll()); } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + _myCamera.setTightness (100.0f); _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); _myCamera.setTargetRotation(_myAvatar.getBodyYaw() - 180.0f, 0.0f, @@ -306,13 +307,15 @@ void Application::paintGL() { if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { _myCamera.setTargetPosition(_myAvatar.getSpringyHeadPosition()); _myCamera.setTargetRotation(_myAvatar.getAbsoluteHeadYaw(), - -_myAvatar.getAbsoluteHeadPitch(), + 0.0f, + //-_myAvatar.getAbsoluteHeadPitch(), 0.0f); } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { _myCamera.setTargetPosition(_myAvatar.getHeadPosition()); _myCamera.setTargetRotation(_myAvatar.getBodyYaw(), - -_myAvatar.getAbsoluteHeadPitch(), + 0.0f, + //-_myAvatar.getAbsoluteHeadPitch(), 0.0f); } } diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bb70f230a9..909a3d912f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -3,8 +3,7 @@ // interface // // Created by Philip Rosedale on 9/11/12. -// adapted by Jeffrey Ventrella -// Copyright (c) 2013 Physical, Inc.. All rights reserved. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. #include #include @@ -18,6 +17,7 @@ #include #include #include +#include using namespace std; @@ -29,8 +29,6 @@ const float THRUST_MAG = 1200.0; const float YAW_MAG = 500.0; const float BODY_SPIN_FRICTION = 5.0; const float BODY_UPRIGHT_FORCE = 10.0; -const float BODY_PITCH_WHILE_WALKING = 40.0; -const float BODY_ROLL_WHILE_TURNING = 0.1; const float VELOCITY_DECAY = 5.0; const float MY_HAND_HOLDING_PULL = 0.2; const float YOUR_HAND_HOLDING_PULL = 1.0; @@ -48,9 +46,8 @@ const float HEAD_MAX_PITCH = 45; const float HEAD_MIN_PITCH = -45; const float HEAD_MAX_YAW = 85; const float HEAD_MIN_YAW = -85; -const float AVATAR_BRAKING_RANGE = 1.6f; -const float AVATAR_BRAKING_STRENGTH = 30.0f; -//const float MAX_JOINT_TOUCH_DOT = 0.995f; +const float PERIPERSONAL_RADIUS = 1.0f; +const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; float skinColor [] = {1.0, 0.84, 0.66}; @@ -92,6 +89,7 @@ Avatar::Avatar(bool isMine) { _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; @@ -107,14 +105,14 @@ Avatar::Avatar(bool isMine) { initializeSkeleton(); - _avatarTouch.setReachableRadius(0.6); + _avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS); if (BALLS_ON) { _balls = new Balls(100); } else { _balls = NULL; } } -Avatar::Avatar(const Avatar &otherAvatar) { - +Avatar::Avatar(const Avatar &otherAvatar) :_head(otherAvatar._head) { //include the copy constructor for head + _velocity = otherAvatar._velocity; _thrust = otherAvatar._thrust; _rotation = otherAvatar._rotation; @@ -148,55 +146,10 @@ Avatar::Avatar(const Avatar &otherAvatar) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) _driveKeys[i] = otherAvatar._driveKeys[i]; - _head.pupilSize = otherAvatar._head.pupilSize; - _head.interPupilDistance = otherAvatar._head.interPupilDistance; - _head.interBrowDistance = otherAvatar._head.interBrowDistance; - _head.nominalPupilSize = otherAvatar._head.nominalPupilSize; - _head.yawRate = otherAvatar._head.yawRate; - _head.pitchRate = otherAvatar._head.pitchRate; - _head.rollRate = otherAvatar._head.rollRate; - _head.eyebrowPitch[0] = otherAvatar._head.eyebrowPitch[0]; - _head.eyebrowPitch[1] = otherAvatar._head.eyebrowPitch[1]; - _head.eyebrowRoll [0] = otherAvatar._head.eyebrowRoll [0]; - _head.eyebrowRoll [1] = otherAvatar._head.eyebrowRoll [1]; - _head.mouthPitch = otherAvatar._head.mouthPitch; - _head.mouthYaw = otherAvatar._head.mouthYaw; - _head.mouthWidth = otherAvatar._head.mouthWidth; - _head.mouthHeight = otherAvatar._head.mouthHeight; - _head.eyeballPitch[0] = otherAvatar._head.eyeballPitch[0]; - _head.eyeballPitch[1] = otherAvatar._head.eyeballPitch[1]; - _head.eyeballScaleX = otherAvatar._head.eyeballScaleX; - _head.eyeballScaleY = otherAvatar._head.eyeballScaleY; - _head.eyeballScaleZ = otherAvatar._head.eyeballScaleZ; - _head.eyeballYaw[0] = otherAvatar._head.eyeballYaw[0]; - _head.eyeballYaw[1] = otherAvatar._head.eyeballYaw[1]; - _head.pitchTarget = otherAvatar._head.pitchTarget; - _head.yawTarget = otherAvatar._head.yawTarget; - _head.noiseEnvelope = otherAvatar._head.noiseEnvelope; - _head.pupilConverge = otherAvatar._head.pupilConverge; - _head.leanForward = otherAvatar._head.leanForward; - _head.leanSideways = otherAvatar._head.leanSideways; - _head.eyeContact = otherAvatar._head.eyeContact; - _head.eyeContactTarget = otherAvatar._head.eyeContactTarget; - _head.scale = otherAvatar._head.scale; - _head.audioAttack = otherAvatar._head.audioAttack; - _head.averageLoudness = otherAvatar._head.averageLoudness; - _head.lastLoudness = otherAvatar._head.lastLoudness; - _head.browAudioLift = otherAvatar._head.browAudioLift; - _head.noise = otherAvatar._head.noise; _distanceToNearestAvatar = otherAvatar._distanceToNearestAvatar; initializeSkeleton(); -/* - if (iris_texture.size() == 0) { - switchToResourcesParentIfRequired(); - unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file); - if (error != 0) { - printLog("error %u: %s\n", error, lodepng_error_text(error)); - } - } -*/ } Avatar::~Avatar() { @@ -333,8 +286,12 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree void Avatar::simulate(float deltaTime) { //figure out if the mouse cursor is over any body spheres... - checkForMouseRayTouching(); - + if (_isMine) { + checkForMouseRayTouching(); + } + // copy velocity so we can use it later for acceleration + glm::vec3 oldVelocity = getVelocity(); + // update balls if (_balls) { _balls->simulate(deltaTime); } @@ -403,10 +360,12 @@ void Avatar::simulate(float deltaTime) { // add thrust to velocity _velocity += _thrust * deltaTime; - // calculate speed + // calculate speed _speed = glm::length(_velocity); //pitch and roll the body as a function of forward speed and turning delta + const float BODY_PITCH_WHILE_WALKING = 20.0; + const float BODY_ROLL_WHILE_TURNING = 0.2; float forwardComponentOfVelocity = glm::dot(_orientation.getFront(), _velocity); _bodyPitch += BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity; _bodyRoll += BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta; @@ -432,8 +391,8 @@ void Avatar::simulate(float deltaTime) { } // If another avatar is near, dampen velocity as a function of closeness - if (_isMine && (_distanceToNearestAvatar < AVATAR_BRAKING_RANGE)) { - float closeness = 1.0f - (_distanceToNearestAvatar / AVATAR_BRAKING_RANGE); + if (_isMine && (_distanceToNearestAvatar < PERIPERSONAL_RADIUS)) { + float closeness = 1.0f - (_distanceToNearestAvatar / PERIPERSONAL_RADIUS); float drag = 1.0f - closeness * AVATAR_BRAKING_STRENGTH * deltaTime; if ( drag > 0.0f ) { _velocity *= drag; @@ -442,9 +401,15 @@ void Avatar::simulate(float deltaTime) { } } + // Compute instantaneous acceleration + float acceleration = glm::distance(getVelocity(), oldVelocity) / deltaTime; + const float ACCELERATION_PITCH_DECAY = 0.4f; - - + // 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)); + } // Get head position data from network for other people if (!_isMine) { @@ -477,7 +442,6 @@ void Avatar::simulate(float deltaTime) { _joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition += headLean * 0.0f; } - // update head state _head.setPositionRotationAndScale( _joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition, @@ -485,6 +449,17 @@ void Avatar::simulate(float deltaTime) { _joint[ AVATAR_JOINT_HEAD_BASE ].radius ); + _head.setBodyYaw(_bodyYaw); + + //the following is still being prototyped (making the eyes look at a specific location), it should be finished by 5/20/13 + if (_interactingOther) { + _head.setLooking(true); + _head.setLookatPosition(_interactingOther->getSpringyHeadPosition()); +//_head.setLookatPosition(_interactingOther->getApproximateEyePosition()); + } else { + _head.setLooking(false); + } + _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, _isMine); @@ -533,10 +508,11 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { if (_isMine) { _avatarTouch.setMyBodyPosition(_position); - - Avatar * _interactingOther = NULL; + float closestDistance = std::numeric_limits::max(); - + + _interactingOther = NULL; + //loop through all the other avatars for potential interactions... AgentList* agentList = AgentList::getInstance(); for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { @@ -553,12 +529,16 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { float distance = glm::length(v); if (distance < closestDistance) { closestDistance = distance; - _interactingOther = otherAvatar; + + if (distance < PERIPERSONAL_RADIUS) { + _interactingOther = otherAvatar; + } } } } - + if (_interactingOther) { + _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -632,10 +612,6 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } } -void Avatar::updateHead(float deltaTime) { - -} - float Avatar::getHeight() { return _height; @@ -784,6 +760,7 @@ static TextRenderer* textRenderer() { void Avatar::setGravity(glm::vec3 gravity) { _gravity = gravity; + _head.setGravity(_gravity); } void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { @@ -815,13 +792,7 @@ void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { //render body renderBody(lookingInMirror); - - /* - // render head - if (_displayingHead) { - _head.render(lookingInMirror, _bodyYaw); - } - */ + // if this is my avatar, then render my interactions with the other avatar if (_isMine) { @@ -1173,6 +1144,12 @@ const glm::vec3& Avatar::getHeadPosition() const { } +glm::vec3 Avatar::getApproximateEyePosition() { + return _head.getApproximateEyePosition(); +} + + + void Avatar::updateArmIKAndConstraints(float deltaTime) { @@ -1219,7 +1196,7 @@ void Avatar::renderBody(bool lookingInMirror) { if (b == AVATAR_JOINT_HEAD_BASE) { // the head is rendered as a special case if (_displayingHead) { - _head.render(lookingInMirror, _bodyYaw); + _head.render(lookingInMirror); } } else { @@ -1344,7 +1321,6 @@ void Avatar::processTransmitterData(unsigned char* packetData, int numBytes) { angularVelocity = glm::vec3(glm::degrees(gyrY), glm::degrees(-gyrX), glm::degrees(-gyrZ)); setHeadFromGyros(&eulerAngles, &angularVelocity, (_transmitterHz == 0.f) ? 0.f : 1.f / _transmitterHz, 1000.0); - } } // diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 11ef6a8327..18565a6db5 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -97,6 +97,7 @@ public: void setLeanForward(float dist); void setLeanSideways(float dist); void addLean(float x, float z); + glm::vec3 getApproximateEyePosition(); const glm::vec3& getHeadPosition() const ; // get the position of the avatar's rigid body head const glm::vec3& getSpringyHeadPosition() const ; // get the springy position of the avatar's head const glm::vec3& getJointPosition(AvatarJointID j) const { return _joint[j].springyPosition; }; @@ -200,12 +201,10 @@ private: glm::vec3 _mouseRayOrigin; glm::vec3 _mouseRayDirection; glm::vec3 _cameraPosition; + Avatar* _interactingOther; float _cumulativeMouseYaw; bool _isMouseTurningRight; - //AvatarJointID _jointTouched; - - // private methods... void initializeSkeleton(); void updateSkeleton(); @@ -213,7 +212,6 @@ private: void updateBodySprings( float deltaTime ); void calculateBoneLengths(); void readSensors(); - void updateHead( float deltaTime ); void updateHandMovementAndTouching(float deltaTime); void updateAvatarCollisions(float deltaTime); void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime ); diff --git a/interface/src/AvatarRenderer.cpp b/interface/src/AvatarRenderer.cpp index 26fb442447..45ce46084f 100644 --- a/interface/src/AvatarRenderer.cpp +++ b/interface/src/AvatarRenderer.cpp @@ -2,9 +2,8 @@ // AvatarRenderer.cpp // interface // -// Created by Jeffrey Ventrella // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// + #include #include #include diff --git a/interface/src/AvatarRenderer.h b/interface/src/AvatarRenderer.h index 74795eaaf9..e0e9d7bbb3 100644 --- a/interface/src/AvatarRenderer.h +++ b/interface/src/AvatarRenderer.h @@ -2,7 +2,6 @@ // AvatarRenderer.h // interface // -// Created by Jeffrey Ventrella // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // diff --git a/interface/src/AvatarTouch.cpp b/interface/src/AvatarTouch.cpp index 170693b8f9..7651a0a9a8 100644 --- a/interface/src/AvatarTouch.cpp +++ b/interface/src/AvatarTouch.cpp @@ -2,9 +2,8 @@ // AvatarTouch.cpp // interface // -// Created by Jeffrey Ventrella // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// + #include #include #include diff --git a/interface/src/AvatarTouch.h b/interface/src/AvatarTouch.h index d988447045..2111c0ecf1 100644 --- a/interface/src/AvatarTouch.h +++ b/interface/src/AvatarTouch.h @@ -2,7 +2,6 @@ // AvatarTouch.h // interface // -// Created by Jeffrey Ventrella // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 14eeace22c..4cba3cc66e 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -1,9 +1,8 @@ -//--------------------------------------------------------------------- // -// Created by Jeffrey Ventrella for High Fidelity. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// Camera.cpp +// interface // -//--------------------------------------------------------------------- +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. #include #include @@ -12,13 +11,14 @@ #include "Camera.h" -const float MODE_SHIFT_RATE = 5.0f; +const float MODE_SHIFT_RATE = 6.0f; Camera::Camera() { _needsToInitialize = true; _frustumNeedsReshape = true; + _modeShift = 0.0; _mode = CAMERA_MODE_THIRD_PERSON; _tightness = 10.0; // default _fieldOfView = 60.0; // default @@ -41,6 +41,10 @@ Camera::Camera() { _attributes[m].upShift = 0.0f; _attributes[m].distance = 0.0f; _attributes[m].tightness = 0.0f; + + _previousAttributes[m].upShift = 0.0f; + _previousAttributes[m].distance = 0.0f; + _previousAttributes[m].tightness = 0.0f; } } @@ -68,6 +72,13 @@ void Camera::generateOrientation() { // use iterative forces to keep the camera at the desired position and angle void Camera::updateFollowMode(float deltaTime) { + if (_modeShift < 1.0f) { + _modeShift += 5.0f * deltaTime; + if (_modeShift > 1.0f ) { + _modeShift = 1.0f; + } + } + // derive t from tightness float t = _tightness * deltaTime; if (t > 1.0) { @@ -106,15 +117,20 @@ void Camera::updateFollowMode(float deltaTime) { // force position towards ideal position _position += (_idealPosition - _position) * t; } - - //transition to the attributes of the current mode - _upShift += (_attributes[_mode].upShift - _upShift ) * deltaTime * MODE_SHIFT_RATE; - _distance += (_attributes[_mode].distance - _distance ) * deltaTime * MODE_SHIFT_RATE; - _tightness += (_attributes[_mode].tightness - _tightness) * deltaTime * MODE_SHIFT_RATE; + + float inverseModeShift = 1.0f - _modeShift; + _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * inverseModeShift; + _distance = _attributes[_mode].distance * _modeShift + _previousAttributes[_mode].distance * inverseModeShift; + _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * inverseModeShift; } + void Camera::setMode(CameraMode m, CameraFollowingAttributes a) { + _previousAttributes[m].upShift = _attributes[m].upShift; + _previousAttributes[m].distance = _attributes[m].distance; + _previousAttributes[m].tightness = _attributes[m].tightness; + _attributes[m].upShift = a.upShift; _attributes[m].distance = a.distance; _attributes[m].tightness = a.tightness; @@ -124,7 +140,7 @@ void Camera::setMode(CameraMode m, CameraFollowingAttributes a) { void Camera::setMode(CameraMode m) { _mode = m; - _needsToInitialize = true; + _modeShift = 0.0; } void Camera::setTargetRotation( float yaw, float pitch, float roll ) { @@ -165,6 +181,7 @@ void Camera::setEyeOffsetOrientation (const glm::quat& o) { void Camera::initialize() { _needsToInitialize = true; + _modeShift = 0.0; } // call to find out if the view frustum needs to be reshaped diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 2f3ce7f099..dd966b8448 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -1,9 +1,9 @@ -//----------------------------------------------------------- // -// Created by Jeffrey Ventrella and added as a utility -// class for High Fidelity Code base, April 2013 +// Camera.h +// interface +// +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -//----------------------------------------------------------- #ifndef __interface__camera__ #define __interface__camera__ @@ -96,8 +96,10 @@ private: float _distance; float _tightness; Orientation _orientation; + float _modeShift; CameraFollowingAttributes _attributes[NUM_CAMERA_MODES]; + CameraFollowingAttributes _previousAttributes[NUM_CAMERA_MODES]; void generateOrientation(); void updateFollowMode( float deltaTime ); diff --git a/interface/src/HandControl.cpp b/interface/src/HandControl.cpp index 1d95388dd9..596f971bd2 100644 --- a/interface/src/HandControl.cpp +++ b/interface/src/HandControl.cpp @@ -2,7 +2,6 @@ // HandControl.cpp // interface // -// Created by Jeffrey Ventrella // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // diff --git a/interface/src/HandControl.h b/interface/src/HandControl.h index 7663004fbf..b2abef48bb 100644 --- a/interface/src/HandControl.h +++ b/interface/src/HandControl.h @@ -2,7 +2,6 @@ // HandControl.h // interface // -// Created by Jeffrey Ventrella // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 8e29c683e2..7a5b62ff88 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -1,12 +1,11 @@ // // Head.cpp -// hifi -// -// Created by Jeffrey on May, 10, 2013 -// Copyright (c) 2013 Physical, Inc.. All rights reserved. +// interface // +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. #include "Head.h" +#include "Util.h" #include #include #include @@ -14,7 +13,7 @@ using namespace std; const float HEAD_MOTION_DECAY = 0.1; - +const float MINIMUM_EYE_ROTATION = 0.7f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; float _mouthColor[] = {1, 0, 0}; @@ -44,101 +43,170 @@ Head::Head() { } } +Head::Head(const Head &head) { + + yawRate = head.yawRate; + noise = head.noise; + leanForward = head.leanForward; + leanSideways = head.leanSideways; + + _sphere = NULL; + _returnHeadToCenter = head._returnHeadToCenter; + _audioLoudness = head._audioLoudness; + _skinColor = head._skinColor; + _position = head._position; + _rotation = head._rotation; + _lookatPosition = head._lookatPosition; + _leftEyePosition = head._leftEyePosition; + _rightEyePosition = head._rightEyePosition; + _yaw = head._yaw; + _pitch = head._pitch; + _roll = head._roll; + _pitchRate = head._pitchRate; + _rollRate = head._rollRate; + _eyeballPitch[0] = head._eyeballPitch[0]; + _eyeballYaw [0] = head._eyeballYaw [0]; + _eyebrowPitch[0] = head._eyebrowPitch[0]; + _eyebrowRoll [0] = head._eyebrowRoll [0]; + _eyeballPitch[1] = head._eyeballPitch[1]; + _eyeballYaw [1] = head._eyeballYaw [1]; + _eyebrowPitch[1] = head._eyebrowPitch[1]; + _eyebrowRoll [1] = head._eyebrowRoll [1]; + _eyeballScaleX = head._eyeballScaleX; + _eyeballScaleY = head._eyeballScaleY; + _eyeballScaleZ = head._eyeballScaleZ; + _interPupilDistance = head._interPupilDistance; + _interBrowDistance = head._interBrowDistance; + _nominalPupilSize = head._nominalPupilSize; + _pupilSize = head._pupilSize; + _mouthPitch = head._mouthPitch; + _mouthYaw = head._mouthYaw; + _mouthWidth = head._mouthWidth; + _mouthHeight = head._mouthHeight; + _pitchTarget = head._pitchTarget; + _yawTarget = head._yawTarget; + _noiseEnvelope = head._noiseEnvelope; + _pupilConverge = head._pupilConverge; + _scale = head._scale; + _eyeContact = head._eyeContact; + _browAudioLift = head._browAudioLift; + _eyeContactTarget = head._eyeContactTarget; + _orientation = head._orientation; + _bodyYaw = head._bodyYaw; + _lastLoudness = head._lastLoudness; + _averageLoudness = head._averageLoudness; + _audioAttack = head._audioAttack; + _looking = head._looking; + _gravity = head._gravity; + _returnSpringScale = head._returnSpringScale; +} + + + void Head::initialize() { - audioLoudness = 0.0; - skinColor = glm::vec3(0.0f, 0.0f, 0.0f); - position = glm::vec3(0.0f, 0.0f, 0.0f); - yaw = 0.0f; - pitch = 0.0f; - roll = 0.0f; - pupilSize = 0.10; - interPupilDistance = 0.6; - interBrowDistance = 0.75; - nominalPupilSize = 0.10; - pitchRate = 0.0; - yawRate = 0.0; - rollRate = 0.0; - eyebrowPitch[0] = -30; - eyebrowPitch[1] = -30; - eyebrowRoll [0] = 20; - eyebrowRoll [1] = -20; - mouthPitch = 0; - mouthYaw = 0; - mouthWidth = 1.0; - mouthHeight = 0.2; - eyeballPitch[0] = 0; - eyeballPitch[1] = 0; - eyeballScaleX = 1.2; - eyeballScaleY = 1.5; - eyeballScaleZ = 1.0; - eyeballYaw[0] = 0; - eyeballYaw[1] = 0; - pitchTarget = 0; - yawTarget = 0; - noiseEnvelope = 1.0; - pupilConverge = 10.0; - leanForward = 0.0; - leanSideways = 0.0; - eyeContact = 1; - eyeContactTarget = LEFT_EYE; - scale = 1.0; - audioAttack = 0.0; - averageLoudness = 0.0; - lastLoudness = 0.0; - browAudioLift = 0.0; - noise = 0; - returnSpringScale = 1.0; - sphere = NULL; + _bodyYaw = 0.0f; + _audioLoudness = 0.0; + _skinColor = glm::vec3(0.0f, 0.0f, 0.0f); + _position = glm::vec3(0.0f, 0.0f, 0.0f); + _lookatPosition = glm::vec3(0.0f, 0.0f, 0.0f); + _gravity = glm::vec3(0.0f, -1.0f, 0.0f); // default + _yaw = 0.0f; + _pitch = 0.0f; + _roll = 0.0f; + _pupilSize = 0.10; + _interPupilDistance = 0.6; + _interBrowDistance = 0.75; + _nominalPupilSize = 0.10; + _pitchRate = 0.0; + yawRate = 0.0; + _rollRate = 0.0; + _eyebrowPitch[0] = -30; + _eyebrowPitch[1] = -30; + _eyebrowRoll [0] = 20; + _eyebrowRoll [1] = -20; + _mouthPitch = 0; + _mouthYaw = 0; + _mouthWidth = 1.0; + _mouthHeight = 0.2; + _eyeballPitch[0] = 0; + _eyeballPitch[1] = 0; + _eyeballScaleX = 1.2; + _eyeballScaleY = 1.5; + _eyeballScaleZ = 1.0; + _eyeballYaw[0] = 0; + _eyeballYaw[1] = 0; + _pitchTarget = 0; + _yawTarget = 0; + _noiseEnvelope = 1.0; + _pupilConverge = 10.0; + leanForward = 0.0; + leanSideways = 0.0; + _eyeContact = 1; + _eyeContactTarget = LEFT_EYE; + _scale = 1.0; + _audioAttack = 0.0; + _averageLoudness = 0.0; + _lastLoudness = 0.0; + _browAudioLift = 0.0; + noise = 0; + _returnSpringScale = 1.0; + _sphere = NULL; } void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { - position = p; - scale = s; - yaw = r.x; - pitch = r.y; - roll = r.z; + _position = p; + _scale = s; + _yaw = r.x; + _pitch = r.y; + _roll = r.z; } void Head::setSkinColor(glm::vec3 c) { - skinColor = c; + _skinColor = c; } void Head::setAudioLoudness(float loudness) { - audioLoudness = loudness; + _audioLoudness = loudness; } void Head::setNewTarget(float pitch, float yaw) { - pitchTarget = pitch; - yawTarget = yaw; + _pitchTarget = pitch; + _yawTarget = yaw; } void Head::simulate(float deltaTime, bool isMine) { + //generate orientation directions based on Euler angles... + _orientation.setToPitchYawRoll( _pitch, _bodyYaw + _yaw, _roll); + + //calculate the eye positions (algorithm still being designed) + updateEyePositions(); + // Decay head back to center if turned on - if (isMine && returnHeadToCenter) { + if (isMine && _returnHeadToCenter) { // Decay back toward center - pitch *= (1.0f - HEAD_MOTION_DECAY * returnSpringScale * 2 * deltaTime); - yaw *= (1.0f - HEAD_MOTION_DECAY * returnSpringScale * 2 * deltaTime); - roll *= (1.0f - HEAD_MOTION_DECAY * returnSpringScale * 2 * deltaTime); + _pitch *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); + _yaw *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); + _roll *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); } // For invensense gyro, decay only slightly when roughly centered if (isMine) { const float RETURN_RANGE = 15.0; const float RETURN_STRENGTH = 2.0; - if (fabs(pitch) < RETURN_RANGE) { pitch *= (1.0f - RETURN_STRENGTH * deltaTime); } - if (fabs(yaw) < RETURN_RANGE) { yaw *= (1.0f - RETURN_STRENGTH * deltaTime); } - if (fabs(roll) < RETURN_RANGE) { roll *= (1.0f - RETURN_STRENGTH * deltaTime); } + if (fabs(_pitch) < RETURN_RANGE) { _pitch *= (1.0f - RETURN_STRENGTH * deltaTime); } + if (fabs(_yaw) < RETURN_RANGE) { _yaw *= (1.0f - RETURN_STRENGTH * deltaTime); } + if (fabs(_roll) < RETURN_RANGE) { _roll *= (1.0f - RETURN_STRENGTH * deltaTime); } } if (noise) { // Move toward new target - pitch += (pitchTarget - pitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; - yaw += (yawTarget - yaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime); - roll *= 1.f - (HEAD_MOTION_DECAY * deltaTime); + _pitch += (_pitchTarget - _pitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; + _yaw += (_yawTarget - _yaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime); + _roll *= 1.f - (HEAD_MOTION_DECAY * deltaTime); } leanForward *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); @@ -148,12 +216,12 @@ void Head::simulate(float deltaTime, bool isMine) { // // First, decide if we are making eye contact or not if (randFloat() < 0.005) { - eyeContact = !eyeContact; - eyeContact = 1; - if (!eyeContact) { + _eyeContact = !_eyeContact; + _eyeContact = 1; + if (!_eyeContact) { // If we just stopped making eye contact,move the eyes markedly away - eyeballPitch[0] = eyeballPitch[1] = eyeballPitch[0] + 5.0 + (randFloat() - 0.5) * 10; - eyeballYaw [0] = eyeballYaw [1] = eyeballYaw [0] + 5.0 + (randFloat() - 0.5) * 5; + _eyeballPitch[0] = _eyeballPitch[1] = _eyeballPitch[0] + 5.0 + (randFloat() - 0.5) * 10; + _eyeballYaw [0] = _eyeballYaw [1] = _eyeballYaw [0] + 5.0 + (randFloat() - 0.5) * 5; } else { // If now making eye contact, turn head to look right at viewer setNewTarget(0,0); @@ -163,65 +231,110 @@ void Head::simulate(float deltaTime, bool isMine) { const float DEGREES_BETWEEN_VIEWER_EYES = 3; const float DEGREES_TO_VIEWER_MOUTH = 7; - if (eyeContact) { + if (_eyeContact) { // Should we pick a new eye contact target? if (randFloat() < 0.01) { // Choose where to look next if (randFloat() < 0.1) { - eyeContactTarget = MOUTH; + _eyeContactTarget = MOUTH; } else { - if (randFloat() < 0.5) eyeContactTarget = LEFT_EYE; else eyeContactTarget = RIGHT_EYE; + if (randFloat() < 0.5) _eyeContactTarget = LEFT_EYE; else _eyeContactTarget = RIGHT_EYE; } } // Set eyeball pitch and yaw to make contact float eye_target_yaw_adjust = 0; float eye_target_pitch_adjust = 0; - if (eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; - if (eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; - if (eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; + if (_eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; + if (_eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; + if (_eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; - eyeballPitch[0] = eyeballPitch[1] = -pitch + eye_target_pitch_adjust; - eyeballYaw [0] = eyeballYaw [1] = yaw + eye_target_yaw_adjust; + _eyeballPitch[0] = _eyeballPitch[1] = -_pitch + eye_target_pitch_adjust; + _eyeballYaw [0] = _eyeballYaw [1] = _yaw + eye_target_yaw_adjust; } if (noise) { - pitch += (randFloat() - 0.5) * 0.2 * noiseEnvelope; - yaw += (randFloat() - 0.5) * 0.3 *noiseEnvelope; + _pitch += (randFloat() - 0.5) * 0.2 * _noiseEnvelope; + _yaw += (randFloat() - 0.5) * 0.3 *_noiseEnvelope; //PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope; - if (randFloat() < 0.005) mouthWidth = _MouthWidthChoices[rand()%3]; + if (randFloat() < 0.005) _mouthWidth = _MouthWidthChoices[rand()%3]; - if (!eyeContact) { - if (randFloat() < 0.01) eyeballPitch[0] = eyeballPitch[1] = (randFloat() - 0.5) * 20; - if (randFloat() < 0.01) eyeballYaw[0] = eyeballYaw[1] = (randFloat()- 0.5) * 10; + if (!_eyeContact) { + if (randFloat() < 0.01) _eyeballPitch[0] = _eyeballPitch[1] = (randFloat() - 0.5) * 20; + if (randFloat() < 0.01) _eyeballYaw[0] = _eyeballYaw[1] = (randFloat()- 0.5) * 10; } - if ((randFloat() < 0.005) && (fabs(pitchTarget - pitch) < 1.0) && (fabs(yawTarget - yaw) < 1.0)) { + if ((randFloat() < 0.005) && (fabs(_pitchTarget - _pitch) < 1.0) && (fabs(_yawTarget - _yaw) < 1.0)) { setNewTarget((randFloat()-0.5) * 20.0, (randFloat()-0.5) * 45.0); } if (0) { // Pick new target - pitchTarget = (randFloat() - 0.5) * 45; - yawTarget = (randFloat() - 0.5) * 22; + _pitchTarget = (randFloat() - 0.5) * 45; + _yawTarget = (randFloat() - 0.5) * 22; } if (randFloat() < 0.01) { - eyebrowPitch[0] = eyebrowPitch[1] = _BrowPitchAngle[rand()%3]; - eyebrowRoll [0] = eyebrowRoll[1] = _BrowRollAngle[rand()%5]; - eyebrowRoll [1] *=-1; + _eyebrowPitch[0] = _eyebrowPitch[1] = _BrowPitchAngle[rand()%3]; + _eyebrowRoll [0] = _eyebrowRoll[1] = _BrowRollAngle[rand()%5]; + _eyebrowRoll [1] *=-1; } } // Update audio trailing average for rendering facial animations const float AUDIO_AVERAGING_SECS = 0.05; - averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * averageLoudness + - (deltaTime / AUDIO_AVERAGING_SECS) * audioLoudness; + _averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * _averageLoudness + + (deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness; + } -void Head::render(bool lookingInMirror, float bodyYaw) { + +void Head::updateEyePositions() { + float rightShift = _scale * 0.27f; + float upShift = _scale * 0.38f; + float frontShift = _scale * 0.8f; + + _leftEyePosition = _position + + _orientation.getRight() * rightShift + + _orientation.getUp () * upShift + + _orientation.getFront() * frontShift; + _rightEyePosition = _position + - _orientation.getRight() * rightShift + + _orientation.getUp () * upShift + + _orientation.getFront() * frontShift; +} + + +void Head::setLooking(bool looking) { + + _looking = looking; + + 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) { + _looking = false; + } +} + +/* +void Head::setLookatPosition(glm::vec3 l) { + _lookatPosition = l; +} + +void Head::setGravity(glm::vec3 gravity) { + _gravity = gravity; +} +*/ + +glm::vec3 Head::getApproximateEyePosition() { + return _leftEyePosition + (_rightEyePosition - _leftEyePosition) * ONE_HALF; +} + +void Head::render(bool lookingInMirror) { int side = 0; @@ -230,22 +343,22 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glPushMatrix(); - glTranslatef(position.x, position.y, position.z); + glTranslatef(_position.x, _position.y, _position.z); - glScalef(scale, scale, scale); + glScalef(_scale, _scale, _scale); if (lookingInMirror) { - glRotatef(bodyYaw - yaw, 0, 1, 0); - glRotatef(pitch, 1, 0, 0); - glRotatef(-roll, 0, 0, 1); + glRotatef(_bodyYaw - _yaw, 0, 1, 0); + glRotatef(_pitch, 1, 0, 0); + glRotatef(-_roll, 0, 0, 1); } else { - glRotatef(bodyYaw + yaw, 0, 1, 0); - glRotatef(pitch, 1, 0, 0); - glRotatef(roll, 0, 0, 1); + glRotatef(_bodyYaw + _yaw, 0, 1, 0); + glRotatef(_pitch, 1, 0, 0); + glRotatef(_roll, 0, 0, 1); } //glScalef(2.0, 2.0, 2.0); - glColor3f(skinColor.x, skinColor.y, skinColor.z); + glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); glutSolidSphere(1, 30, 30); @@ -262,29 +375,28 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glPopMatrix(); // Update audio attack data for facial animation (eyebrows and mouth) - audioAttack = 0.9 * audioAttack + 0.1 * fabs(audioLoudness - lastLoudness); - lastLoudness = audioLoudness; - + _audioAttack = 0.9 * _audioAttack + 0.1 * fabs(_audioLoudness - _lastLoudness); + _lastLoudness = _audioLoudness; const float BROW_LIFT_THRESHOLD = 100; - if (audioAttack > BROW_LIFT_THRESHOLD) - browAudioLift += sqrt(audioAttack) / 1000.0; + if (_audioAttack > BROW_LIFT_THRESHOLD) + _browAudioLift += sqrt(_audioAttack) / 1000.0; - browAudioLift *= .90; + _browAudioLift *= .90; // Render Eyebrows glPushMatrix(); - glTranslatef(-interBrowDistance / 2.0,0.4,0.45); + glTranslatef(-_interBrowDistance / 2.0,0.4,0.45); for(side = 0; side < 2; side++) { glColor3fv(_browColor); glPushMatrix(); - glTranslatef(0, 0.35 + browAudioLift, 0); - glRotatef(eyebrowPitch[side]/2.0, 1, 0, 0); - glRotatef(eyebrowRoll[side]/2.0, 0, 0, 1); + glTranslatef(0, 0.35 + _browAudioLift, 0); + glRotatef(_eyebrowPitch[side]/2.0, 1, 0, 0); + glRotatef(_eyebrowRoll[side]/2.0, 0, 0, 1); glScalef(_browWidth, _browThickness, 1); glutSolidCube(0.5); glPopMatrix(); - glTranslatef(interBrowDistance, 0, 0); + glTranslatef(_interBrowDistance, 0, 0); } glPopMatrix(); @@ -294,87 +406,199 @@ void Head::render(bool lookingInMirror, float bodyYaw) { const float HEIGHT_SENSITIVITY = 30.f; const float MIN_LOUDNESS_SCALE_HEIGHT = 1.0f; glPushMatrix(); - glTranslatef(0,-0.35,0.75); - glColor3f(0,0,0); - glRotatef(mouthPitch, 1, 0, 0); - glRotatef(mouthYaw, 0, 0, 1); - - if ((averageLoudness > 1.f) && (averageLoudness < 10000.f)) { - glScalef(mouthWidth * (MIN_LOUDNESS_SCALE_WIDTH + sqrt(averageLoudness) / WIDTH_SENSITIVITY), - mouthHeight * (MIN_LOUDNESS_SCALE_HEIGHT + sqrt(averageLoudness) / HEIGHT_SENSITIVITY), 1); - } else { - glScalef(mouthWidth, mouthHeight, 1); - } + glTranslatef(0,-0.35,0.75); + glColor3f(0,0,0); - glutSolidCube(0.5); + glRotatef(_mouthPitch, 1, 0, 0); + glRotatef(_mouthYaw, 0, 0, 1); + + if (_averageLoudness > 1.f) { + glScalef(_mouthWidth * (.7f + sqrt(_averageLoudness) /60.f), + _mouthHeight * (1.f + sqrt(_averageLoudness) /30.f), 1); + } else { + glScalef(_mouthWidth, _mouthHeight, 1); + } + + glutSolidCube(0.5); + glPopMatrix(); + + // the original code from Philip's implementation + //previouseRenderEyeBalls(); + + glPopMatrix(); + + //a new version of eyeballs that has the ability to look at specific targets in the world (algo still not finished yet) + renderEyeBalls(); + + if (_looking) { + // Render lines originating from the eyes and converging on the lookatPosition + debugRenderLookatVectors(_leftEyePosition, _rightEyePosition, _lookatPosition); + } +} + + + + +void Head::renderEyeBalls() { + + //make the texture for the iris... + if (_sphere == NULL) { + _sphere = gluNewQuadric(); + gluQuadricTexture(_sphere, GL_TRUE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gluQuadricOrientation(_sphere, GLU_OUTSIDE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]); + } + + // left eyeball + glPushMatrix(); + glColor3fv(_eyeColor); + glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); + gluSphere(_sphere, 0.02, 30, 30); glPopMatrix(); + // left iris + glPushMatrix(); { + glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); + glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _leftEyePosition); + + if (!_looking) { + targetLookatAxis = _orientation.getFront(); + } + + glPushMatrix(); + glm::vec3 rotationAxis = glm::cross(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); + float angle = 180.0f - angleBetween(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); + glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); + glTranslatef( 0.0f, -0.018f, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) + glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris + glEnable(GL_TEXTURE_2D); + gluSphere(_sphere, 0.007, 15, 15); + glDisable(GL_TEXTURE_2D); + glPopMatrix(); + } + glPopMatrix(); + + //right eyeball + glPushMatrix(); + glColor3fv(_eyeColor); + glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); + gluSphere(_sphere, 0.02, 30, 30); + glPopMatrix(); + + //right iris + glPushMatrix(); { + glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); + glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _rightEyePosition); + + if (!_looking) { + targetLookatAxis = _orientation.getFront(); + } + + glPushMatrix(); + glm::vec3 rotationAxis = glm::cross(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); + float angle = 180.0f - angleBetween(targetLookatAxis, glm::vec3(0.0f, 1.0f, 0.0f)); + glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z); + glTranslatef( 0.0f, -0.018f, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!) + glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris + glEnable(GL_TEXTURE_2D); + gluSphere(_sphere, 0.007, 15, 15); + glDisable(GL_TEXTURE_2D); + glPopMatrix(); + } + glPopMatrix(); +} + + + + + +void Head::previouseRenderEyeBalls() { + glTranslatef(0, 1.0, 0); - - glTranslatef(-interPupilDistance/2.0,-0.68,0.7); + + glTranslatef(-_interPupilDistance/2.0,-0.68,0.7); // Right Eye glRotatef(-10, 1, 0, 0); glColor3fv(_eyeColor); glPushMatrix(); { - glTranslatef(interPupilDistance/10.0, 0, 0.05); + glTranslatef(_interPupilDistance/10.0, 0, 0.05); glRotatef(20, 0, 0, 1); - glScalef(eyeballScaleX, eyeballScaleY, eyeballScaleZ); + glScalef(_eyeballScaleX, _eyeballScaleY, _eyeballScaleZ); glutSolidSphere(0.25, 30, 30); } glPopMatrix(); // Right Pupil - if (sphere == NULL) { - sphere = gluNewQuadric(); - gluQuadricTexture(sphere, GL_TRUE); + if (_sphere == NULL) { + _sphere = gluNewQuadric(); + gluQuadricTexture(_sphere, GL_TRUE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gluQuadricOrientation(sphere, GLU_OUTSIDE); + gluQuadricOrientation(_sphere, GLU_OUTSIDE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]); } - + glPushMatrix(); { - glRotatef(eyeballPitch[1], 1, 0, 0); - glRotatef(eyeballYaw[1] + yaw + pupilConverge, 0, 1, 0); + glRotatef(_eyeballPitch[1], 1, 0, 0); + glRotatef(_eyeballYaw[1] + _yaw + _pupilConverge, 0, 1, 0); glTranslatef(0,0,.35); glRotatef(-75,1,0,0); glScalef(1.0, 0.4, 1.0); glEnable(GL_TEXTURE_2D); - gluSphere(sphere, pupilSize, 15, 15); + gluSphere(_sphere, _pupilSize, 15, 15); glDisable(GL_TEXTURE_2D); - } - + } glPopMatrix(); + + // Left Eye glColor3fv(_eyeColor); - glTranslatef(interPupilDistance, 0, 0); + glTranslatef(_interPupilDistance, 0, 0); glPushMatrix(); { - glTranslatef(-interPupilDistance/10.0, 0, .05); + glTranslatef(-_interPupilDistance/10.0, 0, .05); glRotatef(-20, 0, 0, 1); - glScalef(eyeballScaleX, eyeballScaleY, eyeballScaleZ); + glScalef(_eyeballScaleX, _eyeballScaleY, _eyeballScaleZ); glutSolidSphere(0.25, 30, 30); } glPopMatrix(); + // Left Pupil glPushMatrix(); { - glRotatef(eyeballPitch[0], 1, 0, 0); - glRotatef(eyeballYaw[0] + yaw - pupilConverge, 0, 1, 0); + glRotatef(_eyeballPitch[0], 1, 0, 0); + glRotatef(_eyeballYaw[0] + _yaw - _pupilConverge, 0, 1, 0); glTranslatef(0, 0, .35); glRotatef(-75, 1, 0, 0); glScalef(1.0, 0.4, 1.0); glEnable(GL_TEXTURE_2D); - gluSphere(sphere, pupilSize, 15, 15); + gluSphere(_sphere, _pupilSize, 15, 15); glDisable(GL_TEXTURE_2D); } glPopMatrix(); - - glPopMatrix(); - } + + +void Head::debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { + + glColor3f(0.0f, 0.0f, 0.0f); + glLineWidth(3.0); + glBegin(GL_LINE_STRIP); + glVertex3f(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z); + glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z); + glEnd(); + glBegin(GL_LINE_STRIP); + glVertex3f(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z); + glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z); + glEnd(); +} + + + diff --git a/interface/src/Head.h b/interface/src/Head.h index 3d345d5140..209ef0704d 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -1,9 +1,8 @@ // // Head.h -// hifi +// interface // -// Created by Jeffrey on May, 10, 2013 -// Copyright (c) 2013 Physical, Inc.. All rights reserved. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // #ifndef hifi_Head_h @@ -15,6 +14,7 @@ #include "world.h" #include "InterfaceConfig.h" #include "SerialInterface.h" +#include "Orientation.h" enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; @@ -22,72 +22,97 @@ class Head { public: Head(); + Head(const Head &otherHead); + void initialize(); void simulate(float deltaTime, bool isMine); void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale); void setSkinColor(glm::vec3 color); void setAudioLoudness(float loudness); - void render(bool lookingInMirror, float bodyYaw); + void render(bool lookingInMirror); void setNewTarget(float, float); - void setSpringScale(float s) { returnSpringScale = s; } + void setSpringScale(float s) { _returnSpringScale = s; } + void setLookatPosition(glm::vec3 l ) { _lookatPosition = l; } + void setLooking(bool looking); + void setGravity(glm::vec3 gravity) { _gravity = gravity; } + void setBodyYaw(float y) { _bodyYaw = y; } + + glm::vec3 getApproximateEyePosition(); // Do you want head to try to return to center (depends on interface detected) - void setReturnToCenter(bool r) { returnHeadToCenter = r; } - const bool getReturnToCenter() const { return returnHeadToCenter; } + void setReturnToCenter(bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } + const bool getReturnToCenter() const { return _returnHeadToCenter; } - float getAverageLoudness() {return averageLoudness;}; - void setAverageLoudness(float al) { averageLoudness = al;}; + float getAverageLoudness() {return _averageLoudness;}; + void setAverageLoudness(float al) { _averageLoudness = al;}; + + float yawRate; + float noise; + float leanForward; + float leanSideways; + +private: + + bool _returnHeadToCenter; + float _audioLoudness; + glm::vec3 _skinColor; + glm::vec3 _position; + glm::vec3 _rotation; + glm::vec3 _lookatPosition; -//private: -// I am making these public for now - just to get the code moved over quickly! + glm::vec3 _leftEyePosition; + glm::vec3 _rightEyePosition; + + float _yaw; + float _pitch; + float _roll; + float _pitchRate; + float _rollRate; + float _eyeballPitch[2]; + float _eyeballYaw [2]; + float _eyebrowPitch[2]; + float _eyebrowRoll [2]; + float _eyeballScaleX; + float _eyeballScaleY; + float _eyeballScaleZ; + float _interPupilDistance; + float _interBrowDistance; + float _nominalPupilSize; + float _pupilSize; + float _mouthPitch; + float _mouthYaw; + float _mouthWidth; + float _mouthHeight; + float _pitchTarget; + float _yawTarget; + float _noiseEnvelope; + float _pupilConverge; + float _scale; + int _eyeContact; + float _browAudioLift; + eyeContactTargets _eyeContactTarget; + Orientation _orientation; + float _bodyYaw; + + // Sound loudness information + float _lastLoudness; + float _averageLoudness; + float _audioAttack; + + bool _looking; + glm::vec3 _gravity; - bool returnHeadToCenter; - float audioLoudness; - glm::vec3 skinColor; - glm::vec3 position; - glm::vec3 rotation; - float yaw; - float pitch; - float roll; - float pitchRate; - float yawRate; - float rollRate; - float noise; - float eyeballPitch[2]; - float eyeballYaw [2]; - float eyebrowPitch[2]; - float eyebrowRoll [2]; - float eyeballScaleX; - float eyeballScaleY; - float eyeballScaleZ; - float interPupilDistance; - float interBrowDistance; - float nominalPupilSize; - float pupilSize; - float mouthPitch; - float mouthYaw; - float mouthWidth; - float mouthHeight; - float leanForward; - float leanSideways; - float pitchTarget; - float yawTarget; - float noiseEnvelope; - float pupilConverge; - float scale; - int eyeContact; - float browAudioLift; - eyeContactTargets eyeContactTarget; - - // Sound loudness information - float lastLoudness; - float averageLoudness; - float audioAttack; - - GLUquadric* sphere; + + GLUquadric* _sphere; - // Strength of return springs - float returnSpringScale; + // Strength of return springs + float _returnSpringScale; + + // private methods + void previouseRenderEyeBalls(); + void renderEyeBalls(); + void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); + void updateEyePositions(); }; #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 669e64abc1..58bad2db2f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1,28 +1,28 @@ -// -// Interface -// -// Allows you to connect to and see/hear the shared 3D space. -// Optionally uses serialUSB connection to get gyro data for head movement. -// Optionally gets UDP stream from transmitter to animate controller/hand. -// -// Usage: The interface client first attempts to contact a domain server to -// discover the appropriate audio, voxel, and avatar servers to contact. -// Right now, the default domain server is "highfidelity.below92.com" -// You can change the domain server to use your own by editing the -// DOMAIN_HOSTNAME or DOMAIN_IP strings in the file AgentList.cpp -// -// -// Welcome Aboard! -// - -#include "Application.h" -#include "Log.h" - -int main(int argc, const char * argv[]) { - - Application app(argc, const_cast(argv)); - printLog( "Created QT Application.\n" ); - int exitCode = app.exec(); - printLog("Normal exit.\n"); - return exitCode; -} +// +// Interface +// +// Allows you to connect to and see/hear the shared 3D space. +// Optionally uses serialUSB connection to get gyro data for head movement. +// Optionally gets UDP stream from transmitter to animate controller/hand. +// +// Usage: The interface client first attempts to contact a domain server to +// discover the appropriate audio, voxel, and avatar servers to contact. +// Right now, the default domain server is "highfidelity.below92.com" +// You can change the domain server to use your own by editing the +// DOMAIN_HOSTNAME or DOMAIN_IP strings in the file AgentList.cpp +// +// +// Welcome Aboard! +// + +#include "Application.h" +#include "Log.h" + +int main(int argc, const char * argv[]) { + + Application app(argc, const_cast(argv)); + printLog( "Created QT Application.\n" ); + int exitCode = app.exec(); + printLog("Normal exit.\n"); + return exitCode; +} diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp index 447739c32c..6466eb802c 100755 --- a/libraries/avatars/src/Orientation.cpp +++ b/libraries/avatars/src/Orientation.cpp @@ -25,6 +25,15 @@ void Orientation::setToIdentity() { front = glm::vec3(IDENTITY_FRONT); } +void Orientation::setToPitchYawRoll(float pitch_change, float yaw_change, float roll_change) { + + setToIdentity(); + pitch(pitch_change); + yaw (yaw_change); + roll (roll_change); +} + + void Orientation::set(Orientation o) { quat = o.quat; @@ -93,10 +102,10 @@ void Orientation::roll(float angle) { } } -void Orientation::rotate(float p, float y, float r) { - pitch(p); - yaw (y); - roll (r); +void Orientation::rotate(float pitch_change, float yaw_change, float roll_change) { + pitch(pitch_change); + yaw (yaw_change); + roll (roll_change); } void Orientation::rotate(glm::vec3 eulerAngles) { diff --git a/libraries/avatars/src/Orientation.h b/libraries/avatars/src/Orientation.h index 4bf487be02..82d6edc9e5 100755 --- a/libraries/avatars/src/Orientation.h +++ b/libraries/avatars/src/Orientation.h @@ -22,11 +22,12 @@ public: Orientation(); void set(Orientation); + void setToPitchYawRoll(float pitch_change, float yaw_change, float roll_change); void setToIdentity(); - void pitch(float p); - void yaw (float y); - void roll (float r); + void pitch(float pitch_change); + void yaw (float yaw_change); + void roll (float roll_change); void rotate(float pitch, float yaw, float roll); void rotate(glm::vec3 EulerAngles);