From 72f8f447a1e3a05f64c718070479228ede2f4641 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 17:30:13 -0700 Subject: [PATCH 1/4] starting a rework of Head renderer --- interface/src/Avatar.cpp | 64 ++++++++++---------- interface/src/Head.cpp | 128 +++++++++++++++++++++++++++------------ interface/src/Head.h | 24 +++++--- 3 files changed, 134 insertions(+), 82 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index befedcf524..17b656d314 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -51,7 +51,7 @@ const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; float skinColor [] = {1.0, 0.84, 0.66}; -float darkSkinColor[] = {0.8, 0.74, 0.6 }; +float darkSkinColor[] = {0.9, 0.78, 0.63}; float lightBlue [] = {0.7, 0.8, 1.0 }; bool usingBigSphereCollisionTest = true; @@ -232,7 +232,8 @@ 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... - if (_isMine) { + //if (_isMine) { + { checkForMouseRayTouching(); } // copy velocity so we can use it later for acceleration @@ -388,15 +389,8 @@ 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, - glm::vec3(_headYaw, _headPitch, _headRoll), - _joint[ AVATAR_JOINT_HEAD_BASE ].radius - ); - + // set head lookat position setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 - if (_interactingOther) { _head.setLooking(true); @@ -407,8 +401,14 @@ void Avatar::simulate(float deltaTime) { _head.setLooking(false); } - _head.setBodyYaw(_bodyYaw); - _head.setLookatPosition(_lookatPosition); + _head.setLookatPosition(_lookatPosition); // this comes from Avatar Data + _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); + _head.setRotationOffBody(glm::vec3(_headPitch, _headYaw, _headRoll)); + + //_head.setRotationOffBody(glm::vec3(0.0f, 0.0f, 0.0f)); + + _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); + _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, _isMine); @@ -1054,10 +1054,6 @@ const glm::vec3& Avatar::getHeadPosition() const { return _joint[ AVATAR_JOINT_HEAD_BASE ].position; } -glm::vec3 Avatar::getApproximateEyePosition() { - return _head.getApproximateEyePosition(); -} - void Avatar::updateArmIKAndConstraints(float deltaTime) { // determine the arm vector @@ -1134,19 +1130,17 @@ void Avatar::renderBody(bool lookingInMirror) { if (_joint[b].parent != AVATAR_JOINT_NULL) if (b != AVATAR_JOINT_HEAD_TOP) { - /* // Render cone sections connecting the joint positions glColor3fv(darkSkinColor); renderJointConnectingCone ( _joint[_joint[b].parent ].springyPosition, _joint[b ].springyPosition, - _joint[_joint[b].parent ].radius, - _joint[b ].radius + _joint[_joint[b].parent ].radius * 0.8, + _joint[b ].radius * 0.8 ); - */ - + /* // Render lines connecting the joint positions glColor3f(0.4f, 0.5f, 0.6f); glLineWidth(3.0); @@ -1154,6 +1148,7 @@ void Avatar::renderBody(bool lookingInMirror) { glVertex3fv(&_joint[ _joint[ b ].parent ].springyPosition.x); glVertex3fv(&_joint[ b ].springyPosition.x); glEnd(); + */ } } } @@ -1388,11 +1383,12 @@ void Avatar::readAvatarDataFromFile() { } } +// render a makeshift cone section that serves as a body part connecting joint spheres void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) { glBegin(GL_TRIANGLES); - int num = 5; + int num = 10; glm::vec3 axis = glm::normalize(position2 - position1); float length = glm::length(axis); @@ -1402,26 +1398,30 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, glm::vec3 perpSin = glm::vec3(axis.y, axis.z, axis.x); glm::vec3 perpCos = glm::vec3(axis.z, axis.x, axis.y); + float angle1 = 0.0; + float angle2 = 0.0; + for (int i = 0; i < num; i ++) { - float angle1 = ((float)i / (float)num) * PI * 2.0; - float angle2 = ((float)(i+1) / (float)num) * PI * 2.0; + angle1 = angle2; + angle2 = ((float)(i+1) / (float)num) * PI * 2.0; + + float s1 = sin(angle1); + float s2 = sin(angle2); + float c1 = cos(angle1); + float c2 = cos(angle2); - glm::vec3 p1a = position1 + perpSin * sin(angle1) * radius1; - glm::vec3 p1b = position1 + perpCos * cos(angle2) * radius1; + glm::vec3 p1a = position1 + perpSin * s1 * radius1 + perpCos * c1 * radius1; + glm::vec3 p1b = position1 + perpSin * s2 * radius1 + perpCos * c2 * radius1; + glm::vec3 p2a = position2 + perpSin * s1 * radius2 + perpCos * c1 * radius2; + glm::vec3 p2b = position2 + perpSin * s2 * radius2 + perpCos * c2 * radius2; - glm::vec3 p2a = position2 + perpSin * sin(angle1) * radius2; - glm::vec3 p2b = position2 + perpCos * cos(angle2) * radius2; - glVertex3f(p1a.x, p1a.y, p1a.z); glVertex3f(p1b.x, p1b.y, p1b.z); glVertex3f(p2a.x, p2a.y, p2a.z); - - /* glVertex3f(p1b.x, p1b.y, p1b.z); glVertex3f(p2a.x, p2a.y, p2a.z); glVertex3f(p2b.x, p2b.y, p2b.z); - */ } } diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 3b751651b2..823135d449 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -46,9 +46,9 @@ 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), + //_yaw(0.0f), + //_pitch(0.0f), + //_roll(0.0f), _eyeballPitch(), _eyeballYaw(), _interBrowDistance(0.75f), @@ -56,8 +56,8 @@ Head::Head() : _mouthYaw(0), _mouthWidth(1.0f), _mouthHeight(0.2f), - _pitchTarget(0.0f), - _yawTarget(0.0f), + //_pitchTarget(0.0f), + //_yawTarget(0.0f), _noiseEnvelope(1.0f), _scale(1.0f), _eyeContact(1), @@ -67,7 +67,8 @@ Head::Head() : _averageLoudness(0.0f), _audioAttack(0.0f), _returnSpringScale(1.0f), - _bodyYaw(0.0f), + _bodyRotation(0.0f, 0.0f, 0.0f), + _headRotation(0.0f, 0.0f, 0.0f), _eyeContactTarget(LEFT_EYE) { _eyebrowPitch[0] = -30; @@ -76,24 +77,30 @@ Head::Head() : _eyebrowRoll [1] = -20; } - +/* void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { _position = p; _scale = s; - _yaw = r.x; - _pitch = r.y; - _roll = r.z; + _headRotation = r; } +*/ +/* void Head::setNewTarget(float pitch, float 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); + _orientation.setToPitchYawRoll + ( + _headRotation.x, + _bodyRotation.y + _headRotation.y, + _headRotation.z + ); //calculate the eye positions (algorithm still being designed) updateEyePositions(); @@ -101,26 +108,28 @@ void Head::simulate(float deltaTime, bool isMine) { // Decay head back to center if turned on 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); + _headRotation.x *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); + _headRotation.y *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); + _headRotation.z *= (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(_headRotation.x) < RETURN_RANGE) { _headRotation.x *= (1.0f - RETURN_STRENGTH * deltaTime); } + if (fabs(_headRotation.y) < RETURN_RANGE) { _headRotation.y *= (1.0f - RETURN_STRENGTH * deltaTime); } + if (fabs(_headRotation.z) < RETURN_RANGE) { _headRotation.z *= (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); } + */ leanForward *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); leanSideways *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); @@ -137,7 +146,7 @@ void Head::simulate(float deltaTime, bool isMine) { _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); + //setNewTarget(0,0); } } @@ -167,14 +176,14 @@ void Head::simulate(float deltaTime, bool isMine) { 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] = -_headRotation.x + eye_target_pitch_adjust; + _eyeballYaw [0] = _eyeballYaw [1] = _headRotation.y + eye_target_yaw_adjust; } if (noise) { - _pitch += (randFloat() - 0.5) * 0.2 * _noiseEnvelope; - _yaw += (randFloat() - 0.5) * 0.3 *_noiseEnvelope; + _headRotation.x += (randFloat() - 0.5) * 0.2 * _noiseEnvelope; + _headRotation.y += (randFloat() - 0.5) * 0.3 *_noiseEnvelope; //PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope; if (randFloat() < 0.005) _mouthWidth = _MouthWidthChoices[rand()%3]; @@ -184,15 +193,17 @@ void Head::simulate(float deltaTime, bool isMine) { 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)) { 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) { @@ -205,7 +216,7 @@ void Head::simulate(float deltaTime, bool isMine) { // 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; + (deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness; } @@ -215,11 +226,11 @@ void Head::updateEyePositions() { float frontShift = _scale * 0.8f; _leftEyePosition = _position - + _orientation.getRight() * rightShift + - _orientation.getRight() * rightShift + _orientation.getUp () * upShift + _orientation.getFront() * frontShift; _rightEyePosition = _position - - _orientation.getRight() * rightShift + + _orientation.getRight() * rightShift + _orientation.getUp () * upShift + _orientation.getFront() * frontShift; } @@ -238,41 +249,47 @@ void Head::setLooking(bool looking) { } } -glm::vec3 Head::getApproximateEyePosition() { - return _leftEyePosition + (_rightEyePosition - _leftEyePosition) * ONE_HALF; -} void Head::render(bool lookingInMirror) { - int side = 0; + //int side = 0; glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); + + renderEars(); + glPushMatrix(); glTranslatef(_position.x, _position.y, _position.z); //translate to head position glScalef(_scale, _scale, _scale); //scale to head size + + /* if (lookingInMirror) { - glRotatef(_bodyYaw - _yaw, 0, 1, 0); + glRotatef(_bodyRotation.y - _yaw, 0, 1, 0); glRotatef(_pitch, 1, 0, 0); glRotatef(-_roll, 0, 0, 1); } else { - glRotatef(_bodyYaw + _yaw, 0, 1, 0); + glRotatef(_bodyRotation.y + _yaw, 0, 1, 0); glRotatef(_pitch, 1, 0, 0); glRotatef(_roll, 0, 0, 1); - } + }*/ + + //glRotatef( _headRotation.x, IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); + //glRotatef(_bodyRotation.y + _headRotation.y, IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); + //glRotatef( _headRotation.z, IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); - //glScalef(2.0, 2.0, 2.0); + //draw head sphere glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); - glutSolidSphere(1, 30, 30); - // Ears + /* + // render ears glPushMatrix(); glTranslatef(1.0, 0, 0); - for(side = 0; side < 2; side++) { + for(int side = 0; side < 2; side++) { glPushMatrix(); glScalef(0.3, 0.65, .65); glutSolidSphere(0.5, 30, 30); @@ -280,7 +297,11 @@ void Head::render(bool lookingInMirror) { glTranslatef(-2.0, 0, 0); } glPopMatrix(); + */ + + + /* // Update audio attack data for facial animation (eyebrows and mouth) _audioAttack = 0.9 * _audioAttack + 0.1 * fabs(_audioLoudness - _lastLoudness); _lastLoudness = _audioLoudness; @@ -294,7 +315,7 @@ void Head::render(bool lookingInMirror) { // Render Eyebrows glPushMatrix(); glTranslatef(-_interBrowDistance / 2.0,0.4,0.45); - for(side = 0; side < 2; side++) { + for(int side = 0; side < 2; side++) { glColor3fv(_browColor); glPushMatrix(); glTranslatef(0, 0.35 + _browAudioLift, 0); @@ -306,7 +327,15 @@ void Head::render(bool lookingInMirror) { glTranslatef(_interBrowDistance, 0, 0); } glPopMatrix(); + */ + + + + + + + /* // Mouth // const float MIN_LOUDNESS_SCALE_WIDTH = 0.7f; // const float WIDTH_SENSITIVITY = 60.f; @@ -328,11 +357,12 @@ void Head::render(bool lookingInMirror) { glutSolidCube(0.5); glPopMatrix(); + */ glPopMatrix(); renderEyeBalls(); - + /* if (_lookingAtSomething) { // Render lines originating from the eyes and converging on the lookatPosition @@ -341,6 +371,24 @@ void Head::render(bool lookingInMirror) { */ } + +void Head::renderEars() { + + glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glPushMatrix(); + glTranslatef(_position.x -_orientation.getRight().x * _scale, _position.x -_orientation.getRight().y * _scale, _position.x -_orientation.getRight().z * _scale); + //glScalef(0.3, 0.65, .65); + glutSolidSphere(0.01, 30, 30); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(_position.x + _orientation.getRight().x, _position.x + _orientation.getRight().y, _position.x + _orientation.getRight().z); + //glScalef(0.3, 0.65, .65); + glutSolidSphere(0.01, 30, 30); + glPopMatrix(); +} + + void Head::renderEyeBalls() { if (::irisTexture.size() == 0) { diff --git a/interface/src/Head.h b/interface/src/Head.h index 4ee20e3cfd..fe712282c4 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -31,19 +31,21 @@ public: void render(bool lookingInMirror); void setLooking(bool looking); - void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale); - void setNewTarget(float, float); + //void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale); + //void setNewTarget(float, float); + void setScale (float scale ) { _scale = scale; } + void setPosition (glm::vec3 position ) { _position = position; } void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } + void setBodyRotation (glm::vec3 bodyRotation ) { _bodyRotation = bodyRotation; } + void setRotationOffBody(glm::vec3 headRotation ) { _headRotation = headRotation; } void setGravity (glm::vec3 gravity ) { _gravity = gravity; } void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; } - void setBodyYaw (float bodyYaw ) { _bodyYaw = bodyYaw; } void setSpringScale (float returnSpringScale ) { _returnSpringScale = returnSpringScale; } void setAverageLoudness(float averageLoudness ) { _averageLoudness = averageLoudness; } void setAudioLoudness (float audioLoudness ) { _audioLoudness = audioLoudness; } void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } - glm::vec3 getApproximateEyePosition(); const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) float getAverageLoudness() {return _averageLoudness;}; @@ -63,9 +65,9 @@ private: glm::vec3 _lookatPosition; glm::vec3 _leftEyePosition; glm::vec3 _rightEyePosition; - float _yaw; - float _pitch; - float _roll; + //float _yaw; + //float _pitch; + //float _roll; float _eyeballPitch[2]; float _eyeballYaw [2]; float _eyebrowPitch[2]; @@ -75,8 +77,8 @@ private: float _mouthYaw; float _mouthWidth; float _mouthHeight; - float _pitchTarget; - float _yawTarget; + //float _pitchTarget; + //float _yawTarget; float _noiseEnvelope; float _scale; int _eyeContact; @@ -88,11 +90,13 @@ private: float _audioAttack; float _returnSpringScale; //strength of return springs Orientation _orientation; - float _bodyYaw; + glm::vec3 _bodyRotation; + glm::vec3 _headRotation; eyeContactTargets _eyeContactTarget; // private methods void renderEyeBalls(); + void renderEars(); void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); void updateEyePositions(); }; From 9d3e76efe26e15041e1aad2293966e00b8cfdb07 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 20 May 2013 17:53:55 -0700 Subject: [PATCH 2/4] operating on head. patient under anesthesia --- interface/src/Avatar.cpp | 6 +-- interface/src/Head.cpp | 96 ++++++++++++++++++++++------------------ interface/src/Head.h | 4 +- 3 files changed, 60 insertions(+), 46 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index eb4c013933..7cd29ecc90 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -370,7 +370,7 @@ void Avatar::simulate(float deltaTime) { } // set head lookat position - setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 + //setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 if (_interactingOther) { _head.setLooking(true); @@ -381,9 +381,9 @@ void Avatar::simulate(float deltaTime) { _head.setLooking(false); } - _head.setLookatPosition(_lookatPosition); // this comes from Avatar Data + //_head.setLookatPosition(_lookatPosition); // this comes from Avatar Data _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); - _head.setRotationOffBody(glm::vec3(_headPitch, _headYaw, _headRoll)); + //_head.setRotationOffBody(glm::vec3(_headPitch, _headYaw, _headRoll)); //_head.setRotationOffBody(glm::vec3(0.0f, 0.0f, 0.0f)); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 75816c2967..13c4112e7e 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -43,7 +43,7 @@ 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), + //_lookatPosition(0.0f, 0.0f, 0.0f), //_yaw(0.0f), //_pitch(0.0f), //_roll(0.0f), @@ -100,29 +100,55 @@ void Head::simulate(float deltaTime, bool isMine) { //generate orientation directions based on Euler angles... _orientation.setToPitchYawRoll ( - _headRotation.x, - _bodyRotation.y + _headRotation.y, - _headRotation.z + _pitch, + _bodyRotation.y + _yaw, + _roll ); //calculate the eye positions (algorithm still being designed) - 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; + + rightShift = _scale * 1.0f; + upShift = _scale * 0.0f; + frontShift = _scale * 0.0f; + + _leftEarPosition = _position + - _orientation.getRight() * rightShift + + _orientation.getUp () * upShift + + _orientation.getFront() * frontShift; + _rightEarPosition = _position + + _orientation.getRight() * rightShift + + _orientation.getUp () * upShift + + _orientation.getFront() * frontShift; + + // Decay head back to center if turned on if (isMine && _returnHeadToCenter) { // Decay back toward center - _headRotation.x *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); - _headRotation.y *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * 2 * deltaTime); - _headRotation.z *= (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(_headRotation.x) < RETURN_RANGE) { _headRotation.x *= (1.0f - RETURN_STRENGTH * deltaTime); } - if (fabs(_headRotation.y) < RETURN_RANGE) { _headRotation.y *= (1.0f - RETURN_STRENGTH * deltaTime); } - if (fabs(_headRotation.z) < RETURN_RANGE) { _headRotation.z *= (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); } } /* @@ -179,14 +205,14 @@ void Head::simulate(float deltaTime, bool isMine) { 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] = -_headRotation.x + eye_target_pitch_adjust; - _eyeballYaw [0] = _eyeballYaw [1] = _headRotation.y + eye_target_yaw_adjust; + _eyeballPitch[0] = _eyeballPitch[1] = -_pitch + eye_target_pitch_adjust; + _eyeballYaw [0] = _eyeballYaw [1] = _yaw + eye_target_yaw_adjust; } if (noise) { - _headRotation.x += (randFloat() - 0.5) * 0.2 * _noiseEnvelope; - _headRotation.y += (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]; @@ -223,21 +249,6 @@ void Head::simulate(float deltaTime, bool isMine) { } -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) { @@ -260,8 +271,6 @@ void Head::render(bool lookingInMirror) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - renderEars(); - glPushMatrix(); @@ -280,9 +289,9 @@ void Head::render(bool lookingInMirror) { glRotatef(_roll, 0, 0, 1); }*/ - //glRotatef( _headRotation.x, IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); - //glRotatef(_bodyRotation.y + _headRotation.y, IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); - //glRotatef( _headRotation.z, IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); + //glRotatef( _pitch, IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); + //glRotatef(_bodyRotation.y + _yaw, IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); + //glRotatef( _roll, IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); //draw head sphere glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); @@ -365,6 +374,10 @@ void Head::render(bool lookingInMirror) { glPopMatrix(); renderEyeBalls(); + + renderEars(); + + /* if (_lookingAtSomething) { @@ -377,17 +390,16 @@ void Head::render(bool lookingInMirror) { void Head::renderEars() { - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); glPushMatrix(); - glTranslatef(_position.x -_orientation.getRight().x * _scale, _position.x -_orientation.getRight().y * _scale, _position.x -_orientation.getRight().z * _scale); - //glScalef(0.3, 0.65, .65); - glutSolidSphere(0.01, 30, 30); + glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glTranslatef(_leftEarPosition.x, _leftEarPosition.y, _leftEarPosition.z); + glutSolidSphere(0.02, 30, 30); glPopMatrix(); glPushMatrix(); - glTranslatef(_position.x + _orientation.getRight().x, _position.x + _orientation.getRight().y, _position.x + _orientation.getRight().z); - //glScalef(0.3, 0.65, .65); - glutSolidSphere(0.01, 30, 30); + glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glTranslatef(_rightEarPosition.x, _rightEarPosition.y, _rightEarPosition.z); + glutSolidSphere(0.02, 30, 30); glPopMatrix(); } diff --git a/interface/src/Head.h b/interface/src/Head.h index c39f2a3d2d..0a71d0405e 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -37,7 +37,7 @@ public: void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } - void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } + //void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } void setBodyRotation (glm::vec3 bodyRotation ) { _bodyRotation = bodyRotation; } void setRotationOffBody(glm::vec3 headRotation ) { _headRotation = headRotation; } void setGravity (glm::vec3 gravity ) { _gravity = gravity; } @@ -63,6 +63,8 @@ private: glm::vec3 _rotation; glm::vec3 _leftEyePosition; glm::vec3 _rightEyePosition; + glm::vec3 _leftEarPosition; + glm::vec3 _rightEarPosition; //float _yaw; //float _pitch; //float _roll; From d21b48ad6e2fc197c33ddf52c22c2f5ec81032cb Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 21 May 2013 14:20:44 -0700 Subject: [PATCH 3/4] cleaned up a lot of pitch/yaw/roll confusion in Head and made new versions of eyes, eyebrows and mouth (Head still needs work) --- interface/src/Application.cpp | 4 +- interface/src/Avatar.cpp | 59 ++-- interface/src/Head.cpp | 518 ++++++++++++++-------------------- interface/src/Head.h | 28 +- 4 files changed, 255 insertions(+), 354 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3c356af930..a65e0be4de 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1707,9 +1707,9 @@ void Application::displaySide(Camera& whichCamera) { } } agentList->unlock(); - + // Render my own Avatar - _myAvatar.render(_lookingInMirror, _myCamera.getPosition()); + _myAvatar.render(_lookingInMirror->isChecked(), _myCamera.getPosition()); } // Render the world box diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 7cd29ecc90..4ad2d54db7 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -134,8 +134,8 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa // Update avatar head position based on measured gyro rates _head.addPitch(measuredPitchRate * deltaTime); - _head.addYaw(measuredYawRate * deltaTime); - _head.addRoll(measuredRollRate * deltaTime); + _head.addYaw (measuredYawRate * deltaTime); + _head.addRoll (measuredRollRate * deltaTime); // Update head lean distance based on accelerometer data const float LEAN_SENSITIVITY = 0.15; @@ -674,7 +674,7 @@ void Avatar::setGravity(glm::vec3 gravity) { } void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { - + _cameraPosition = cameraPosition; // store this for use in various parts of the code if (usingBigSphereCollisionTest) { @@ -1083,41 +1083,38 @@ void Avatar::renderBody(bool lookingInMirror) { } } else { - //show direction vectors of the bone orientation - //renderOrientationDirections(_joint[b].springyPosition, _joint[b].orientation, _joint[b].radius * 2.0); - - glColor3fv(skinColor); + glColor3f + ( + skinColor[0] + _joint[b].touchForce * 0.3f, + skinColor[1] - _joint[b].touchForce * 0.2f, + skinColor[2] - _joint[b].touchForce * 0.1f + ); glPushMatrix(); glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); glPopMatrix(); } - - if (_joint[b].touchForce > 0.0f) { - - float alpha = _joint[b].touchForce * 0.2; - float r = _joint[b].radius * 1.1f + 0.005f; - glColor4f(0.5f, 0.2f, 0.2f, alpha); - glPushMatrix(); - glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); - glScalef(r, r, r); - glutSolidSphere(1, 20, 20); - glPopMatrix(); - } } - for (int b = 1; b < NUM_AVATAR_JOINTS; b++) { - if (_joint[b].parent != AVATAR_JOINT_NULL) - if (b != AVATAR_JOINT_HEAD_TOP) { - + for (int j = 1; j < NUM_AVATAR_JOINTS; j++) { + if (_joint[j].parent != AVATAR_JOINT_NULL) + if ((j != AVATAR_JOINT_HEAD_TOP ) + && (j != AVATAR_JOINT_HEAD_BASE ) + && (j != AVATAR_JOINT_PELVIS ) + && (j != AVATAR_JOINT_TORSO ) + && (j != AVATAR_JOINT_CHEST ) + && (j != AVATAR_JOINT_LEFT_COLLAR ) + && (j != AVATAR_JOINT_LEFT_SHOULDER ) + && (j != AVATAR_JOINT_RIGHT_COLLAR ) + && (j != AVATAR_JOINT_RIGHT_SHOULDER)) { // Render cone sections connecting the joint positions glColor3fv(darkSkinColor); renderJointConnectingCone ( - _joint[_joint[b].parent ].springyPosition, - _joint[b ].springyPosition, - _joint[_joint[b].parent ].radius * 0.8, - _joint[b ].radius * 0.8 + _joint[_joint[j].parent ].springyPosition, + _joint[j ].springyPosition, + _joint[_joint[j].parent ].radius * 0.8, + _joint[j ].radius * 0.8 ); /* @@ -1312,18 +1309,18 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity if (deltaTime == 0.f) { // On first sample, set head to absolute position - _head.setYaw(eulerAngles->x); + _head.setYaw (eulerAngles->x); _head.setPitch(eulerAngles->y); - _head.setRoll(eulerAngles->z); + _head.setRoll (eulerAngles->z); } else { 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); - _head.setYaw(angles.x); + _head.setYaw (angles.x); _head.setPitch(angles.y); - _head.setRoll(angles.z); + _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/Head.cpp b/interface/src/Head.cpp index 13c4112e7e..19b7701f72 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -12,53 +12,32 @@ 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 +const float EYE_RIGHT_OFFSET = 0.27f; +const float EYE_UP_OFFSET = 0.38f; +const float EYE_FRONT_OFFSET = 0.8f; +const float EAR_RIGHT_OFFSET = 1.0; +const float MOUTH_FRONT_OFFSET = 1.0f; +const float MOUTH_UP_OFFSET = -0.2f; +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 +const float EYEBALL_RADIUS = 0.02; +const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f}; +const float IRIS_RADIUS = 0.007; +const float IRIS_PROTRUSION = 0.018f; +const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png"; -const float EYEBALL_RADIUS = 0.02; -const float IRIS_RADIUS = 0.007; -const float IRIS_PROTRUSION = 0.018f; - -float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; -float _mouthColor[] = {1, 0, 0}; - -float _BrowRollAngle [5] = { 0.0f, 15.0f, 30.0f, -30.0f, -15.0f}; -float _BrowPitchAngle[3] = {-70.0f, -60.0f, -50.0f}; -float _eyeColor [3] = { 0.9f, 0.9f, 0.8f}; - -float _MouthWidthChoices[3] = {0.5, 0.77, 0.3}; - -float _browWidth = 0.8; -float _browThickness = 0.16; - -const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png"; -unsigned int IRIS_TEXTURE_WIDTH = 768; +unsigned int IRIS_TEXTURE_WIDTH = 768; unsigned int IRIS_TEXTURE_HEIGHT = 498; vector irisTexture; Head::Head() : yawRate(0.0f), - noise(0.0f), _audioLoudness(0.0f), _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), - //_yaw(0.0f), - //_pitch(0.0f), - //_roll(0.0f), - _eyeballPitch(), - _eyeballYaw(), - _interBrowDistance(0.75f), - _mouthPitch(0), - _mouthYaw(0), - _mouthWidth(1.0f), - _mouthHeight(0.2f), - //_pitchTarget(0.0f), - //_yawTarget(0.0f), - _noiseEnvelope(1.0f), + _mouthPosition(0.0f, 0.0f, 0.0f), _scale(1.0f), - _eyeContact(1), _browAudioLift(0.0f), _gravity(0.0f, -1.0f, 0.0f), _lastLoudness(0.0f), @@ -66,80 +45,24 @@ Head::Head() : _audioAttack(0.0f), _returnSpringScale(1.0f), _bodyRotation(0.0f, 0.0f, 0.0f), - _headRotation(0.0f, 0.0f, 0.0f), - _eyeContactTarget(LEFT_EYE) -{ - _eyebrowPitch[0] = -30; - _eyebrowPitch[1] = -30; - _eyebrowRoll [0] = 20; - _eyebrowRoll [1] = -20; + _headRotation(0.0f, 0.0f, 0.0f) { } -/* -void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { - _position = p; - _scale = s; - _headRotation = r; -} -*/ - -/* -void Head::setNewTarget(float pitch, float yaw) { - _pitchTarget = pitch; - _yawTarget = yaw; -} -*/ - void Head::reset() { _yaw = _pitch = _roll = 0.0f; _leanForward = _leanSideways = 0.0f; } + void Head::simulate(float deltaTime, bool isMine) { - //generate orientation directions based on Euler angles... - _orientation.setToPitchYawRoll - ( - _pitch, - _bodyRotation.y + _yaw, - _roll - ); - - //calculate the eye positions (algorithm still being designed) - 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; - - rightShift = _scale * 1.0f; - upShift = _scale * 0.0f; - frontShift = _scale * 0.0f; - - _leftEarPosition = _position - - _orientation.getRight() * rightShift - + _orientation.getUp () * upShift - + _orientation.getFront() * frontShift; - _rightEarPosition = _position - + _orientation.getRight() * rightShift - + _orientation.getUp () * upShift - + _orientation.getFront() * frontShift; - - - // Decay head back to center if turned on if (isMine && _returnHeadToCenter) { - // Decay back toward center + + // Decay rotation 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); + _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 @@ -147,106 +70,33 @@ void Head::simulate(float deltaTime, bool 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(_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); - } - */ - + // decay lean _leanForward *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); _leanSideways *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime); - - // Update where the avatar's eyes are - // - // First, decide if we are making eye contact or not - if (randFloat() < 0.005) { - _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; - } else { - // If now making eye contact, turn head to look right at viewer - //setNewTarget(0,0); - } - } - - const float DEGREES_BETWEEN_VIEWER_EYES = 3; - const float DEGREES_TO_VIEWER_MOUTH = 7; - - 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; - } else { - 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.0f; - float eye_target_pitch_adjust = 0.0f; - - 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; - } - - if (noise) - { - _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 (!_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)) { - 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; - } - if (randFloat() < 0.01) - { - _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; - + + + // Update audio attack data for facial animation (eyebrows and mouth) + _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) * 0.00005; + + float clamp = 0.01; + if (_browAudioLift > clamp) { _browAudioLift = clamp; } + + _browAudioLift *= 0.7f; + } @@ -264,120 +114,59 @@ void Head::setLooking(bool looking) { } + + +void Head::calculateGeometry(bool lookingInMirror) { + //generate orientation directions based on Euler angles... + + float pitch = -_pitch; + float yaw = -_yaw; + float roll = _roll; + + if (lookingInMirror) { + yaw = _yaw; + roll = -_roll; + } + + _orientation.setToPitchYawRoll + ( + _bodyRotation.x + pitch, + _bodyRotation.y + yaw, + _bodyRotation.z + roll + ); + + //calculate the eye positions + _leftEyePosition = _position + - _orientation.getRight() * _scale * EYE_RIGHT_OFFSET + + _orientation.getUp () * _scale * EYE_UP_OFFSET + + _orientation.getFront() * _scale * EYE_FRONT_OFFSET; + _rightEyePosition = _position + + _orientation.getRight() * _scale * EYE_RIGHT_OFFSET + + _orientation.getUp () * _scale * EYE_UP_OFFSET + + _orientation.getFront() * _scale * EYE_FRONT_OFFSET; + + //calculate the ear positions + _leftEarPosition = _position - _orientation.getRight() * _scale * EAR_RIGHT_OFFSET; + _rightEarPosition = _position + _orientation.getRight() * _scale * EAR_RIGHT_OFFSET; + + //calculate the mouth position + _mouthPosition = _position + _orientation.getUp () * _scale * MOUTH_UP_OFFSET + + _orientation.getFront() * _scale * MOUTH_FRONT_OFFSET; +} + + void Head::render(bool lookingInMirror) { - //int side = 0; - + calculateGeometry(lookingInMirror); + glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); - - glPushMatrix(); - - glTranslatef(_position.x, _position.y, _position.z); //translate to head position - glScalef(_scale, _scale, _scale); //scale to head size - - - /* - if (lookingInMirror) { - glRotatef(_bodyRotation.y - _yaw, 0, 1, 0); - glRotatef(_pitch, 1, 0, 0); - glRotatef(-_roll, 0, 0, 1); - } else { - glRotatef(_bodyRotation.y + _yaw, 0, 1, 0); - glRotatef(_pitch, 1, 0, 0); - glRotatef(_roll, 0, 0, 1); - }*/ - - //glRotatef( _pitch, IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); - //glRotatef(_bodyRotation.y + _yaw, IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); - //glRotatef( _roll, IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); - - //draw head sphere - glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); - glutSolidSphere(1, 30, 30); - - /* - // render ears - glPushMatrix(); - glTranslatef(1.0, 0, 0); - for(int side = 0; side < 2; side++) { - glPushMatrix(); - glScalef(0.3, 0.65, .65); - glutSolidSphere(0.5, 30, 30); - glPopMatrix(); - glTranslatef(-2.0, 0, 0); - } - glPopMatrix(); - */ - - - - /* - // Update audio attack data for facial animation (eyebrows and mouth) - _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; - - _browAudioLift *= .90; - - // Render Eyebrows - glPushMatrix(); - glTranslatef(-_interBrowDistance / 2.0,0.4,0.45); - for(int 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); - glScalef(_browWidth, _browThickness, 1); - glutSolidCube(0.5); - glPopMatrix(); - glTranslatef(_interBrowDistance, 0, 0); - } - glPopMatrix(); - */ - - - - - - - - /* - // Mouth -// const float MIN_LOUDNESS_SCALE_WIDTH = 0.7f; -// const float WIDTH_SENSITIVITY = 60.f; -// 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) { - glScalef(_mouthWidth * (.7f + sqrt(_averageLoudness) /60.f), - _mouthHeight * (1.f + sqrt(_averageLoudness) /30.f), 1); - } else { - glScalef(_mouthWidth, _mouthHeight, 1); - } - - glutSolidCube(0.5); - glPopMatrix(); - */ - - glPopMatrix(); - + renderHeadSphere(); renderEyeBalls(); - renderEars(); - - + renderMouth(); + renderEyeBrows(); /* if (_lookingAtSomething) { @@ -387,6 +176,14 @@ void Head::render(bool lookingInMirror) { */ } +void Head::renderHeadSphere() { + glPushMatrix(); + glTranslatef(_position.x, _position.y, _position.z); //translate to head position + glScalef(_scale, _scale, _scale); //scale to head size + glColor3f(_skinColor.x, _skinColor.y, _skinColor.z); + glutSolidSphere(1, 30, 30); + glPopMatrix(); +} void Head::renderEars() { @@ -404,6 +201,129 @@ void Head::renderEars() { } + +void Head::renderMouth() { + + float s = sqrt(_averageLoudness); + float height = _scale * (0.02f + s * 0.003f ); + float width = _scale * (0.30f + s * 0.001f ); + + glm::vec3 leftCorner = _mouthPosition; + glm::vec3 rightCorner = _mouthPosition; + glm::vec3 leftTop = _mouthPosition; + glm::vec3 rightTop = _mouthPosition; + glm::vec3 leftBottom = _mouthPosition; + glm::vec3 rightBottom = _mouthPosition; + + leftCorner -= _orientation.getRight() * width; + rightCorner += _orientation.getRight() * width; + leftTop -= _orientation.getRight() * width * 0.3f; + rightTop += _orientation.getRight() * width * 0.3f; + leftBottom -= _orientation.getRight() * width * 0.3f; + rightBottom += _orientation.getRight() * width * 0.3f; + + leftTop += _orientation.getUp() * height * 0.7f; + rightTop += _orientation.getUp() * height * 0.7f; + leftBottom -= _orientation.getUp() * height; + rightBottom -= _orientation.getUp() * height; + + leftTop += _orientation.getFront() * _scale * 0.1f; + rightTop += _orientation.getFront() * _scale * 0.1f; + leftBottom += _orientation.getFront() * _scale * 0.1f; + rightBottom += _orientation.getFront() * _scale * 0.1f; + + glColor3f(0.2f, 0.0f, 0.0f); + + glBegin(GL_TRIANGLES); + + glVertex3f(leftCorner.x, leftCorner.y, leftCorner.z); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z); + glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + + glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z); + + glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); + + glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); + glVertex3f(rightCorner.x, rightCorner.y, rightCorner.z); + + glEnd(); +} + + + +void Head::renderEyeBrows() { + + float height = _scale * 0.3f + _browAudioLift; + float length = _scale * 0.2f; + float width = _scale * 0.07f; + + glColor3f(0.3f, 0.25f, 0.2f); + + glm::vec3 leftCorner = _leftEyePosition; + glm::vec3 rightCorner = _leftEyePosition; + glm::vec3 leftTop = _leftEyePosition; + glm::vec3 rightTop = _leftEyePosition; + glm::vec3 leftBottom = _leftEyePosition; + glm::vec3 rightBottom = _leftEyePosition; + + for (int i = 0; i<2; i++) { + + if ( i == 1 ) { + leftCorner = rightCorner = leftTop = rightTop = leftBottom = rightBottom = _rightEyePosition; + } + + leftCorner -= _orientation.getRight() * length; + rightCorner += _orientation.getRight() * length; + leftTop -= _orientation.getRight() * length * 0.4f; + rightTop += _orientation.getRight() * length * 0.4f; + leftBottom -= _orientation.getRight() * length * 0.4f; + rightBottom += _orientation.getRight() * length * 0.4f; + + leftCorner += _orientation.getUp() * height; + rightCorner += _orientation.getUp() * height; + leftTop += _orientation.getUp() * (height + width); + rightTop += _orientation.getUp() * (height + width); + leftBottom += _orientation.getUp() * height; + rightBottom += _orientation.getUp() * height; + + leftCorner += _orientation.getFront() * _scale * -0.1f; + rightCorner += _orientation.getFront() * _scale * -0.1f; + leftTop += _orientation.getFront() * _scale * -0.1f; + rightTop += _orientation.getFront() * _scale * -0.1f; + leftBottom += _orientation.getFront() * _scale * -0.1f; + rightBottom += _orientation.getFront() * _scale * -0.1f; + + + glBegin(GL_TRIANGLES); + + glVertex3f(leftCorner.x, leftCorner.y, leftCorner.z); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z); + glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + + glVertex3f(leftTop.x, leftTop.y, leftTop.z ); + glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z); + + glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z ); + glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); + + glVertex3f(rightTop.x, rightTop.y, rightTop.z ); + glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z); + glVertex3f(rightCorner.x, rightCorner.y, rightCorner.z); + + glEnd(); + } + } + + + void Head::renderEyeBalls() { if (::irisTexture.size() == 0) { @@ -425,7 +345,7 @@ void Head::renderEyeBalls() { // render white ball of left eyeball glPushMatrix(); - glColor3fv(_eyeColor); + glColor3fv(EYEBALL_COLOR); glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glPopMatrix(); @@ -469,7 +389,7 @@ void Head::renderEyeBalls() { //render white ball of right eyeball glPushMatrix(); - glColor3fv(_eyeColor); + glColor3fv(EYEBALL_COLOR); glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30); glPopMatrix(); diff --git a/interface/src/Head.h b/interface/src/Head.h index 0a71d0405e..35f8c8e083 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -32,12 +32,9 @@ public: void render(bool lookingInMirror); void setLooking(bool looking); - //void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale); - //void setNewTarget(float, float); void setScale (float scale ) { _scale = scale; } void setPosition (glm::vec3 position ) { _position = position; } - //void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; } void setBodyRotation (glm::vec3 bodyRotation ) { _bodyRotation = bodyRotation; } void setRotationOffBody(glm::vec3 headRotation ) { _headRotation = headRotation; } void setGravity (glm::vec3 gravity ) { _gravity = gravity; } @@ -48,9 +45,8 @@ public: void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } const bool getReturnToCenter() const { return _returnHeadToCenter; } // Do you want head to try to return to center (depends on interface detected) - float getAverageLoudness() {return _averageLoudness;}; + float getAverageLoudness() {return _averageLoudness;}; - //some public members (left-over from pulling Head out of Avatar - I may see about privatizing these later). float yawRate; float noise; @@ -65,23 +61,8 @@ private: glm::vec3 _rightEyePosition; glm::vec3 _leftEarPosition; glm::vec3 _rightEarPosition; - //float _yaw; - //float _pitch; - //float _roll; - float _eyeballPitch[2]; - float _eyeballYaw [2]; - float _eyebrowPitch[2]; - float _eyebrowRoll [2]; - float _interBrowDistance; - float _mouthPitch; - float _mouthYaw; - float _mouthWidth; - float _mouthHeight; - //float _pitchTarget; - //float _yawTarget; - float _noiseEnvelope; + glm::vec3 _mouthPosition; float _scale; - int _eyeContact; float _browAudioLift; bool _lookingAtSomething; glm::vec3 _gravity; @@ -92,13 +73,16 @@ private: Orientation _orientation; glm::vec3 _bodyRotation; glm::vec3 _headRotation; - eyeContactTargets _eyeContactTarget; // private methods + void renderHeadSphere(); void renderEyeBalls(); + void renderEyeBrows(); void renderEars(); + void renderMouth(); void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); void updateEyePositions(); + void calculateGeometry( bool lookingInMirror); }; #endif From c11851b75d828393f9d47a1e0a5012f0e1e0d234 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 21 May 2013 15:02:44 -0700 Subject: [PATCH 4/4] cleaned up formatting stuff --- interface/src/Avatar.cpp | 24 ++++++++---------------- interface/src/Head.cpp | 4 ++-- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 2f0051ec88..9ca648a44a 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -213,10 +213,8 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree void Avatar::simulate(float deltaTime, Transmitter* transmitter) { //figure out if the mouse cursor is over any body spheres... - //if (_isMine) { - { - checkForMouseRayTouching(); - } + checkForMouseRayTouching(); + // copy velocity so we can use it later for acceleration glm::vec3 oldVelocity = getVelocity(); @@ -390,7 +388,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } // set head lookat position - //setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0 if (_interactingOther) { _head.setLooking(true); @@ -401,12 +398,7 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { _head.setLooking(false); } - //_head.setLookatPosition(_lookatPosition); // this comes from Avatar Data _head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); - //_head.setRotationOffBody(glm::vec3(_headPitch, _headYaw, _headRoll)); - - //_head.setRotationOffBody(glm::vec3(0.0f, 0.0f, 0.0f)); - _head.setPosition(_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition); _head.setScale (_joint[ AVATAR_JOINT_HEAD_BASE ].radius); _head.setAudioLoudness(_audioLoudness); @@ -1117,12 +1109,12 @@ void Avatar::renderBody(bool lookingInMirror) { } } else { - glColor3f - ( + glColor3f( skinColor[0] + _joint[b].touchForce * 0.3f, skinColor[1] - _joint[b].touchForce * 0.2f, skinColor[2] - _joint[b].touchForce * 0.1f ); + glPushMatrix(); glTranslatef(_joint[b].springyPosition.x, _joint[b].springyPosition.y, _joint[b].springyPosition.z); glutSolidSphere(_joint[b].radius, 20.0f, 20.0f); @@ -1248,10 +1240,10 @@ void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, angle1 = angle2; angle2 = ((float)(i+1) / (float)num) * PI * 2.0; - float s1 = sin(angle1); - float s2 = sin(angle2); - float c1 = cos(angle1); - float c2 = cos(angle2); + float s1 = sinf(angle1); + float s2 = sinf(angle2); + float c1 = cosf(angle1); + float c2 = cosf(angle2); glm::vec3 p1a = position1 + perpSin * s1 * radius1 + perpCos * c1 * radius1; glm::vec3 p1b = position1 + perpSin * s2 * radius1 + perpCos * c2 * radius1; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 19b7701f72..2dac795af1 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -21,7 +21,7 @@ const float MOUTH_UP_OFFSET = -0.2f; 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 const float EYEBALL_RADIUS = 0.02; -const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f}; +const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f }; const float IRIS_RADIUS = 0.007; const float IRIS_PROTRUSION = 0.018f; const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png"; @@ -272,7 +272,7 @@ void Head::renderEyeBrows() { glm::vec3 leftBottom = _leftEyePosition; glm::vec3 rightBottom = _leftEyePosition; - for (int i = 0; i<2; i++) { + for (int i = 0; i < 2; i++) { if ( i == 1 ) { leftCorner = rightCorner = leftTop = rightTop = leftBottom = rightBottom = _rightEyePosition;