From acda87502e337109e5279f40215d038b99b7f3a0 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 14 May 2013 11:43:51 -0700 Subject: [PATCH 1/9] more work on camera shifting between modes --- interface/src/Avatar.cpp | 16 ++----- interface/src/Camera.cpp | 31 ++++++++++++- interface/src/Camera.h | 2 + interface/src/Head.cpp | 11 +++-- interface/src/Head.h | 95 +++++++++++++++++++--------------------- interface/src/main.cpp | 36 ++++++++++++--- 6 files changed, 115 insertions(+), 76 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 64b9310b78..4b9a35733a 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -47,9 +47,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 AVATAR_BRAKING_RANGE = 1.3f; +const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; float skinColor [] = {1.0, 0.84, 0.66}; @@ -105,7 +104,7 @@ Avatar::Avatar(bool isMine) { initializeSkeleton(); - _avatarTouch.setReachableRadius(0.6); + _avatarTouch.setReachableRadius(1.0); if (BALLS_ON) { _balls = new Balls(100); } else { _balls = NULL; } @@ -880,13 +879,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) { @@ -1407,7 +1400,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/Camera.cpp b/interface/src/Camera.cpp index 4cd66521f0..2a74de363b 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -12,13 +12,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 +42,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 +73,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 +118,29 @@ void Camera::updateFollowMode(float deltaTime) { // force position towards ideal position _position += (_idealPosition - _position) * t; } + + float mm = 1.0f - _modeShift; + _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * mm; + _distance = _attributes[_mode].distance * _modeShift + _previousAttributes[_mode].distance * mm; + _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * mm; + + /* //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; + */ + } + 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 +150,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 ) { @@ -155,6 +181,7 @@ void Camera::setFarClip (float f) { 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 52c577e88a..348bde0d89 100644 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -89,8 +89,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/Head.cpp b/interface/src/Head.cpp index 6cdc9a7c7a..51d3e42c3f 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -222,8 +222,6 @@ void Head::simulate(float deltaTime, bool isMine) { } - - void Head::render(bool lookingInMirror, float bodyYaw) { int side = 0; @@ -268,7 +266,6 @@ void Head::render(bool lookingInMirror, float bodyYaw) { 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; @@ -295,20 +292,23 @@ void Head::render(bool lookingInMirror, float bodyYaw) { 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), + glScalef(mouthWidth * (.7f + sqrt(averageLoudness) /60.f), mouthHeight * (1.f + sqrt(averageLoudness) /30.f), 1); } else { glScalef(mouthWidth, mouthHeight, 1); - } + } glutSolidCube(0.5); glPopMatrix(); glTranslatef(0, 1.0, 0); + glTranslatef(-interPupilDistance/2.0,-0.68,0.7); // Right Eye glRotatef(-10, 1, 0, 0); @@ -373,6 +373,5 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glPopMatrix(); glPopMatrix(); - } diff --git a/interface/src/Head.h b/interface/src/Head.h index 3d345d5140..ee12098e24 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -37,57 +37,54 @@ public: float getAverageLoudness() {return averageLoudness;}; void setAverageLoudness(float al) { averageLoudness = al;}; + + 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; -//private: -// I am making these public for now - just to get the code moved over quickly! + // Sound loudness information + float lastLoudness; + float averageLoudness; + float audioAttack; + + GLUquadric* sphere; - 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; - - // Strength of return springs - float returnSpringScale; + // Strength of return springs + float returnSpringScale; }; #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index f606fab416..ff3cd22034 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -97,7 +97,6 @@ int packetsPerSecond = 0; int bytesPerSecond = 0; int bytesCount = 0; - int screenWidth = 1200; // Window size int screenHeight = 800; @@ -339,6 +338,7 @@ void init(void) { a.distance = 1.5f; a.tightness = 8.0f; myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + myCamera.initialize(); myAvatar.setDisplayingHead(true); OculusManager::connect(); @@ -1046,7 +1046,7 @@ void display(void) glPushMatrix(); { glLoadIdentity(); - + // camera settings if (OculusManager::isConnected()) { myAvatar.setDisplayingHead(false); @@ -1063,13 +1063,14 @@ void display(void) } else { if (myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition()); - myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f); + myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, -20.0f + myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f); } else if (myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + myCamera.setTargetPosition(myAvatar.getHeadPosition()); myCamera.setTargetRotation(myAvatar.getBodyYaw() - mouseViewShiftYaw, mouseViewShiftPitch, 0.0f); } } - + // important... myCamera.update( 1.f/FPS ); @@ -1081,7 +1082,7 @@ void display(void) glTranslatef(1, 1, HUD_Z_OFFSET); drawVector(&test); glPopMatrix(); - */ + */ // Note: whichCamera is used to pick between the normal camera myCamera for our @@ -1240,6 +1241,7 @@ int setRenderFirstPerson(int state) { bool value = setValue(state, &::renderFirstPersonOn); if (state == MENU_ROW_PICKED) { if (::renderFirstPersonOn) { + Camera::CameraFollowingAttributes a; a.upShift = 0.0f; a.distance = 0.0f; @@ -1870,14 +1872,34 @@ void idle(void) { ::mouseVoxel.green = ::mouseVoxel.blue = 0; } } - - // walking triggers the handControl to stop + + // when walking handControl stops if (myAvatar.getMode() == AVATAR_MODE_WALKING) { handControl.stop(); mouseViewShiftYaw *= 0.9; mouseViewShiftPitch *= 0.9; } + if (myCamera.getMode() != CAMERA_MODE_MIRROR) { + if (myAvatar.getIsNearInteractingOther()) { + myAvatar.setDisplayingHead(false); + Camera::CameraFollowingAttributes a; + a.upShift = 0.0f; + a.distance = 0.0f; + a.tightness = 100.0f; + myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); + } else { + if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { + myAvatar.setDisplayingHead(true); + Camera::CameraFollowingAttributes a; + a.upShift = -0.2f; + a.distance = 1.5f; + a.tightness = 8.0f; + myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); + } + } + } + // Read serial port interface devices if (serialPort.active) { serialPort.readData(); From f53b49c4966f0496cd641cc2d23f446e42716b63 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 14 May 2013 17:30:41 -0700 Subject: [PATCH 2/9] working on lookat (eye contact) --- interface/src/Avatar.cpp | 116 +------------- interface/src/Avatar.h | 4 - interface/src/Head.cpp | 214 ++++++++++++++++++++------ interface/src/Head.h | 9 ++ interface/src/main.cpp | 2 +- libraries/avatars/src/Orientation.cpp | 9 ++ libraries/avatars/src/Orientation.h | 1 + 7 files changed, 193 insertions(+), 162 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 4b9a35733a..bd5e255437 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -293,7 +293,9 @@ bool Avatar::getIsNearInteractingOther() { void Avatar::simulate(float deltaTime) { //figure out if the mouse cursor is over any body spheres... - checkForMouseRayTouching(); + if (_isMine) { + checkForMouseRayTouching(); + } // update balls if (_balls) { _balls->simulate(deltaTime); } @@ -519,6 +521,9 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } if (_interactingOther) { + + _head.setLookatPosition( _interactingOther->getSpringyHeadPosition()); + _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); _avatarTouch.setYourHandState (_interactingOther->_handState); @@ -592,115 +597,6 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } } -void Avatar::updateHead(float deltaTime) { - -/* - // Decay head back to center if turned on - if (_isMine && _returnHeadToCenter) { - // Decay back toward center - _headPitch *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime); - _headYaw *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime); - _headRoll *= (1.0f - DECAY * _head.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(_headPitch) < RETURN_RANGE) { _headPitch *= (1.0f - RETURN_STRENGTH * deltaTime); } - if (fabs(_headYaw) < RETURN_RANGE) { _headYaw *= (1.0f - RETURN_STRENGTH * deltaTime); } - if (fabs(_headRoll) < RETURN_RANGE) { _headRoll *= (1.0f - RETURN_STRENGTH * deltaTime); } - } - - if (_head.noise) { - // Move toward new target - _headPitch += (_head.pitchTarget - _headPitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; - _headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime); - _headRoll *= 1.f - (DECAY * deltaTime); - } - - _head.leanForward *= (1.f - DECAY * 30 * deltaTime); - _head.leanSideways *= (1.f - DECAY * 30 * deltaTime); - - // Update where the avatar's eyes are - // - // First, decide if we are making eye contact or not - if (randFloat() < 0.005) { - _head.eyeContact = !_head.eyeContact; - _head.eyeContact = 1; - if (!_head.eyeContact) { - // If we just stopped making eye contact,move the eyes markedly away - _head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5) * 10; - _head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5) * 5; - } else { - // If now making eye contact, turn head to look right at viewer - SetNewHeadTarget(0,0); - } - } - - const float DEGREES_BETWEEN_VIEWER_EYES = 3; - const float DEGREES_TO_VIEWER_MOUTH = 7; - - if (_head.eyeContact) { - // Should we pick a new eye contact target? - if (randFloat() < 0.01) { - // Choose where to look next - if (randFloat() < 0.1) { - _head.eyeContactTarget = MOUTH; - } else { - if (randFloat() < 0.5) _head.eyeContactTarget = LEFT_EYE; else _head.eyeContactTarget = RIGHT_EYE; - } - } - // Set eyeball pitch and yaw to make contact - float eye_target_yaw_adjust = 0; - float eye_target_pitch_adjust = 0; - if (_head.eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; - if (_head.eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; - if (_head.eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; - - _head.eyeballPitch[0] = _head.eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust; - _head.eyeballYaw[0] = _head.eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust; - } - - if (_head.noise) - { - _headPitch += (randFloat() - 0.5) * 0.2 * _head.noiseEnvelope; - _headYaw += (randFloat() - 0.5) * 0.3 *_head.noiseEnvelope; - //PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope; - - if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3]; - - if (!_head.eyeContact) { - if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5) * 20; - if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5) * 10; - } - - if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _headPitch) < 1.0) && (fabs(_head.yawTarget - _headYaw) < 1.0)) { - SetNewHeadTarget((randFloat()-0.5) * 20.0, (randFloat()-0.5) * 45.0); - } - - if (0) { - - // Pick new target - _head.pitchTarget = (randFloat() - 0.5) * 45; - _head.yawTarget = (randFloat() - 0.5) * 22; - } - if (randFloat() < 0.01) - { - _head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3]; - _head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5]; - _head.eyebrowRoll [1] *=-1; - } - } - - // Update audio trailing average for rendering facial animations - const float AUDIO_AVERAGING_SECS = 0.05; - _head.averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * _head.averageLoudness + - (deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness; -*/ -} - - float Avatar::getHeight() { return _height; } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index beca93b53e..c922098f59 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -195,9 +195,6 @@ private: glm::vec3 _mouseRayDirection; glm::vec3 _cameraPosition; - //AvatarJointID _jointTouched; - - // private methods... void initializeSkeleton(); void updateSkeleton(); @@ -205,7 +202,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/Head.cpp b/interface/src/Head.cpp index 51d3e42c3f..39875873db 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -7,6 +7,7 @@ // #include "Head.h" +#include "Util.h" #include #include #include @@ -15,6 +16,8 @@ using namespace std; const float HEAD_MOTION_DECAY = 0.1; +const bool TESTING_LOOKAT = false; + float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; float _mouthColor[] = {1, 0, 0}; @@ -49,6 +52,7 @@ void Head::initialize() { 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); yaw = 0.0f; pitch = 0.0f; roll = 0.0f; @@ -219,11 +223,21 @@ void Head::simulate(float deltaTime, bool isMine) { const float AUDIO_AVERAGING_SECS = 0.05; averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * averageLoudness + (deltaTime / AUDIO_AVERAGING_SECS) * audioLoudness; + } +void Head::setLookatPosition(glm::vec3 l) { + lookatPosition = l; +} + + + void Head::render(bool lookingInMirror, float bodyYaw) { + +//float a = angleBetween( &position, &position); + int side = 0; glEnable(GL_DEPTH_TEST); @@ -236,11 +250,11 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glScalef(scale, scale, scale); if (lookingInMirror) { - glRotatef(bodyYaw - yaw, 0, 1, 0); + glRotatef(bodyYaw - yaw, 0, 1, 0); glRotatef(pitch, 1, 0, 0); glRotatef(-roll, 0, 0, 1); } else { - glRotatef(bodyYaw + yaw, 0, 1, 0); + glRotatef(bodyYaw + yaw, 0, 1, 0); glRotatef(pitch, 1, 0, 0); glRotatef(roll, 0, 0, 1); } @@ -290,24 +304,37 @@ void Head::render(bool lookingInMirror, float bodyYaw) { // Mouth glPushMatrix(); - glTranslatef(0,-0.35,0.75); - glColor3f(0,0,0); + glTranslatef(0,-0.35,0.75); + glColor3f(0,0,0); - glRotatef(mouthPitch, 1, 0, 0); - glRotatef(mouthYaw, 0, 0, 1); + 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); - } + 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); + glutSolidCube(0.5); glPopMatrix(); - glTranslatef(0, 1.0, 0); + renderEyeBalls(); + glPopMatrix(); + + if (TESTING_LOOKAT) { + //the irises are special - they have the ability to look at specific targets in the world (code still not finished yet) + renderIrises(bodyYaw + yaw); + } +} + + + +void Head::renderEyeBalls() { + + glTranslatef(0, 1.0, 0); glTranslatef(-interPupilDistance/2.0,-0.68,0.7); // Right Eye @@ -322,30 +349,33 @@ void Head::render(bool lookingInMirror, float bodyYaw) { } glPopMatrix(); - // Right Pupil - 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]); + if (!TESTING_LOOKAT) { + // Right Pupil + 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]); + } + + glPushMatrix(); + { + 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); + glDisable(GL_TEXTURE_2D); + } + glPopMatrix(); } - - glPushMatrix(); - { - 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); - glDisable(GL_TEXTURE_2D); - } - - glPopMatrix(); + + // Left Eye glColor3fv(_eyeColor); glTranslatef(interPupilDistance, 0, 0); @@ -357,21 +387,111 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glutSolidSphere(0.25, 30, 30); } glPopMatrix(); - // Left Pupil + + if (!TESTING_LOOKAT) { + // Left Pupil + glPushMatrix(); + { + 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); + glDisable(GL_TEXTURE_2D); + } + glPopMatrix(); + } +} + + +//--------------------------------------------------------- +// the code below is still in the prototyping stages.... +//--------------------------------------------------------- +void Head::renderIrises(float yaw) { + Orientation orientation; + orientation.setToPitchYawRoll( pitch, yaw, roll); + + // Render lines originating from the eyes and converging on the lookatPosition + float rightShift = scale * 0.22f; + float upShift = scale * 0.38f; + float frontShift = scale * 0.9f; + + glm::vec3 leftEyePosition = position + orientation.getRight() * rightShift + + orientation.getUp () * upShift + + orientation.getFront() * frontShift; + glm::vec3 rightEyePosition = position - orientation.getRight() * rightShift + + orientation.getUp () * upShift + + orientation.getFront() * frontShift; + + debugRenderLookatVectors(leftEyePosition, rightEyePosition, lookatPosition); + + glColor3fv(_eyeColor); + + 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]); + } + + //render left iris glPushMatrix(); { - 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); + glTranslatef(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z); + glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - leftEyePosition); - glEnable(GL_TEXTURE_2D); - gluSphere(sphere, pupilSize, 15, 15); - glDisable(GL_TEXTURE_2D); + glPushMatrix(); + glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight()); + glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp()); + + glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); + glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); + glEnable(GL_TEXTURE_2D); + gluSphere(sphere, 0.01, 15, 15); + glDisable(GL_TEXTURE_2D); + glPopMatrix(); } glPopMatrix(); - + + //render right iris + glPushMatrix(); + { + glTranslatef(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z); + glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - rightEyePosition); + + glPushMatrix(); + glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight()); + glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp()); + + glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); + glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); + glEnable(GL_TEXTURE_2D); + gluSphere(sphere, 0.01, 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 ee12098e24..4562f82ad8 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -15,6 +15,7 @@ #include "world.h" #include "InterfaceConfig.h" #include "SerialInterface.h" +#include "Orientation.h" enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; @@ -30,6 +31,7 @@ public: void render(bool lookingInMirror, float bodyYaw); void setNewTarget(float, float); void setSpringScale(float s) { returnSpringScale = s; } + void setLookatPosition(glm::vec3 lookatPosition); // Do you want head to try to return to center (depends on interface detected) void setReturnToCenter(bool r) { returnHeadToCenter = r; } @@ -43,6 +45,7 @@ public: glm::vec3 skinColor; glm::vec3 position; glm::vec3 rotation; + glm::vec3 lookatPosition; float yaw; float pitch; float roll; @@ -85,6 +88,12 @@ public: // Strength of return springs float returnSpringScale; + +private: + void renderEyeBalls(); + void renderIrises(float yaw); + void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); + }; #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 2fd5ef7d3a..54ed1a58b8 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1059,6 +1059,7 @@ void display(void) myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -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, 0.0f); @@ -1086,7 +1087,6 @@ void display(void) glPopMatrix(); */ - // Note: whichCamera is used to pick between the normal camera myCamera for our // main camera, vs, an alternate camera. The alternate camera we support right now // is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp index 447739c32c..1f74cb7f80 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 p, float y, float r) { + + setToIdentity(); + pitch(p); + yaw (y); + roll (r); +} + + void Orientation::set(Orientation o) { quat = o.quat; diff --git a/libraries/avatars/src/Orientation.h b/libraries/avatars/src/Orientation.h index 4bf487be02..ea1dbf16ac 100755 --- a/libraries/avatars/src/Orientation.h +++ b/libraries/avatars/src/Orientation.h @@ -22,6 +22,7 @@ public: Orientation(); void set(Orientation); + void setToPitchYawRoll(float p, float y, float r); void setToIdentity(); void pitch(float p); From a0e8c0da74a119d8fb7e695644957c6e6e224bc8 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Tue, 14 May 2013 18:15:54 -0700 Subject: [PATCH 3/9] more work on avatar lookat --- interface/src/Application.cpp | 1 + interface/src/Avatar.cpp | 23 +- interface/src/Avatar.h | 1 + interface/src/Head.cpp | 27 +- interface/src/Head.h | 3 + interface/src/main.cpp | 2079 +-------------------------------- 6 files changed, 64 insertions(+), 2070 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1cf45ac750..6efa88ad58 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -308,6 +308,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, 0.0f); diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index bd5e255437..f43ed5e319 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -89,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; @@ -404,9 +405,6 @@ void Avatar::simulate(float deltaTime) { } } - - - // Get head position data from network for other people if (!_isMine) { @@ -439,7 +437,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, @@ -447,6 +444,13 @@ void Avatar::simulate(float deltaTime) { _joint[ AVATAR_JOINT_HEAD_BASE ].radius ); + if (_interactingOther) { + _head.setLooking(true); + _head.setLookatPosition(_interactingOther->getSpringyHeadPosition()); + } else { + _head.setLooking(false); + } + _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); _head.simulate(deltaTime, _isMine); @@ -495,10 +499,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++) { @@ -519,10 +524,8 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { } } } - - if (_interactingOther) { - _head.setLookatPosition( _interactingOther->getSpringyHeadPosition()); + if (_interactingOther) { _avatarTouch.setYourBodyPosition(_interactingOther->_position); _avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index c922098f59..06627adadf 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -194,6 +194,7 @@ private: glm::vec3 _mouseRayOrigin; glm::vec3 _mouseRayDirection; glm::vec3 _cameraPosition; + Avatar * _interactingOther; // private methods... void initializeSkeleton(); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 39875873db..479204472b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -16,8 +16,7 @@ using namespace std; const float HEAD_MOTION_DECAY = 0.1; -const bool TESTING_LOOKAT = false; - +//const bool TESTING_LOOKAT = true; float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; float _mouthColor[] = {1, 0, 0}; @@ -226,6 +225,10 @@ void Head::simulate(float deltaTime, bool isMine) { } +void Head::setLooking(bool l) { + _looking = l; +} + void Head::setLookatPosition(glm::vec3 l) { lookatPosition = l; @@ -324,7 +327,7 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glPopMatrix(); - if (TESTING_LOOKAT) { + if (_looking) { //the irises are special - they have the ability to look at specific targets in the world (code still not finished yet) renderIrises(bodyYaw + yaw); } @@ -349,7 +352,7 @@ void Head::renderEyeBalls() { } glPopMatrix(); - if (!TESTING_LOOKAT) { + if (!_looking) { // Right Pupil if (sphere == NULL) { sphere = gluNewQuadric(); @@ -388,7 +391,7 @@ void Head::renderEyeBalls() { } glPopMatrix(); - if (!TESTING_LOOKAT) { + if (!_looking) { // Left Pupil glPushMatrix(); { @@ -449,8 +452,11 @@ void Head::renderIrises(float yaw) { glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight()); glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp()); - glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); - glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); + float yaw = angleBetween(targetLookatAxis, orientation.getUp()); + float pitch = angleBetween(targetLookatAxis, orientation.getRight()); + + glRotatef(yaw, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); + glRotatef(pitch, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); glEnable(GL_TEXTURE_2D); gluSphere(sphere, 0.01, 15, 15); glDisable(GL_TEXTURE_2D); @@ -468,8 +474,11 @@ void Head::renderIrises(float yaw) { glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight()); glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp()); - glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); - glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); + float yaw = angleBetween(targetLookatAxis, orientation.getUp()); + float pitch = angleBetween(targetLookatAxis, orientation.getRight()); + + glRotatef(yaw, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); + glRotatef(pitch, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); glEnable(GL_TEXTURE_2D); gluSphere(sphere, 0.01, 15, 15); glDisable(GL_TEXTURE_2D); diff --git a/interface/src/Head.h b/interface/src/Head.h index 4562f82ad8..5d4ccaec31 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -32,6 +32,7 @@ public: void setNewTarget(float, float); void setSpringScale(float s) { returnSpringScale = s; } void setLookatPosition(glm::vec3 lookatPosition); + void setLooking(bool looking); // Do you want head to try to return to center (depends on interface detected) void setReturnToCenter(bool r) { returnHeadToCenter = r; } @@ -84,6 +85,8 @@ public: float averageLoudness; float audioAttack; + bool _looking; + GLUquadric* sphere; // Strength of return springs diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b88510d554..58bad2db2f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1,2051 +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 "Camera.h" -#include "Avatar.h" -#include -#include -#include "VoxelSystem.h" -#include "Environment.h" -#include "Oscilloscope.h" -#include "UDPSocket.h" -#include "SerialInterface.h" -#include -#include -#include -#include - -#include "ViewFrustum.h" -#include "HandControl.h" -#include "AvatarRenderer.h" -#include "OculusManager.h" - -using namespace std; - -void reshape(int width, int height); // will be defined below -void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below - -glm::vec3 getGravity(glm::vec3 pos); //get the local gravity vector at this location in the universe - -bool enableNetworkThread = true; -pthread_t networkReceiveThread; -bool stopNetworkReceiveThread = false; - -unsigned char incomingPacket[MAX_PACKET_SIZE]; -int packetCount = 0; -int packetsPerSecond = 0; -int bytesPerSecond = 0; -int bytesCount = 0; - -int screenWidth = 1200; // Window size -int screenHeight = 800; - -int fullscreen = 0; -float aspectRatio = 1.0f; - -// PER: Jeffrey - please move these our of main.cpp - also these not constants! -float mouseViewShiftYaw = 0.0f; -float mouseViewShiftPitch = 0.0f; -bool USING_MOUSE_VIEW_SHIFT = false; -float MOUSE_VIEW_SHIFT_RATE = 40.0f; -float MOUSE_VIEW_SHIFT_YAW_MARGIN = (float)(::screenWidth * 0.2f); -float MOUSE_VIEW_SHIFT_PITCH_MARGIN = (float)(::screenHeight * 0.2f); -float MOUSE_VIEW_SHIFT_YAW_LIMIT = 45.0; -float MOUSE_VIEW_SHIFT_PITCH_LIMIT = 30.0; - -bool wantColorRandomizer = true; // for addSphere and load file - -Oscilloscope audioScope(256,200,true); - -ViewFrustum viewFrustum; // current state of view frustum, perspective, orientation, etc. - -Avatar myAvatar(true); // The rendered avatar of oneself -Camera myCamera; // My view onto the world -Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode - -AvatarRenderer avatarRenderer; - -// Starfield information -char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; -char starCacheFile[] = "cachedStars.txt"; -Stars stars; - -glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE); - -VoxelSystem voxels; - -Environment environment; - - -#ifndef _WIN32 -Audio audio(&audioScope, &myAvatar); -#endif - -#define IDLE_SIMULATE_MSECS 16 // How often should call simulate and other stuff - // in the idle loop? (60 FPS is default) - - -glm::vec3 start_location(6.1f, 0, 1.4f); // Where one's own agent begins in the world - // (will be overwritten if avatar data file is found) - -bool renderWarningsOn = false; // Whether to show render pipeline warnings -bool renderStatsOn = false; // Whether to show onscreen text overlay with stats -bool renderVoxels = true; // Whether to render voxels -bool renderStarsOn = true; // Whether to display the stars -bool renderAtmosphereOn = true; // Whether to display the atmosphere -bool renderAvatarsOn = true; // Whether to render avatars -bool renderFirstPersonOn = false; // Whether to render in first person -bool paintOn = false; // Whether to paint voxels as you fly around -VoxelDetail paintingVoxel; // The voxel we're painting if we're painting -unsigned char dominantColor = 0; // The dominant color of the voxel we're painting -bool perfStatsOn = false; // Do we want to display perfStats? -bool wantMonochrome = false; // ask server to send us in monochrome -bool wantResIn = false; // ask server to res in - -bool logOn = true; // Whether to show on-screen log - -bool wantToKillLocalVoxels = false; - -int noiseOn = 0; // Whether to add random noise -float noise = 1.0; // Overall magnitude scaling for random noise levels - -bool gyroLook = true; // Whether to allow the gyro data from head to move your view - -int displayLevels = 0; -bool lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror? - -int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement -int headMouseX, headMouseY; - -HandControl handControl; - -int mouseX = 0; -int mouseY = 0; - -// Mouse location at start of last down click -int mousePressed = 0; // true if mouse has been pressed (clear when finished) - -// The current mode for mouse interaction -enum MouseMode { NO_EDIT_MODE, ADD_VOXEL_MODE, DELETE_VOXEL_MODE, COLOR_VOXEL_MODE }; -MouseMode mouseMode = NO_EDIT_MODE; -VoxelDetail mouseVoxel; // details of the voxel under the mouse cursor -float mouseVoxelScale = 1.0f / 1024.0f; // the scale for adding/removing voxels - -Menu menu; // main menu -int menuOn = 1; // Whether to show onscreen menu - -ChatEntry chatEntry; // chat entry field -bool chatEntryOn = false; // Whether to show the chat entry - -bool oculusOn = false; // Whether to configure the display for the Oculus Rift -GLuint oculusTextureID = 0; // The texture to which we render for Oculus distortion -ProgramObject* oculusProgram = 0; // The GLSL program containing the distortion shader -float oculusDistortionScale = 1.25; // Controls the Oculus field of viewa - -SerialInterface serialPort; - -glm::vec3 gravity; - -// Frame Rate Measurement - -int frameCount = 0; -float FPS = 120.f; -timeval timerStart, timerEnd; -timeval lastTimeIdle; -double elapsedTime; -timeval applicationStartupTime; -bool justStarted = true; - -// Every second, check the frame rates and other stuff -void Timer(int extra) { - gettimeofday(&timerEnd, NULL); - FPS = (float)frameCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); - packetsPerSecond = (float)packetCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); - bytesPerSecond = (float)bytesCount / ((float)diffclock(&timerStart, &timerEnd) / 1000.f); - frameCount = 0; - packetCount = 0; - bytesCount = 0; - - glutTimerFunc(1000,Timer,0); - gettimeofday(&timerStart, NULL); - - // if we haven't detected gyros, check for them now - if (!serialPort.active) { - serialPort.pair(); - } -} - -void displayStats(void) { - int statsVerticalOffset = 50; - if (::menuOn == 0) { - statsVerticalOffset = 8; - } - - char stats[200]; - sprintf(stats, "%3.0f FPS, %d Pkts/sec, %3.2f Mbps", - FPS, packetsPerSecond, (float)bytesPerSecond * 8.f / 1000000.f); - drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, stats); - - std::stringstream voxelStats; - voxelStats.precision(4); - voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered() / 1000.f << "K Updated: " << voxels.getVoxelsUpdated()/1000.f << "K"; - drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - - voxelStats.str(""); - voxelStats << "Voxels Created: " << voxels.getVoxelsCreated() / 1000.f << "K (" << voxels.getVoxelsCreatedPerSecondAverage() / 1000.f - << "Kps) "; - drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - - voxelStats.str(""); - voxelStats << "Voxels Colored: " << voxels.getVoxelsColored() / 1000.f << "K (" << voxels.getVoxelsColoredPerSecondAverage() / 1000.f - << "Kps) "; - drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - - voxelStats.str(""); - voxelStats << "Voxel Bits Read: " << voxels.getVoxelsBytesRead() * 8.f / 1000000.f - << "M (" << voxels.getVoxelsBytesReadPerSecondAverage() * 8.f / 1000000.f << " Mbps)"; - drawtext(10, statsVerticalOffset + 290,0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - - voxelStats.str(""); - float voxelsBytesPerColored = voxels.getVoxelsColored() - ? ((float) voxels.getVoxelsBytesRead() / voxels.getVoxelsColored()) - : 0; - - voxelStats << "Voxels Bits per Colored: " << voxelsBytesPerColored * 8; - drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); - - Agent *avatarMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); - char avatarMixerStats[200]; - - if (avatarMixer) { - sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps", - roundf(avatarMixer->getAverageKilobitsPerSecond()), - roundf(avatarMixer->getAveragePacketsPerSecond())); - } else { - sprintf(avatarMixerStats, "No Avatar Mixer"); - } - - drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats); - - if (::perfStatsOn) { - // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups - char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; - int lines = PerfStat::DumpStats(perfStatLinesArray); - int atZ = 150; // arbitrary place on screen that looks good - for (int line=0; line < lines; line++) { - drawtext(10, statsVerticalOffset + atZ, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); - delete perfStatLinesArray[line]; // we're responsible for cleanup - perfStatLinesArray[line]=NULL; - atZ+=20; // height of a line - } - delete []perfStatLinesArray; // we're responsible for cleanup - } -} - -void initDisplay(void) { - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glShadeModel (GL_SMOOTH); - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_DEPTH_TEST); - - if (fullscreen) glutFullScreen(); -} - -void init(void) { - voxels.init(); - voxels.setViewerAvatar(&myAvatar); - voxels.setCamera(&myCamera); - - environment.init(); - - handControl.setScreenDimensions(::screenWidth, ::screenHeight); - - headMouseX = ::screenWidth /2; - headMouseY = ::screenHeight/2; - - stars.readInput(starFile, starCacheFile, 0); - - if (noiseOn) { - myAvatar.setNoise(noise); - } - - myAvatar.setPosition(start_location); - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); - myCamera.initialize(); - myAvatar.setDisplayingHead(true); - - OculusManager::connect(); - - gettimeofday(&timerStart, NULL); - gettimeofday(&lastTimeIdle, NULL); -} - -void terminate () { - // Close serial port - // close(serial_fd); - - myAvatar.writeAvatarDataToFile(); - - #ifndef _WIN32 - audio.terminate(); - #endif - - if (enableNetworkThread) { - stopNetworkReceiveThread = true; - pthread_join(networkReceiveThread, NULL); - } - - exit(EXIT_SUCCESS); -} - -void resetSensors() { - - myAvatar.setPosition(start_location); - headMouseX = ::screenWidth / 2; - headMouseY = ::screenHeight / 2; - if (serialPort.active) { - serialPort.resetAverages(); - } - myAvatar.reset(); -} - -void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) { - unsigned char* bufferOut; - int sizeOut; - - if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){ - AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1); - delete bufferOut; - } -} - -// Using gyro data, update both view frustum and avatar head position -void updateAvatar(float deltaTime) { - - // Update my avatar's head position from gyros - myAvatar.updateHeadFromGyros(deltaTime, &serialPort, &gravity); - - // Grab latest readings from the gyros - float measuredPitchRate = serialPort.getLastPitchRate(); - float measuredYawRate = serialPort.getLastYawRate(); - - // Update gyro-based mouse (X,Y on screen) - const float MIN_MOUSE_RATE = 1.0; - const float HORIZONTAL_PIXELS_PER_DEGREE = 2880.f / 45.f; - const float VERTICAL_PIXELS_PER_DEGREE = 1800.f / 30.f; - if (powf(measuredYawRate * measuredYawRate + - measuredPitchRate * measuredPitchRate, 0.5) > MIN_MOUSE_RATE) - { - headMouseX += measuredYawRate * HORIZONTAL_PIXELS_PER_DEGREE * deltaTime; - headMouseY -= measuredPitchRate * VERTICAL_PIXELS_PER_DEGREE * deltaTime; - } - headMouseX = max(headMouseX, 0); - headMouseX = min(headMouseX, ::screenWidth); - headMouseY = max(headMouseY, 0); - headMouseY = min(headMouseY, ::screenHeight); - - // Update head and body pitch and yaw based on measured gyro rates - if (::gyroLook) { - // Render Yaw - float renderYawSpring = fabs(headMouseX - ::screenWidth / 2.f) / (::screenWidth / 2.f); - const float RENDER_YAW_MULTIPLY = 4.f; - myAvatar.setRenderYaw((1.f - renderYawSpring * deltaTime) * myAvatar.getRenderYaw() + - renderYawSpring * deltaTime * -myAvatar.getHeadYaw() * RENDER_YAW_MULTIPLY); - // Render Pitch - float renderPitchSpring = fabs(headMouseY - ::screenHeight / 2.f) / (::screenHeight / 2.f); - const float RENDER_PITCH_MULTIPLY = 4.f; - myAvatar.setRenderPitch((1.f - renderPitchSpring * deltaTime) * myAvatar.getRenderPitch() + - renderPitchSpring * deltaTime * -myAvatar.getHeadPitch() * RENDER_PITCH_MULTIPLY); - } - - - if (USING_MOUSE_VIEW_SHIFT) - { - //make it so that when your mouse hits the edge of the screen, the camera shifts - float rightBoundary = (float)::screenWidth - MOUSE_VIEW_SHIFT_YAW_MARGIN; - float bottomBoundary = (float)::screenHeight - MOUSE_VIEW_SHIFT_PITCH_MARGIN; - - if (mouseX > rightBoundary) { - float f = (mouseX - rightBoundary) / ( (float)::screenWidth - rightBoundary); - mouseViewShiftYaw += MOUSE_VIEW_SHIFT_RATE * f * deltaTime; - if (mouseViewShiftYaw > MOUSE_VIEW_SHIFT_YAW_LIMIT) { mouseViewShiftYaw = MOUSE_VIEW_SHIFT_YAW_LIMIT; } - } else if (mouseX < MOUSE_VIEW_SHIFT_YAW_MARGIN) { - float f = 1.0 - (mouseX / MOUSE_VIEW_SHIFT_YAW_MARGIN); - mouseViewShiftYaw -= MOUSE_VIEW_SHIFT_RATE * f * deltaTime; - if (mouseViewShiftYaw < -MOUSE_VIEW_SHIFT_YAW_LIMIT) { mouseViewShiftYaw = -MOUSE_VIEW_SHIFT_YAW_LIMIT; } - } - if (mouseY < MOUSE_VIEW_SHIFT_PITCH_MARGIN) { - float f = 1.0 - (mouseY / MOUSE_VIEW_SHIFT_PITCH_MARGIN); - mouseViewShiftPitch += MOUSE_VIEW_SHIFT_RATE * f * deltaTime; - if ( mouseViewShiftPitch > MOUSE_VIEW_SHIFT_PITCH_LIMIT ) { mouseViewShiftPitch = MOUSE_VIEW_SHIFT_PITCH_LIMIT; } - } - else if (mouseY > bottomBoundary) { - float f = (mouseY - bottomBoundary) / ((float)::screenHeight - bottomBoundary); - mouseViewShiftPitch -= MOUSE_VIEW_SHIFT_RATE * f * deltaTime; - if (mouseViewShiftPitch < -MOUSE_VIEW_SHIFT_PITCH_LIMIT) { mouseViewShiftPitch = -MOUSE_VIEW_SHIFT_PITCH_LIMIT; } - } - } - - if (OculusManager::isConnected()) { - float yaw, pitch, roll; - OculusManager::getEulerAngles(yaw, pitch, roll); - - myAvatar.setHeadYaw(-yaw); - myAvatar.setHeadPitch(pitch); - myAvatar.setHeadRoll(roll); - } - - // Get audio loudness data from audio input device - #ifndef _WIN32 - myAvatar.setLoudness(audio.getInputLoudness()); - #endif - - // Update Avatar with latest camera and view frustum data... - // NOTE: we get this from the view frustum, to make it simpler, since the - // loadViewFrumstum() method will get the correct details from the camera - // We could optimize this to not actually load the viewFrustum, since we don't - // actually need to calculate the view frustum planes to send these details - // to the server. - loadViewFrustum(::viewFrustum); - myAvatar.setCameraPosition(::viewFrustum.getPosition()); - myAvatar.setCameraDirection(::viewFrustum.getDirection()); - myAvatar.setCameraUp(::viewFrustum.getUp()); - myAvatar.setCameraRight(::viewFrustum.getRight()); - myAvatar.setCameraFov(::viewFrustum.getFieldOfView()); - myAvatar.setCameraAspectRatio(::viewFrustum.getAspectRatio()); - myAvatar.setCameraNearClip(::viewFrustum.getNearClip()); - myAvatar.setCameraFarClip(::viewFrustum.getFarClip()); - - AgentList* agentList = AgentList::getInstance(); - if (agentList->getOwnerID() != UNKNOWN_AGENT_ID) { - // if I know my ID, send head/hand data to the avatar mixer and voxel server - unsigned char broadcastString[200]; - unsigned char* endOfBroadcastStringWrite = broadcastString; - - *(endOfBroadcastStringWrite++) = PACKET_HEADER_HEAD_DATA; - endOfBroadcastStringWrite += packAgentId(endOfBroadcastStringWrite, agentList->getOwnerID()); - - endOfBroadcastStringWrite += myAvatar.getBroadcastData(endOfBroadcastStringWrite); - - const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER}; - AgentList::getInstance()->broadcastToAgents(broadcastString, endOfBroadcastStringWrite - broadcastString, broadcastReceivers, sizeof(broadcastReceivers)); - } - - // If I'm in paint mode, send a voxel out to VOXEL server agents. - if (::paintOn) { - - glm::vec3 avatarPos = myAvatar.getPosition(); - - // For some reason, we don't want to flip X and Z here. - ::paintingVoxel.x = avatarPos.x / 10.0; - ::paintingVoxel.y = avatarPos.y / 10.0; - ::paintingVoxel.z = avatarPos.z / 10.0; - - if (::paintingVoxel.x >= 0.0 && ::paintingVoxel.x <= 1.0 && - ::paintingVoxel.y >= 0.0 && ::paintingVoxel.y <= 1.0 && - ::paintingVoxel.z >= 0.0 && ::paintingVoxel.z <= 1.0) { - - sendVoxelEditMessage(PACKET_HEADER_SET_VOXEL, ::paintingVoxel); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////// -// loadViewFrustum() -// -// Description: this will load the view frustum bounds for EITHER the head -// or the "myCamera". -// - -// These global scoped variables are used by our loadViewFrustum() and renderViewFrustum functions below, but are also -// available as globals so that the keyboard and menu can manipulate them. - -bool frustumOn = false; // Whether or not to display the debug view frustum -bool cameraFrustum = true; // which frustum to look at - -bool viewFrustumFromOffset =false; // Wether or not to offset the view of the frustum -float viewFrustumOffsetYaw = -135.0; // the following variables control yaw, pitch, roll and distance form regular -float viewFrustumOffsetPitch = 0.0; // camera to the offset camera -float viewFrustumOffsetRoll = 0.0; -float viewFrustumOffsetDistance = 25.0; -float viewFrustumOffsetUp = 0.0; - -void loadViewFrustum(ViewFrustum& viewFrustum) { - // We will use these below, from either the camera or head vectors calculated above - glm::vec3 position; - glm::vec3 direction; - glm::vec3 up; - glm::vec3 right; - float fov, nearClip, farClip; - - // Camera or Head? - if (::cameraFrustum) { - position = ::myCamera.getPosition(); - } else { - position = ::myAvatar.getHeadPosition(); - } - - fov = ::myCamera.getFieldOfView(); - nearClip = ::myCamera.getNearClip(); - farClip = ::myCamera.getFarClip(); - - Orientation o = ::myCamera.getOrientation(); - - direction = o.getFront(); - up = o.getUp(); - right = o.getRight(); - - /* - printf("position.x=%f, position.y=%f, position.z=%f\n", position.x, position.y, position.z); - printf("yaw=%f, pitch=%f, roll=%f\n", yaw,pitch,roll); - printf("direction.x=%f, direction.y=%f, direction.z=%f\n", direction.x, direction.y, direction.z); - printf("up.x=%f, up.y=%f, up.z=%f\n", up.x, up.y, up.z); - printf("right.x=%f, right.y=%f, right.z=%f\n", right.x, right.y, right.z); - printf("fov=%f\n", fov); - printf("nearClip=%f\n", nearClip); - printf("farClip=%f\n", farClip); - */ - - // Set the viewFrustum up with the correct position and orientation of the camera - viewFrustum.setPosition(position); - viewFrustum.setOrientation(direction,up,right); - - // Also make sure it's got the correct lens details from the camera - viewFrustum.setFieldOfView(fov); - viewFrustum.setNearClip(nearClip); - viewFrustum.setFarClip(farClip); - - // Ask the ViewFrustum class to calculate our corners - viewFrustum.calculate(); -} - -///////////////////////////////////////////////////////////////////////////////////// -// renderViewFrustum() -// -// Description: this will render the view frustum bounds for EITHER the head -// or the "myCamera". -// -// Frustum rendering mode. For debug purposes, we allow drawing the frustum in a couple of different ways. -// We can draw it with each of these parts: -// * Origin Direction/Up/Right vectors - these will be drawn at the point of the camera -// * Near plane - this plane is drawn very close to the origin point. -// * Right/Left planes - these two planes are drawn between the near and far planes. -// * Far plane - the plane is drawn in the distance. -// Modes - the following modes, will draw the following parts. -// * All - draws all the parts listed above -// * Planes - draws the planes but not the origin vectors -// * Origin Vectors - draws the origin vectors ONLY -// * Near Plane - draws only the near plane -// * Far Plane - draws only the far plane -#define FRUSTUM_DRAW_MODE_ALL 0 -#define FRUSTUM_DRAW_MODE_VECTORS 1 -#define FRUSTUM_DRAW_MODE_PLANES 2 -#define FRUSTUM_DRAW_MODE_NEAR_PLANE 3 -#define FRUSTUM_DRAW_MODE_FAR_PLANE 4 -#define FRUSTUM_DRAW_MODE_COUNT 5 - -int frustumDrawingMode = FRUSTUM_DRAW_MODE_ALL; // the mode we're drawing the frustum in, see notes above - -void renderViewFrustum(ViewFrustum& viewFrustum) { - - // Load it with the latest details! - loadViewFrustum(viewFrustum); - - glm::vec3 position = viewFrustum.getPosition(); - glm::vec3 direction = viewFrustum.getDirection(); - glm::vec3 up = viewFrustum.getUp(); - glm::vec3 right = viewFrustum.getRight(); - - // Get ready to draw some lines - glDisable(GL_LIGHTING); - glColor4f(1.0, 1.0, 1.0, 1.0); - glLineWidth(1.0); - glBegin(GL_LINES); - - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_VECTORS) { - // Calculate the origin direction vectors - glm::vec3 lookingAt = position + (direction * 0.2f); - glm::vec3 lookingAtUp = position + (up * 0.2f); - glm::vec3 lookingAtRight = position + (right * 0.2f); - - // Looking At = white - glColor3f(1,1,1); - glVertex3f(position.x, position.y, position.z); - glVertex3f(lookingAt.x, lookingAt.y, lookingAt.z); - - // Looking At Up = purple - glColor3f(1,0,1); - glVertex3f(position.x, position.y, position.z); - glVertex3f(lookingAtUp.x, lookingAtUp.y, lookingAtUp.z); - - // Looking At Right = cyan - glColor3f(0,1,1); - glVertex3f(position.x, position.y, position.z); - glVertex3f(lookingAtRight.x, lookingAtRight.y, lookingAtRight.z); - } - - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES - || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_NEAR_PLANE) { - // Drawing the bounds of the frustum - // viewFrustum.getNear plane - bottom edge - glColor3f(1,0,0); - glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); - glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); - - // viewFrustum.getNear plane - top edge - glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); - glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); - - // viewFrustum.getNear plane - right edge - glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); - glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); - - // viewFrustum.getNear plane - left edge - glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); - glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); - } - - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES - || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_FAR_PLANE) { - // viewFrustum.getFar plane - bottom edge - glColor3f(0,1,0); // GREEN!!! - glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); - glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); - - // viewFrustum.getFar plane - top edge - glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); - glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); - - // viewFrustum.getFar plane - right edge - glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); - glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); - - // viewFrustum.getFar plane - left edge - glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); - glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); - } - - if (::frustumDrawingMode == FRUSTUM_DRAW_MODE_ALL || ::frustumDrawingMode == FRUSTUM_DRAW_MODE_PLANES) { - // RIGHT PLANE IS CYAN - // right plane - bottom edge - viewFrustum.getNear to distant - glColor3f(0,1,1); - glVertex3f(viewFrustum.getNearBottomRight().x, viewFrustum.getNearBottomRight().y, viewFrustum.getNearBottomRight().z); - glVertex3f(viewFrustum.getFarBottomRight().x, viewFrustum.getFarBottomRight().y, viewFrustum.getFarBottomRight().z); - - // right plane - top edge - viewFrustum.getNear to distant - glVertex3f(viewFrustum.getNearTopRight().x, viewFrustum.getNearTopRight().y, viewFrustum.getNearTopRight().z); - glVertex3f(viewFrustum.getFarTopRight().x, viewFrustum.getFarTopRight().y, viewFrustum.getFarTopRight().z); - - // LEFT PLANE IS BLUE - // left plane - bottom edge - viewFrustum.getNear to distant - glColor3f(0,0,1); - glVertex3f(viewFrustum.getNearBottomLeft().x, viewFrustum.getNearBottomLeft().y, viewFrustum.getNearBottomLeft().z); - glVertex3f(viewFrustum.getFarBottomLeft().x, viewFrustum.getFarBottomLeft().y, viewFrustum.getFarBottomLeft().z); - - // left plane - top edge - viewFrustum.getNear to distant - glVertex3f(viewFrustum.getNearTopLeft().x, viewFrustum.getNearTopLeft().y, viewFrustum.getNearTopLeft().z); - glVertex3f(viewFrustum.getFarTopLeft().x, viewFrustum.getFarTopLeft().y, viewFrustum.getFarTopLeft().z); - } - - glEnd(); - glEnable(GL_LIGHTING); -} - -// displays a single side (left, right, or combined for non-Oculus) -void displaySide(Camera& whichCamera) { - glPushMatrix(); - - if (::renderStarsOn) { - // should be the first rendering pass - w/o depth buffer / lighting - - // compute starfield alpha based on distance from atmosphere - float alpha = 1.0f; - if (::renderAtmosphereOn) { - float height = glm::distance(whichCamera.getPosition(), environment.getAtmosphereCenter()); - if (height < environment.getAtmosphereInnerRadius()) { - alpha = 0.0f; - - } else if (height < environment.getAtmosphereOuterRadius()) { - alpha = (height - environment.getAtmosphereInnerRadius()) / - (environment.getAtmosphereOuterRadius() - environment.getAtmosphereInnerRadius()); - } - } - - // finally render the starfield - stars.render(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), whichCamera.getNearClip(), alpha); - } - - // draw the sky dome - if (::renderAtmosphereOn) { - environment.renderAtmosphere(whichCamera); - } - - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - - // draw a red sphere - float sphereRadius = 0.25f; - glColor3f(1,0,0); - glPushMatrix(); - glutSolidSphere(sphereRadius, 15, 15); - glPopMatrix(); - - //draw a grid ground plane.... - drawGroundPlaneGrid(10.f); - - // Draw voxels - if (renderVoxels) { - voxels.render(); - } - - // indicate what we'll be adding/removing in mouse mode, if anything - if (::mouseVoxel.s != 0) { - glPushMatrix(); - if (::mouseMode == ADD_VOXEL_MODE) { - // use a contrasting color so that we can see what we're doing - glColor3ub(::mouseVoxel.red + 128, ::mouseVoxel.green + 128, ::mouseVoxel.blue + 128); - } else { - glColor3ub(::mouseVoxel.red, ::mouseVoxel.green, ::mouseVoxel.blue); - } - glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE); - glTranslatef(::mouseVoxel.x + ::mouseVoxel.s*0.5f, - ::mouseVoxel.y + ::mouseVoxel.s*0.5f, - ::mouseVoxel.z + ::mouseVoxel.s*0.5f); - glLineWidth(4.0f); - glutWireCube(::mouseVoxel.s); - glLineWidth(1.0f); - glPopMatrix(); - } - - if (::renderAvatarsOn) { - // Render avatars of other agents - AgentList* agentList = AgentList::getInstance(); - agentList->lock(); - for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { - Avatar *avatar = (Avatar *)agent->getLinkedData(); - avatar->render(0, ::myCamera.getPosition()); - } - } - agentList->unlock(); - - // Render my own Avatar - myAvatar.render(::lookingInMirror, ::myCamera.getPosition()); - } - - // Render the world box - if (!::lookingInMirror && ::renderStatsOn) { render_world_box(); } - - // brad's frustum for debugging - if (::frustumOn) renderViewFrustum(::viewFrustum); - - glPopMatrix(); -} - -// this shader is an adaptation (HLSL -> GLSL, removed conditional) of the one in the Oculus sample -// code (Samples/OculusRoomTiny/RenderTiny_D3D1X_Device.cpp), which is under the Apache license -// (http://www.apache.org/licenses/LICENSE-2.0) -const char* DISTORTION_FRAGMENT_SHADER = - "#version 120\n" - "uniform sampler2D texture;" - "uniform vec2 lensCenter;" - "uniform vec2 screenCenter;" - "uniform vec2 scale;" - "uniform vec2 scaleIn;" - "uniform vec4 hmdWarpParam;" - "vec2 hmdWarp(vec2 in01) {" - " vec2 theta = (in01 - lensCenter) * scaleIn;" - " float rSq = theta.x * theta.x + theta.y * theta.y;" - " vec2 theta1 = theta * (hmdWarpParam.x + hmdWarpParam.y * rSq + " - " hmdWarpParam.z * rSq * rSq + hmdWarpParam.w * rSq * rSq * rSq);" - " return lensCenter + scale * theta1;" - "}" - "void main(void) {" - " vec2 tc = hmdWarp(gl_TexCoord[0].st);" - " vec2 below = step(screenCenter.st + vec2(-0.25, -0.5), tc.st);" - " vec2 above = vec2(1.0, 1.0) - step(screenCenter.st + vec2(0.25, 0.5), tc.st);" - " gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 1.0), texture2D(texture, tc), " - " above.s * above.t * below.s * below.t);" - "}"; - -// the locations of the uniform variables -int textureLocation; -int lensCenterLocation; -int screenCenterLocation; -int scaleLocation; -int scaleInLocation; -int hmdWarpParamLocation; - -// renders both sides into a texture, then renders the texture to the display with distortion -void displayOculus(Camera& whichCamera) { - // magic numbers ahoy! in order to avoid pulling in the Oculus utility library that calculates - // the rendering parameters from the hardware stats, i just folded their calculations into - // constants using the stats for the current-model hardware as contained in the SDK file - // LibOVR/Src/Util/Util_Render_Stereo.cpp - - // eye - - // render the left eye view to the left side of the screen - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glTranslatef(0.151976, 0, 0); // +h, see Oculus SDK docs p. 26 - gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), - whichCamera.getNearClip(), whichCamera.getFarClip()); - glTranslatef(0.032, 0, 0); // dip/2, see p. 27 - - glMatrixMode(GL_MODELVIEW); - glViewport(0, 0, ::screenWidth / 2, ::screenHeight); - displaySide(whichCamera); - - // and the right eye to the right side - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glTranslatef(-0.151976, 0, 0); // -h - gluPerspective(whichCamera.getFieldOfView(), whichCamera.getAspectRatio(), - whichCamera.getNearClip(), whichCamera.getFarClip()); - glTranslatef(-0.032, 0, 0); - - glMatrixMode(GL_MODELVIEW); - glViewport(::screenWidth / 2, 0, ::screenWidth / 2, ::screenHeight); - displaySide(whichCamera); - - glPopMatrix(); - - // restore our normal viewport - glViewport(0, 0, ::screenWidth, ::screenHeight); - - if (::oculusTextureID == 0) { - glGenTextures(1, &::oculusTextureID); - glBindTexture(GL_TEXTURE_2D, ::oculusTextureID); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ::screenWidth, ::screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - ::oculusProgram = new ProgramObject(); - ::oculusProgram->attachFromSourceCode(GL_FRAGMENT_SHADER_ARB, DISTORTION_FRAGMENT_SHADER); - ::oculusProgram->link(); - - textureLocation = ::oculusProgram->getUniformLocation("texture"); - lensCenterLocation = ::oculusProgram->getUniformLocation("lensCenter"); - screenCenterLocation = ::oculusProgram->getUniformLocation("screenCenter"); - scaleLocation = ::oculusProgram->getUniformLocation("scale"); - scaleInLocation = ::oculusProgram->getUniformLocation("scaleIn"); - hmdWarpParamLocation = ::oculusProgram->getUniformLocation("hmdWarpParam"); - - } else { - glBindTexture(GL_TEXTURE_2D, ::oculusTextureID); - } - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, ::screenWidth, ::screenHeight); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0, ::screenWidth, 0, ::screenHeight); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - - // for reference on setting these values, see SDK file Samples/OculusRoomTiny/RenderTiny_Device.cpp - - float scaleFactor = 1.0 / ::oculusDistortionScale; - float aspectRatio = (::screenWidth * 0.5) / ::screenHeight; - - glDisable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - ::oculusProgram->bind(); - ::oculusProgram->setUniform(textureLocation, 0); - ::oculusProgram->setUniform(lensCenterLocation, 0.287994, 0.5); // see SDK docs, p. 29 - ::oculusProgram->setUniform(screenCenterLocation, 0.25, 0.5); - ::oculusProgram->setUniform(scaleLocation, 0.25 * scaleFactor, 0.5 * scaleFactor * aspectRatio); - ::oculusProgram->setUniform(scaleInLocation, 4, 2 / aspectRatio); - ::oculusProgram->setUniform(hmdWarpParamLocation, 1.0, 0.22, 0.24, 0); - - glColor3f(1, 0, 1); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2f(0, 0); - glTexCoord2f(0.5, 0); - glVertex2f(::screenWidth/2, 0); - glTexCoord2f(0.5, 1); - glVertex2f(::screenWidth / 2, ::screenHeight); - glTexCoord2f(0, 1); - glVertex2f(0, ::screenHeight); - glEnd(); - - ::oculusProgram->setUniform(lensCenterLocation, 0.787994, 0.5); - ::oculusProgram->setUniform(screenCenterLocation, 0.75, 0.5); - - glBegin(GL_QUADS); - glTexCoord2f(0.5, 0); - glVertex2f(::screenWidth / 2, 0); - glTexCoord2f(1, 0); - glVertex2f(::screenWidth, 0); - glTexCoord2f(1, 1); - glVertex2f(::screenWidth, ::screenHeight); - glTexCoord2f(0.5, 1); - glVertex2f(::screenWidth / 2, ::screenHeight); - glEnd(); - - glEnable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); - ::oculusProgram->release(); - - glPopMatrix(); -} - -void displayOverlay() { - // Render 2D overlay: I/O level bar graphs and text - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, ::screenWidth, ::screenHeight, 0); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - - #ifndef _WIN32 - audio.render(::screenWidth, ::screenHeight); - audioScope.render(20, ::screenHeight - 200); - #endif - - //noiseTest(::screenWidth, ::screenHeight); - - if (displayHeadMouse && !::lookingInMirror && USING_INVENSENSE_MPU9150) { - // Display small target box at center or head mouse target that can also be used to measure LOD - glColor3f(1.0, 1.0, 1.0); - glDisable(GL_LINE_SMOOTH); - const int PIXEL_BOX = 20; - glBegin(GL_LINE_STRIP); - glVertex2f(headMouseX - PIXEL_BOX/2, headMouseY - PIXEL_BOX/2); - glVertex2f(headMouseX + PIXEL_BOX/2, headMouseY - PIXEL_BOX/2); - glVertex2f(headMouseX + PIXEL_BOX/2, headMouseY + PIXEL_BOX/2); - glVertex2f(headMouseX - PIXEL_BOX/2, headMouseY + PIXEL_BOX/2); - glVertex2f(headMouseX - PIXEL_BOX/2, headMouseY - PIXEL_BOX/2); - glEnd(); - glEnable(GL_LINE_SMOOTH); - } - - // Show detected levels from the serial I/O ADC channel sensors - if (displayLevels) serialPort.renderLevels(::screenWidth,::screenHeight); - - // Display stats and log text onscreen - glLineWidth(1.0f); - glPointSize(1.0f); - - if (::renderStatsOn) { displayStats(); } - if (::logOn) { logger.render(::screenWidth, ::screenHeight); } - - // Show menu - if (::menuOn) { - glLineWidth(1.0f); - glPointSize(1.0f); - menu.render(::screenWidth,::screenHeight); - } - - // Show chat entry field - if (::chatEntryOn) { - chatEntry.render(::screenWidth, ::screenHeight); - } - - // Stats at upper right of screen about who domain server is telling us about - glPointSize(1.0f); - char agents[100]; - - AgentList* agentList = AgentList::getInstance(); - int totalAvatars = 0, totalServers = 0; - - for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - agent->getType() == AGENT_TYPE_AVATAR ? totalAvatars++ : totalServers++; - } - - sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); - drawtext(::screenWidth - 150, 20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); - - if (::paintOn) { - - char paintMessage[100]; - sprintf(paintMessage,"Painting (%.3f,%.3f,%.3f/%.3f/%d,%d,%d)", - ::paintingVoxel.x,::paintingVoxel.y,::paintingVoxel.z,::paintingVoxel.s, - (unsigned int)::paintingVoxel.red,(unsigned int)::paintingVoxel.green,(unsigned int)::paintingVoxel.blue); - drawtext(::screenWidth - 350, 50, 0.10, 0, 1.0, 0, paintMessage, 1, 1, 0); - } - - glPopMatrix(); -} - -void display(void) -{ - PerfStat("display"); - - glEnable(GL_LINE_SMOOTH); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_MODELVIEW); - - glPushMatrix(); { - glLoadIdentity(); - - // camera settings - if (OculusManager::isConnected()) { - myAvatar.setDisplayingHead(false); - myCamera.setUpShift (0.0f); - myCamera.setDistance (0.0f); - myCamera.setTightness (100.0f); - myCamera.setTargetPosition(myAvatar.getHeadPosition()); - myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -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, 0.0f); - - } else { - if (myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition()); - myCamera.setTargetRotation(myAvatar.getAbsoluteHeadYaw()- mouseViewShiftYaw, -20.0f + myAvatar.getRenderPitch() + mouseViewShiftPitch, 0.0f); - } else if (myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - - myCamera.setTargetPosition(myAvatar.getHeadPosition()); - myCamera.setTargetRotation(myAvatar.getBodyYaw() - mouseViewShiftYaw, mouseViewShiftPitch, 0.0f); - } - } - - // important... - myCamera.update( 1.f/FPS ); - - // Render anything (like HUD items) that we want to be in 3D but not in worldspace - /* - const float HUD_Z_OFFSET = -5.f; - glPushMatrix(); - glm::vec3 test(0.5, 0.5, 0.5); - glTranslatef(1, 1, HUD_Z_OFFSET); - drawVector(&test); - glPopMatrix(); - */ - - // Note: whichCamera is used to pick between the normal camera myCamera for our - // main camera, vs, an alternate camera. The alternate camera we support right now - // is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism - // to add other cameras. - // - // Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum() - // code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of - // myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera - Camera whichCamera = myCamera; - Camera viewFrustumOffsetCamera = myCamera; - - if (::viewFrustumFromOffset && ::frustumOn) { - - // set the camera to third-person view but offset so we can see the frustum - viewFrustumOffsetCamera.setTargetYaw(::viewFrustumOffsetYaw + myAvatar.getBodyYaw()); - viewFrustumOffsetCamera.setPitch (::viewFrustumOffsetPitch ); - viewFrustumOffsetCamera.setRoll (::viewFrustumOffsetRoll ); - viewFrustumOffsetCamera.setUpShift (::viewFrustumOffsetUp ); - viewFrustumOffsetCamera.setDistance (::viewFrustumOffsetDistance); - viewFrustumOffsetCamera.update(1.f/FPS); - whichCamera = viewFrustumOffsetCamera; - } - - // transform view according to whichCamera - // could be myCamera (if in normal mode) - // or could be viewFrustumOffsetCamera if in offset mode - // I changed the ordering here - roll is FIRST (JJV) - - glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z); - glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z); - glRotatef (180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z ); - - glTranslatef(-whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z); - - // Setup 3D lights (after the camera transform, so that they are positioned in world space) - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - - GLfloat light_position0[] = { 1.0, 1.0, 0.0, 0.0 }; - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - GLfloat ambient_color[] = { 0.7, 0.7, 0.8 }; - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color); - GLfloat diffuse_color[] = { 0.8, 0.7, 0.7 }; - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color); - GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0}; - glLightfv(GL_LIGHT0, GL_SPECULAR, specular_color); - - glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color); - glMateriali(GL_FRONT, GL_SHININESS, 96); - - if (::oculusOn) { - displayOculus(whichCamera); - - } else { - displaySide(whichCamera); - glPopMatrix(); - - displayOverlay(); - } - } - - glutSwapBuffers(); - frameCount++; - - // If application has just started, report time from startup to now (first frame display) - if (justStarted) { - float startupTime = (usecTimestampNow() - usecTimestamp(&applicationStartupTime))/1000000.0; - justStarted = false; - char title[30]; - snprintf(title, 30, "Interface: %4.2f seconds", startupTime); - glutSetWindowTitle(title); - } -} - -// int version of setValue() -int setValue(int state, int *value) { - if (state == MENU_ROW_PICKED) { - *value = !(*value); - } else if (state == MENU_ROW_GET_VALUE) { - return *value; - } else { - *value = state; - } - return *value; -} - -// bool version of setValue() -int setValue(int state, bool *value) { - if (state == MENU_ROW_PICKED) { - *value = !(*value); - } else if (state == MENU_ROW_GET_VALUE) { - return *value; - } else { - *value = state; - } - return *value; -} - -int setHead(int state) { - return setValue(state, &::lookingInMirror); -} - -int setNoise(int state) { - int iRet = setValue(state, &noiseOn); - if (noiseOn) { - myAvatar.setNoise(noise); - } else { - myAvatar.setNoise(0); - } - return iRet; -} - -int setLog(int state) { - int iRet = setValue(state, &::logOn); - return iRet; -} - -int setGyroLook(int state) { - int iRet = setValue(state, &::gyroLook); - return iRet; -} - -int setFullscreen(int state) { - bool wasFullscreen = ::fullscreen; - int value = setValue(state, &::fullscreen); - if (::fullscreen != wasFullscreen) { - if (::fullscreen) { - glutFullScreen(); - - } else { - glutReshapeWindow(::screenWidth, ::screenHeight); - } - } - return value; -} - -int setVoxels(int state) { - return setValue(state, &::renderVoxels); -} - -int setStars(int state) { - return setValue(state, &::renderStarsOn); -} - -int setAtmosphere(int state) { - return setValue(state, &::renderAtmosphereOn); -} - -int setRenderAvatars(int state) { - return setValue(state, &::renderAvatarsOn); -} - -int setRenderFirstPerson(int state) { - bool value = setValue(state, &::renderFirstPersonOn); - if (state == MENU_ROW_PICKED) { - if (::renderFirstPersonOn) { - - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.0f; - a.tightness = 100.0f; - myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); - myAvatar.setDisplayingHead(false); - } else { - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); - myAvatar.setDisplayingHead(true); - } - } - return value; -} - -int setOculus(int state) { - bool wasOn = ::oculusOn; - int value = setValue(state, &::oculusOn); - if (::oculusOn != wasOn) { - reshape(::screenWidth, ::screenHeight); - } - return value; -} - -int setStats(int state) { - return setValue(state, &::renderStatsOn); -} - -int setMenu(int state) { - return setValue(state, &::menuOn); -} - -int setRenderWarnings(int state) { - int value = setValue(state, &::renderWarningsOn); - if (state == MENU_ROW_PICKED) { - ::voxels.setRenderPipelineWarnings(::renderWarningsOn); - } - return value; -} - -int setWantResIn(int state) { - int value = setValue(state, &::wantResIn); - if (state == MENU_ROW_PICKED) { - ::myAvatar.setWantResIn(::wantResIn); - } - return value; -} - -int setWantMonochrome(int state) { - int value = setValue(state, &::wantMonochrome); - if (state == MENU_ROW_PICKED) { - ::myAvatar.setWantColor(!::wantMonochrome); - } - return value; -} - -int setDisplayFrustum(int state) { - return setValue(state, &::frustumOn); -} - -int setFrustumOffset(int state) { - int value = setValue(state, &::viewFrustumFromOffset); - - // reshape so that OpenGL will get the right lens details for the camera of choice - if (state == MENU_ROW_PICKED) { - reshape(::screenWidth, ::screenHeight); - } - - return value; -} - -int setFrustumOrigin(int state) { - return setValue(state, &::cameraFrustum); -} - -int quitApp(int state) { - if (state == MENU_ROW_PICKED) { - ::terminate(); - } - return 2; // non state so menu class doesn't add "state" -} - -int setFrustumRenderMode(int state) { - if (state == MENU_ROW_PICKED) { - ::frustumDrawingMode = (::frustumDrawingMode+1)%FRUSTUM_DRAW_MODE_COUNT; - } - return ::frustumDrawingMode; -} - -int doKillLocalVoxels(int state) { - if (state == MENU_ROW_PICKED) { - ::wantToKillLocalVoxels = true; - } - return state; -} - -int doRandomizeVoxelColors(int state) { - if (state == MENU_ROW_PICKED) { - ::voxels.randomizeVoxelColors(); - } - return state; -} - -int doFalseRandomizeEveryOtherVoxelColors(int state) { - if (state == MENU_ROW_PICKED) { - ::voxels.falseColorizeRandomEveryOther(); - } - return state; -} - -int doTreeStats(int state) { - if (state == MENU_ROW_PICKED) { - ::voxels.collectStatsForTreesAndVBOs(); - } - return state; -} - -int doFalseRandomizeVoxelColors(int state) { - if (state == MENU_ROW_PICKED) { - ::voxels.falseColorizeRandom(); - } - return state; -} - -int doTrueVoxelColors(int state) { - if (state == MENU_ROW_PICKED) { - ::voxels.trueColorize(); - } - return state; -} - -int doFalseColorizeByDistance(int state) { - if (state == MENU_ROW_PICKED) { - loadViewFrustum(::viewFrustum); - voxels.falseColorizeDistanceFromView(&::viewFrustum); - } - return state; -} - -int doFalseColorizeInView(int state) { - if (state == MENU_ROW_PICKED) { - loadViewFrustum(::viewFrustum); - // we probably want to make sure the viewFrustum is initialized first - voxels.falseColorizeInView(&::viewFrustum); - } - return state; -} - - - -const char* modeAll = " - All "; -const char* modeVectors = " - Vectors "; -const char* modePlanes = " - Planes "; -const char* modeNear = " - Near "; -const char* modeFar = " - Far "; - -const char* getFrustumRenderModeName(int state) { - const char * mode; - switch (state) { - case FRUSTUM_DRAW_MODE_ALL: - mode = modeAll; - break; - case FRUSTUM_DRAW_MODE_VECTORS: - mode = modeVectors; - break; - case FRUSTUM_DRAW_MODE_PLANES: - mode = modePlanes; - break; - case FRUSTUM_DRAW_MODE_NEAR_PLANE: - mode = modeNear; - break; - case FRUSTUM_DRAW_MODE_FAR_PLANE: - mode = modeFar; - break; - } - return mode; -} - -void initMenu() { - MenuColumn *menuColumnOptions, *menuColumnRender, *menuColumnTools, *menuColumnDebug, *menuColumnFrustum; - // Options - menuColumnOptions = menu.addColumn("Options"); - menuColumnOptions->addRow("Mirror (h)", setHead); - menuColumnOptions->addRow("Noise (n)", setNoise); - menuColumnOptions->addRow("Gyro Look", setGyroLook); - menuColumnOptions->addRow("Fullscreen (f)", setFullscreen); - menuColumnOptions->addRow("Quit (q)", quitApp); - - // Render - menuColumnRender = menu.addColumn("Render"); - menuColumnRender->addRow("Voxels (V)", setVoxels); - menuColumnRender->addRow("Stars (*)", setStars); - menuColumnRender->addRow("Atmosphere (A)", setAtmosphere); - menuColumnRender->addRow("Avatars", setRenderAvatars); - menuColumnRender->addRow("First Person (p)", setRenderFirstPerson); - menuColumnRender->addRow("Oculus (o)", setOculus); - - // Tools - menuColumnTools = menu.addColumn("Tools"); - menuColumnTools->addRow("Stats (/)", setStats); - menuColumnTools->addRow("Log ", setLog); - menuColumnTools->addRow("(M)enu", setMenu); - - // Frustum Options - menuColumnFrustum = menu.addColumn("Frustum"); - menuColumnFrustum->addRow("Display (F)rustum", setDisplayFrustum); - menuColumnFrustum->addRow("Use (O)ffset Camera", setFrustumOffset); - menuColumnFrustum->addRow("Switch (C)amera", setFrustumOrigin); - menuColumnFrustum->addRow("(R)ender Mode", setFrustumRenderMode, getFrustumRenderModeName); - - // Debug - menuColumnDebug = menu.addColumn("Debug"); - menuColumnDebug->addRow("Show Render Pipeline Warnings", setRenderWarnings); - menuColumnDebug->addRow("Kill Local Voxels", doKillLocalVoxels); - menuColumnDebug->addRow("Randomize Voxel TRUE Colors", doRandomizeVoxelColors); - menuColumnDebug->addRow("FALSE Color Voxels Randomly", doFalseRandomizeVoxelColors); - menuColumnDebug->addRow("FALSE Color Voxel Every Other Randomly", doFalseRandomizeEveryOtherVoxelColors); - menuColumnDebug->addRow("FALSE Color Voxels by Distance", doFalseColorizeByDistance); - menuColumnDebug->addRow("FALSE Color Voxel Out of View", doFalseColorizeInView); - menuColumnDebug->addRow("Show TRUE Colors", doTrueVoxelColors); - menuColumnDebug->addRow("Calculate Tree Stats", doTreeStats); - menuColumnDebug->addRow("Wants Res-In", setWantResIn); - menuColumnDebug->addRow("Wants Monochrome", setWantMonochrome); -} - -void testPointToVoxel() { - float y=0; - float z=0; - float s=0.1; - for (float x=0; x<=1; x+= 0.05) { - printLog(" x=%f"); - - unsigned char red = 200; //randomColorValue(65); - unsigned char green = 200; //randomColorValue(65); - unsigned char blue = 200; //randomColorValue(65); - - unsigned char* voxelCode = pointToVoxel(x, y, z, s,red,green,blue); - printVoxelCode(voxelCode); - delete voxelCode; - printLog("\n"); - } -} - -void sendVoxelServerEraseAll() { - char message[100]; - sprintf(message,"%c%s",'Z',"erase all"); - int messageSize = strlen(message) + 1; - AgentList::getInstance()->broadcastToAgents((unsigned char*) message, messageSize, &AGENT_TYPE_VOXEL, 1); -} - -void sendVoxelServerAddScene() { - char message[100]; - sprintf(message,"%c%s",'Z',"add scene"); - int messageSize = strlen(message) + 1; - AgentList::getInstance()->broadcastToAgents((unsigned char*)message, messageSize, &AGENT_TYPE_VOXEL, 1); -} - -void shiftPaintingColor() -{ - // About the color of the paintbrush... first determine the dominant color - ::dominantColor = (::dominantColor+1)%3; // 0=red,1=green,2=blue - ::paintingVoxel.red = (::dominantColor==0)?randIntInRange(200,255):randIntInRange(40,100); - ::paintingVoxel.green = (::dominantColor==1)?randIntInRange(200,255):randIntInRange(40,100); - ::paintingVoxel.blue = (::dominantColor==2)?randIntInRange(200,255):randIntInRange(40,100); -} - -void setupPaintingVoxel() { - glm::vec3 avatarPos = myAvatar.getPosition(); - - ::paintingVoxel.x = avatarPos.z/-10.0; // voxel space x is negative z head space - ::paintingVoxel.y = avatarPos.y/-10.0; // voxel space y is negative y head space - ::paintingVoxel.z = avatarPos.x/-10.0; // voxel space z is negative x head space - ::paintingVoxel.s = 1.0/256; - - shiftPaintingColor(); -} - -void addVoxelInFrontOfAvatar() { - VoxelDetail detail; - - glm::vec3 position = (myAvatar.getPosition() + myAvatar.getCameraDirection()) * (1.0f / TREE_SCALE); - detail.s = ::mouseVoxelScale; - - detail.x = detail.s * floor(position.x / detail.s); - detail.y = detail.s * floor(position.y / detail.s); - detail.z = detail.s * floor(position.z / detail.s); - detail.red = 128; - detail.green = 128; - detail.blue = 128; - - sendVoxelEditMessage(PACKET_HEADER_SET_VOXEL, detail); - - // create the voxel locally so it appears immediately - voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue); -} - -void addVoxelUnderCursor() { - if (::mouseVoxel.s != 0) { - sendVoxelEditMessage(PACKET_HEADER_SET_VOXEL, ::mouseVoxel); - - // create the voxel locally so it appears immediately - voxels.createVoxel(::mouseVoxel.x, ::mouseVoxel.y, ::mouseVoxel.z, ::mouseVoxel.s, - ::mouseVoxel.red, ::mouseVoxel.green, ::mouseVoxel.blue); - } -} - -void deleteVoxelUnderCursor() { - if (::mouseVoxel.s != 0) { - sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, ::mouseVoxel); - - // delete the voxel locally so it disappears immediately - voxels.deleteVoxelAt(::mouseVoxel.x, ::mouseVoxel.y, ::mouseVoxel.z, ::mouseVoxel.s); - } -} - -const float KEYBOARD_YAW_RATE = 0.8; -const float KEYBOARD_PITCH_RATE = 0.6; -const float KEYBOARD_STRAFE_RATE = 0.03; -const float KEYBOARD_FLY_RATE = 0.08; - -void specialkeyUp(int k, int x, int y) { - if (k == GLUT_KEY_UP) { - myAvatar.setDriveKeys(FWD, 0); - myAvatar.setDriveKeys(UP, 0); - } - if (k == GLUT_KEY_DOWN) { - myAvatar.setDriveKeys(BACK, 0); - myAvatar.setDriveKeys(DOWN, 0); - } - if (k == GLUT_KEY_LEFT) { - myAvatar.setDriveKeys(LEFT, 0); - myAvatar.setDriveKeys(ROT_LEFT, 0); - } - if (k == GLUT_KEY_RIGHT) { - myAvatar.setDriveKeys(RIGHT, 0); - myAvatar.setDriveKeys(ROT_RIGHT, 0); - } -} - -void specialkey(int k, int x, int y) { - if (::chatEntryOn) { - chatEntry.specialKey(k); - return; - } - - if (k == GLUT_KEY_UP || k == GLUT_KEY_DOWN || k == GLUT_KEY_LEFT || k == GLUT_KEY_RIGHT) { - if (k == GLUT_KEY_UP) { - if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) myAvatar.setDriveKeys(UP, 1); - else myAvatar.setDriveKeys(FWD, 1); - } - if (k == GLUT_KEY_DOWN) { - if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) myAvatar.setDriveKeys(DOWN, 1); - else myAvatar.setDriveKeys(BACK, 1); - } - if (k == GLUT_KEY_LEFT) { - if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) myAvatar.setDriveKeys(LEFT, 1); - else myAvatar.setDriveKeys(ROT_LEFT, 1); - } - if (k == GLUT_KEY_RIGHT) { - if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) myAvatar.setDriveKeys(RIGHT, 1); - else myAvatar.setDriveKeys(ROT_RIGHT, 1); - } - } -} - -void keyUp(unsigned char k, int x, int y) { - if (::chatEntryOn) { - myAvatar.setKeyState(NO_KEY_DOWN); - return; - } - - if (k == 'e') myAvatar.setDriveKeys(UP, 0); - if (k == 'c') myAvatar.setDriveKeys(DOWN, 0); - if (k == 'w') myAvatar.setDriveKeys(FWD, 0); - if (k == 's') myAvatar.setDriveKeys(BACK, 0); - if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 0); - if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 0); -} - -void toggleMouseMode(MouseMode mode) { - ::mouseMode = (::mouseMode == mode) ? NO_EDIT_MODE : mode; -} - -void key(unsigned char k, int x, int y) { - if (::chatEntryOn) { - if (chatEntry.key(k)) { - myAvatar.setKeyState(k == '\b' || k == 127 ? // backspace or delete - DELETE_KEY_DOWN : INSERT_KEY_DOWN); - myAvatar.setChatMessage(string(chatEntry.getContents().size(), SOLID_BLOCK_CHAR)); - - } else { - myAvatar.setChatMessage(chatEntry.getContents()); - chatEntry.clear(); - ::chatEntryOn = false; - } - return; - } - - // Process keypresses - - if (k == 'S') { - ::voxels.collectStatsForTreesAndVBOs(); - } - - if (k == 'q' || k == 'Q') ::terminate(); - if (k == '/') ::renderStatsOn = !::renderStatsOn; // toggle stats - if (k == '*') ::renderStarsOn = !::renderStarsOn; // toggle stars - if (k == 'V' || k == 'v') ::renderVoxels = !::renderVoxels; // toggle voxels - if (k == 'A') ::renderAtmosphereOn = !::renderAtmosphereOn; - if (k == 'F') ::frustumOn = !::frustumOn; // toggle view frustum debugging - if (k == 'C') ::cameraFrustum = !::cameraFrustum; // toggle which frustum to look at - if (k == 'O' || k == 'G') setFrustumOffset(MENU_ROW_PICKED); // toggle view frustum offset debugging - if (k == 'f') setFullscreen(!::fullscreen); - if (k == 'o') setOculus(!::oculusOn); - if (k == 'p') setRenderFirstPerson(MENU_ROW_PICKED); - if (k == '[') ::viewFrustumOffsetYaw -= 0.5; - if (k == ']') ::viewFrustumOffsetYaw += 0.5; - if (k == '{') ::viewFrustumOffsetPitch -= 0.5; - if (k == '}') ::viewFrustumOffsetPitch += 0.5; - if (k == '(') ::viewFrustumOffsetRoll -= 0.5; - if (k == ')') ::viewFrustumOffsetRoll += 0.5; - if (k == '<') ::viewFrustumOffsetDistance -= 0.5; - if (k == '>') ::viewFrustumOffsetDistance += 0.5; - if (k == ',') ::viewFrustumOffsetUp -= 0.05; - if (k == '.') ::viewFrustumOffsetUp += 0.05; - -// if (k == '|') ViewFrustum::fovAngleAdust -= 0.05; -// if (k == '\\') ViewFrustum::fovAngleAdust += 0.05; - - if (k == 'R') setFrustumRenderMode(MENU_ROW_PICKED); - - if (k == '&') { - ::paintOn = !::paintOn; // toggle paint - ::setupPaintingVoxel(); // also randomizes colors - } - if (k == '^') ::shiftPaintingColor(); // shifts randomize color between R,G,B dominant - if (k == '-') ::sendVoxelServerEraseAll(); // sends erase all command to voxel server - if (k == '%') ::sendVoxelServerAddScene(); // sends add scene command to voxel server - if (k == '1') ::mouseMode = (::mouseMode == ADD_VOXEL_MODE) ? NO_EDIT_MODE : ADD_VOXEL_MODE; - if (k == '2') ::mouseMode = (::mouseMode == DELETE_VOXEL_MODE) ? NO_EDIT_MODE : DELETE_VOXEL_MODE; - if (k == '3') ::mouseMode = (::mouseMode == COLOR_VOXEL_MODE) ? NO_EDIT_MODE : COLOR_VOXEL_MODE; - if (k == '4') addVoxelInFrontOfAvatar(); - if (k == '5') ::mouseVoxelScale /= 2; - if (k == '6') ::mouseVoxelScale *= 2; - if (k == 'n' || k == 'N') - { - noiseOn = !noiseOn; // Toggle noise - if (noiseOn) - { - myAvatar.setNoise(noise); - } - else - { - myAvatar.setNoise(0); - } - } - - if (k == 'h') { - ::lookingInMirror = !::lookingInMirror; - #ifndef _WIN32 - audio.setMixerLoopbackFlag(::lookingInMirror); - - if (::lookingInMirror) { - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.2f; - a.tightness = 100.0f; - myCamera.setMode(CAMERA_MODE_MIRROR, a); - myAvatar.setDisplayingHead(true); - } else { - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); - myAvatar.setDisplayingHead(true); - } - #endif - } - - if (k == 'm' || k == 'M') setMenu(MENU_ROW_PICKED); - - if (k == 'l') displayLevels = !displayLevels; - if (k == 'e') myAvatar.setDriveKeys(UP, 1); - if (k == 'c') myAvatar.setDriveKeys(DOWN, 1); - if (k == 'w') myAvatar.setDriveKeys(FWD, 1); - if (k == 's') myAvatar.setDriveKeys(BACK, 1); - if (k == ' ') resetSensors(); - if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 1); - if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 1); - - if (k == '\r') { - ::chatEntryOn = true; - myAvatar.setKeyState(NO_KEY_DOWN); - myAvatar.setChatMessage(string()); - } -} - -// Receive packets from other agents/servers and decide what to do with them! -void* networkReceive(void* args) { - sockaddr senderAddress; - ssize_t bytesReceived; - - while (!stopNetworkReceiveThread) { - // check to see if the UI thread asked us to kill the voxel tree. since we're the only thread allowed to do that - if (::wantToKillLocalVoxels) { - ::voxels.killLocalVoxels(); - ::wantToKillLocalVoxels = false; - } - - if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { - packetCount++; - bytesCount += bytesReceived; - - switch (incomingPacket[0]) { - case PACKET_HEADER_TRANSMITTER_DATA: - // Process UDP packets that are sent to the client from local sensor devices - myAvatar.processTransmitterData(incomingPacket, bytesReceived); - break; - case PACKET_HEADER_VOXEL_DATA: - case PACKET_HEADER_VOXEL_DATA_MONOCHROME: - case PACKET_HEADER_Z_COMMAND: - case PACKET_HEADER_ERASE_VOXEL: - voxels.parseData(incomingPacket, bytesReceived); - break; - case PACKET_HEADER_ENVIRONMENT_DATA: - environment.parseData(incomingPacket, bytesReceived); - break; - case PACKET_HEADER_BULK_AVATAR_DATA: - AgentList::getInstance()->processBulkAgentData(&senderAddress, - incomingPacket, - bytesReceived); - break; - default: - AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); - break; - } - } else if (!enableNetworkThread) { - break; - } - } - - if (enableNetworkThread) { - pthread_exit(0); - } - return NULL; -} - -glm::vec3 getFaceVector(BoxFace face) { - switch (face) { - case MIN_X_FACE: - return glm::vec3(-1, 0, 0); - - case MAX_X_FACE: - return glm::vec3(1, 0, 0); - - case MIN_Y_FACE: - return glm::vec3(0, -1, 0); - - case MAX_Y_FACE: - return glm::vec3(0, 1, 0); - - case MIN_Z_FACE: - return glm::vec3(0, 0, -1); - - case MAX_Z_FACE: - return glm::vec3(0, 0, 1); - } -} - -void idle(void) { - timeval check; - gettimeofday(&check, NULL); - - // Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time - - if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) { - - float deltaTime = 1.f/FPS; - - // update behaviors for avatar hand movement: handControl takes mouse values as input, - // and gives back 3D values modulated for smooth transitioning between interaction modes. - handControl.update(mouseX, mouseY); - myAvatar.setHandMovementValues(handControl.getValues()); - - // tell my avatar if the mouse is being pressed... - myAvatar.setMousePressed(mousePressed); - - // check what's under the mouse and update the mouse voxel - glm::vec3 mouseRayOrigin, mouseRayDirection; - viewFrustum.computePickRay(mouseX / (float)::screenWidth, mouseY / (float)::screenHeight, mouseRayOrigin, mouseRayDirection); - - // tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position - myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection); - - float distance; - BoxFace face; - ::mouseVoxel.s = 0.0f; - if (voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, ::mouseVoxel, distance, face)) { - // find the nearest voxel with the desired scale - if (::mouseVoxelScale > ::mouseVoxel.s) { - // choose the larger voxel that encompasses the one selected - ::mouseVoxel.x = ::mouseVoxelScale * floorf(::mouseVoxel.x / ::mouseVoxelScale); - ::mouseVoxel.y = ::mouseVoxelScale * floorf(::mouseVoxel.y / ::mouseVoxelScale); - ::mouseVoxel.z = ::mouseVoxelScale * floorf(::mouseVoxel.z / ::mouseVoxelScale); - ::mouseVoxel.s = ::mouseVoxelScale; - - } else if (::mouseVoxelScale < ::mouseVoxel.s) { - glm::vec3 pt = (mouseRayOrigin + mouseRayDirection * distance) / (float)TREE_SCALE - - getFaceVector(face) * (::mouseVoxelScale * 0.5f); - ::mouseVoxel.x = ::mouseVoxelScale * floorf(pt.x / ::mouseVoxelScale); - ::mouseVoxel.y = ::mouseVoxelScale * floorf(pt.y / ::mouseVoxelScale); - ::mouseVoxel.z = ::mouseVoxelScale * floorf(pt.z / ::mouseVoxelScale); - ::mouseVoxel.s = ::mouseVoxelScale; - } - - if (::mouseMode == COLOR_VOXEL_MODE) { - ::mouseVoxel.red = 0; - ::mouseVoxel.green = 255; - ::mouseVoxel.blue = 0; - - } else if (::mouseMode == DELETE_VOXEL_MODE) { - // red indicates deletion - ::mouseVoxel.red = 255; - ::mouseVoxel.green = ::mouseVoxel.blue = 0; - } - } - - // when walking handControl stops - if (myAvatar.getMode() == AVATAR_MODE_WALKING) { - handControl.stop(); - mouseViewShiftYaw *= 0.9; - mouseViewShiftPitch *= 0.9; - } - - if (myCamera.getMode() != CAMERA_MODE_MIRROR) { - if (myAvatar.getIsNearInteractingOther()) { - myAvatar.setDisplayingHead(false); - Camera::CameraFollowingAttributes a; - a.upShift = 0.0f; - a.distance = 0.0f; - a.tightness = 100.0f; - myCamera.setMode(CAMERA_MODE_FIRST_PERSON, a); - } else { - if (myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { - myAvatar.setDisplayingHead(true); - Camera::CameraFollowingAttributes a; - a.upShift = -0.2f; - a.distance = 1.5f; - a.tightness = 8.0f; - myCamera.setMode(CAMERA_MODE_THIRD_PERSON, a); - } - } - } - - // Read serial port interface devices - if (serialPort.active) { - serialPort.readData(); - } - - // Sample hardware, update view frustum if needed, and send avatar data to mixer/agents - updateAvatar(deltaTime); - - // read incoming packets from network - if (!enableNetworkThread) { - networkReceive(0); - } - - //loop through all the remote avatars and simulate them... - AgentList* agentList = AgentList::getInstance(); - agentList->lock(); - for(AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { - if (agent->getLinkedData() != NULL) { - Avatar *avatar = (Avatar *)agent->getLinkedData(); - avatar->simulate(deltaTime); - avatar->setMouseRay(mouseRayOrigin, mouseRayDirection); - } - } - agentList->unlock(); - - myAvatar.setGravity(getGravity(myAvatar.getPosition())); - myAvatar.simulate(deltaTime); - - // Update audio stats for procedural sounds - audio.setLastAcceleration(myAvatar.getThrust()); - audio.setLastVelocity(myAvatar.getVelocity()); - - glutPostRedisplay(); - lastTimeIdle = check; - } -} - -void reshape(int width, int height) { - ::screenWidth = width; - ::screenHeight = height; - aspectRatio = ((float)width/(float)height); // based on screen resize - - // get the lens details from the current camera - Camera& camera = ::viewFrustumFromOffset ? (::viewFrustumOffsetCamera) : (::myCamera); - float nearClip = camera.getNearClip(); - float farClip = camera.getFarClip(); - float fov; - - if (::oculusOn) { - // more magic numbers; see Oculus SDK docs, p. 32 - camera.setAspectRatio(aspectRatio *= 0.5); - camera.setFieldOfView(fov = 2 * atan((0.0468 * ::oculusDistortionScale) / 0.041) * (180 / PI)); - - // resize the render texture - if (::oculusTextureID != 0) { - glBindTexture(GL_TEXTURE_2D, ::oculusTextureID); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ::screenWidth, ::screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, 0); - } - } else { - camera.setAspectRatio(aspectRatio); - camera.setFieldOfView(fov = 60); - } - - // Tell our viewFrustum about this change - ::viewFrustum.setAspectRatio(aspectRatio); - - glViewport(0, 0, width, height); // shouldn't this account for the menu??? - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // XXXBHG - If we're in view frustum mode, then we need to do this little bit of hackery so that - // OpenGL won't clip our frustum rendering lines. This is a debug hack for sure! Basically, this makes - // the near clip a little bit closer (therefor you see more) and the far clip a little bit farther (also, - // to see more.) - if (::frustumOn) { - nearClip -= 0.01f; - farClip += 0.01f; - } - - // On window reshape, we need to tell OpenGL about our new setting - gluPerspective(fov,aspectRatio,nearClip,farClip); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -} - -//Find and return the gravity vector at this location -glm::vec3 getGravity(glm::vec3 pos) { - // - // For now, we'll test this with a simple global lookup, but soon we will add getting this - // from the domain/voxelserver (or something similar) - // - if ((pos.x > 0.f) && - (pos.x < 10.f) && - (pos.z > 0.f) && - (pos.z < 10.f) && - (pos.y > 0.f) && - (pos.y < 3.f)) { - // If above ground plane, turn gravity on - return glm::vec3(0.f, -1.f, 0.f); - } else { - // If flying in space, turn gravity OFF - return glm::vec3(0.f, 0.f, 0.f); - } -} - -bool menuDisplayed = false; -void mouseFunc(int button, int state, int x, int y) { - bool menuFound = menu.mouseClick(x, y); - - // If we didn't previously have the menu displayed, and we did just click on the menu, then - // go into menuDisplayed mode.... - if (!::menuDisplayed && menuFound) { - ::menuDisplayed = true; - } - - // If the menu was displayed, and we're not over a menu, then leave menu mode - if (::menuDisplayed && !menuFound) { - ::menuDisplayed = false; - menu.hidePopupMenu(); - } - - // In menu displayed mode use old logic - if (::menuDisplayed) { - if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { - if (state == GLUT_DOWN && !menu.mouseClick(x, y)) { - mouseX = x; - mouseY = y; - mousePressed = 1; - } else if (state == GLUT_UP) { - mouseX = x; - mouseY = y; - mousePressed = 0; - } - } - } else { - if (button == GLUT_LEFT_BUTTON) { - mouseX = x; - mouseY = y; - - if (state == GLUT_DOWN) { - mousePressed = 1; - if (::mouseMode == ADD_VOXEL_MODE || ::mouseMode == COLOR_VOXEL_MODE) { - addVoxelUnderCursor(); - - } else if (::mouseMode == DELETE_VOXEL_MODE) { - deleteVoxelUnderCursor(); - } - } else if (state == GLUT_UP) { - mousePressed = 0; - } - } else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN && ::mouseMode != NO_EDIT_MODE) { - deleteVoxelUnderCursor(); - } - } -} - - -void motionFunc(int x, int y) { - mouseX = x; - mouseY = y; -} - -void mouseoverFunc(int x, int y){ - menu.mouseOver(x, y); - - mouseX = x; - mouseY = y; -} - -void attachNewHeadToAgent(Agent *newAgent) { - if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new Avatar(false)); - } -} - -#ifndef _WIN32 -void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) { - audio.updateMixerParams(newMixerAddress, newMixerPort); -} -#endif - -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; +} From 04828c82247a6c5711ff18924a7dd20ae79ae6cf Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 16 May 2013 12:06:36 -0700 Subject: [PATCH 4/9] cleaned up copyright header notifications in several files --- interface/src/Avatar.cpp | 3 +-- interface/src/AvatarRenderer.cpp | 3 +-- interface/src/AvatarRenderer.h | 1 - interface/src/AvatarTouch.cpp | 3 +-- interface/src/AvatarTouch.h | 1 - interface/src/Camera.cpp | 7 +++---- interface/src/Camera.h | 8 ++++---- interface/src/HandControl.cpp | 1 - interface/src/HandControl.h | 1 - interface/src/Head.cpp | 6 ++---- interface/src/Head.h | 5 ++--- 11 files changed, 14 insertions(+), 25 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index f43ed5e319..0b55839027 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 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 2a74de363b..50c9ed809b 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 diff --git a/interface/src/Camera.h b/interface/src/Camera.h index 348bde0d89..8d21422f8f 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__ 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 479204472b..d5f137b404 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -1,10 +1,8 @@ // // 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" diff --git a/interface/src/Head.h b/interface/src/Head.h index 5d4ccaec31..9d6e84ce7d 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 From aafb557b025942d97adc4ed5a211ea50dd18103e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 16 May 2013 12:14:36 -0700 Subject: [PATCH 5/9] turned off look at behavior - until it is finished and working correctly --- interface/src/Avatar.cpp | 6 +++++- interface/src/Head.cpp | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 0b55839027..658f07cbb7 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -443,12 +443,16 @@ void Avatar::simulate(float deltaTime) { _joint[ AVATAR_JOINT_HEAD_BASE ].radius ); + //the following is still being prototyped (making the eyes look at a specific location), it should be finished by 5/20/13 + _head.setLooking(false); + /* if (_interactingOther) { _head.setLooking(true); _head.setLookatPosition(_interactingOther->getSpringyHeadPosition()); } else { _head.setLooking(false); - } + } + */ _head.setAudioLoudness(_audioLoudness); _head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2])); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index d5f137b404..83f4beb030 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -14,8 +14,6 @@ using namespace std; const float HEAD_MOTION_DECAY = 0.1; -//const bool TESTING_LOOKAT = true; - float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; float _mouthColor[] = {1, 0, 0}; @@ -412,10 +410,10 @@ void Head::renderEyeBalls() { // the code below is still in the prototyping stages.... //--------------------------------------------------------- void Head::renderIrises(float yaw) { + Orientation orientation; orientation.setToPitchYawRoll( pitch, yaw, roll); - // Render lines originating from the eyes and converging on the lookatPosition float rightShift = scale * 0.22f; float upShift = scale * 0.38f; float frontShift = scale * 0.9f; @@ -427,10 +425,12 @@ void Head::renderIrises(float yaw) { + orientation.getUp () * upShift + orientation.getFront() * frontShift; + // Render lines originating from the eyes and converging on the lookatPosition debugRenderLookatVectors(leftEyePosition, rightEyePosition, lookatPosition); glColor3fv(_eyeColor); + //make the texture for the iris sphere... if (sphere == NULL) { sphere = gluNewQuadric(); gluQuadricTexture(sphere, GL_TRUE); From cd248188d9c7ba47f89745cf55b8fc280856102c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 16 May 2013 12:19:20 -0700 Subject: [PATCH 6/9] thingy --- interface/src/Head.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 83f4beb030..4c6f7df97a 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -441,8 +441,7 @@ void Head::renderIrises(float yaw) { } //render left iris - glPushMatrix(); - { + glPushMatrix(); { glTranslatef(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z); glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - leftEyePosition); @@ -463,8 +462,7 @@ void Head::renderIrises(float yaw) { glPopMatrix(); //render right iris - glPushMatrix(); - { + glPushMatrix(); { glTranslatef(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z); glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - rightEyePosition); From 750a48bb7344a8e990e88d238cf2467074eb328b Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 16 May 2013 17:20:00 -0700 Subject: [PATCH 7/9] cleaned up head class - made most members private. Added copy constructor --- interface/src/Avatar.cpp | 45 +-- interface/src/Avatar.h | 1 + interface/src/Head.cpp | 654 ++++++++++++++++++++++++--------------- interface/src/Head.h | 114 ++++--- 4 files changed, 496 insertions(+), 318 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 658f07cbb7..4ddd7c928f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -46,7 +46,7 @@ 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.3f; +const float PERIPERSONAL_RADIUS = 1.0f; const float AVATAR_BRAKING_STRENGTH = 40.0f; const float JOINT_TOUCH_RANGE = 0.0005f; @@ -104,14 +104,14 @@ Avatar::Avatar(bool isMine) { initializeSkeleton(); - _avatarTouch.setReachableRadius(1.0); + _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; @@ -145,6 +145,7 @@ 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; @@ -181,19 +182,11 @@ Avatar::Avatar(const Avatar &otherAvatar) { _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() { @@ -394,8 +387,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; @@ -443,16 +436,16 @@ 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 - _head.setLooking(false); - /* 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])); @@ -523,7 +516,10 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) { float distance = glm::length(v); if (distance < closestDistance) { closestDistance = distance; - _interactingOther = otherAvatar; + + if (distance < PERIPERSONAL_RADIUS) { + _interactingOther = otherAvatar; + } } } } @@ -750,6 +746,7 @@ static TextRenderer* textRenderer() { void Avatar::setGravity(glm::vec3 gravity) { _gravity = gravity; + _head.setGravity(_gravity); } void Avatar::render(bool lookingInMirror, glm::vec3 cameraPosition) { @@ -1131,6 +1128,12 @@ const glm::vec3& Avatar::getHeadPosition() const { } +glm::vec3 Avatar::getApproximateEyePosition() { + return _head.getApproximateEyePosition(); +} + + + void Avatar::updateArmIKAndConstraints(float deltaTime) { @@ -1177,7 +1180,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 { diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 06627adadf..a8aa40a955 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -100,6 +100,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; }; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 4c6f7df97a..89ffe8b6f9 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -13,6 +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}; @@ -42,102 +43,229 @@ 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); - lookatPosition = 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::copyFromHead(const Head &head) { + + 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; + yawRate = head.yawRate; + rollRate = head.rollRate; + noise = head.noise; + 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; + leanForward = head.leanForward; + leanSideways = head.leanSideways; + 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; + sphere = head.sphere; + returnSpringScale = head.returnSpringScale; +} +*/ + 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); @@ -147,12 +275,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); @@ -162,80 +290,104 @@ 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::setLooking(bool l) { - _looking = l; +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 averagEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; + glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - averagEyePosition); + + float dot = glm::dot(targetLookatAxis, _orientation.getFront()); + if (dot < MINIMUM_EYE_ROTATION) { + _looking = false; + } +} void Head::setLookatPosition(glm::vec3 l) { - lookatPosition = 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, float bodyYaw) { - - -//float a = angleBetween( &position, &position); +void Head::render(bool lookingInMirror) { int side = 0; @@ -244,22 +396,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); @@ -276,28 +428,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(); @@ -306,184 +458,188 @@ void Head::render(bool lookingInMirror, float bodyYaw) { glTranslatef(0,-0.35,0.75); glColor3f(0,0,0); - glRotatef(mouthPitch, 1, 0, 0); - glRotatef(mouthYaw, 0, 0, 1); + 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); + if (_averageLoudness > 1.f) { + glScalef(_mouthWidth * (.7f + sqrt(_averageLoudness) /60.f), + _mouthHeight * (1.f + sqrt(_averageLoudness) /30.f), 1); } else { - glScalef(mouthWidth, mouthHeight, 1); + glScalef(_mouthWidth, _mouthHeight, 1); } glutSolidCube(0.5); glPopMatrix(); - - renderEyeBalls(); + + // 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) { - //the irises are special - they have the ability to look at specific targets in the world (code still not finished yet) - renderIrises(bodyYaw + yaw); + // Render lines originating from the eyes and converging on the lookatPosition + debugRenderLookatVectors(_leftEyePosition, _rightEyePosition, _lookatPosition); } } -void Head::renderEyeBalls() { + +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)); + + //glm::vec3 U_rotationAxis = glm::vec3(0.0f, 0.0f, 1.0f); + //float U_angle = angleBetween(_orientation.getFront(), glm::vec3(1.0f, 0.0f, 0.0f)); + //glRotatef(U_angle, U_rotationAxis.x, U_rotationAxis.y, U_rotationAxis.z); + 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(); - if (!_looking) { - // Right Pupil - 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]); - } - - glPushMatrix(); - { - 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); - glDisable(GL_TEXTURE_2D); - } - glPopMatrix(); + // Right Pupil + 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]); } + glPushMatrix(); + { + 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); + 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(); - if (!_looking) { - // Left Pupil - glPushMatrix(); - { - 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); - glDisable(GL_TEXTURE_2D); - } - glPopMatrix(); - } -} - - -//--------------------------------------------------------- -// the code below is still in the prototyping stages.... -//--------------------------------------------------------- -void Head::renderIrises(float yaw) { - - Orientation orientation; - orientation.setToPitchYawRoll( pitch, yaw, roll); - - float rightShift = scale * 0.22f; - float upShift = scale * 0.38f; - float frontShift = scale * 0.9f; - - glm::vec3 leftEyePosition = position + orientation.getRight() * rightShift - + orientation.getUp () * upShift - + orientation.getFront() * frontShift; - glm::vec3 rightEyePosition = position - orientation.getRight() * rightShift - + orientation.getUp () * upShift - + orientation.getFront() * frontShift; - - // Render lines originating from the eyes and converging on the lookatPosition - debugRenderLookatVectors(leftEyePosition, rightEyePosition, lookatPosition); - - glColor3fv(_eyeColor); - - //make the texture for the iris sphere... - 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]); - } - - //render left iris - glPushMatrix(); { - glTranslatef(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z); - glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - leftEyePosition); + // Left Pupil + glPushMatrix(); + { + 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); - glPushMatrix(); - glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight()); - glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp()); - - float yaw = angleBetween(targetLookatAxis, orientation.getUp()); - float pitch = angleBetween(targetLookatAxis, orientation.getRight()); - - glRotatef(yaw, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); - glRotatef(pitch, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); - glEnable(GL_TEXTURE_2D); - gluSphere(sphere, 0.01, 15, 15); - glDisable(GL_TEXTURE_2D); - glPopMatrix(); - } - glPopMatrix(); - - //render right iris - glPushMatrix(); { - glTranslatef(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z); - glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - rightEyePosition); - - glPushMatrix(); - glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight()); - glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp()); - - float yaw = angleBetween(targetLookatAxis, orientation.getUp()); - float pitch = angleBetween(targetLookatAxis, orientation.getRight()); - - glRotatef(yaw, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z); - glRotatef(pitch, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z); - glEnable(GL_TEXTURE_2D); - gluSphere(sphere, 0.01, 15, 15); - glDisable(GL_TEXTURE_2D); - glPopMatrix(); + glEnable(GL_TEXTURE_2D); + gluSphere(_sphere, _pupilSize, 15, 15); + glDisable(GL_TEXTURE_2D); } glPopMatrix(); } + void Head::debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) { glColor3f(0.0f, 0.0f, 0.0f); diff --git a/interface/src/Head.h b/interface/src/Head.h index 9d6e84ce7d..bf1a5426de 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -22,80 +22,98 @@ 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 lookatPosition); void setLooking(bool looking); + void setGravity(glm::vec3 gravity); + void setBodyYaw(float y) { _bodyYaw = y; } + void copyFromHead(const Head &head); + + 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 r) { _returnHeadToCenter = r; } + 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;}; - bool returnHeadToCenter; - float audioLoudness; - glm::vec3 skinColor; - glm::vec3 position; - glm::vec3 rotation; - glm::vec3 lookatPosition; - 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; + +private: + + bool _returnHeadToCenter; + float _audioLoudness; + glm::vec3 _skinColor; + glm::vec3 _position; + glm::vec3 _rotation; + glm::vec3 _lookatPosition; + + 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; + float _lastLoudness; + float _averageLoudness; + float _audioAttack; bool _looking; + glm::vec3 _gravity; + - GLUquadric* sphere; + GLUquadric* _sphere; // Strength of return springs - float returnSpringScale; + float _returnSpringScale; -private: + // private methods + void previouseRenderEyeBalls(); void renderEyeBalls(); - void renderIrises(float yaw); void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition); - + void updateEyePositions(); }; #endif From 7e0877e753a1cf2036bdd144507a9352d2a1f97f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 17 May 2013 08:48:54 -0700 Subject: [PATCH 8/9] cleanup --- interface/src/Avatar.cpp | 39 ----------------- interface/src/Avatar.h | 2 +- interface/src/Camera.cpp | 8 ++-- interface/src/Head.cpp | 91 +++++++--------------------------------- interface/src/Head.h | 5 +-- 5 files changed, 23 insertions(+), 122 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 1378d27904..c82fd5422f 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -147,45 +147,6 @@ Avatar::Avatar(const Avatar &otherAvatar) :_head(otherAvatar._head) { //include 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(); diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 74e8161b7c..18565a6db5 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -201,7 +201,7 @@ private: glm::vec3 _mouseRayOrigin; glm::vec3 _mouseRayDirection; glm::vec3 _cameraPosition; - Avatar * _interactingOther; + Avatar* _interactingOther; float _cumulativeMouseYaw; bool _isMouseTurningRight; diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 50c9ed809b..65e67c49da 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -118,10 +118,10 @@ void Camera::updateFollowMode(float deltaTime) { _position += (_idealPosition - _position) * t; } - float mm = 1.0f - _modeShift; - _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * mm; - _distance = _attributes[_mode].distance * _modeShift + _previousAttributes[_mode].distance * mm; - _upShift = _attributes[_mode].upShift * _modeShift + _previousAttributes[_mode].upShift * mm; + 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; /* diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 4ac9cb9ddc..7a5b62ff88 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -154,65 +154,6 @@ void Head::initialize() { _sphere = NULL; } -/* -void Head::copyFromHead(const Head &head) { - - 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; - yawRate = head.yawRate; - rollRate = head.rollRate; - noise = head.noise; - 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; - leanForward = head.leanForward; - leanSideways = head.leanSideways; - 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; - sphere = head.sphere; - returnSpringScale = head.returnSpringScale; -} -*/ - void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) { _position = p; @@ -355,20 +296,23 @@ void Head::updateEyePositions() { 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; + _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 averagEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF; - glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - averagEyePosition); + 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) { @@ -376,6 +320,7 @@ void Head::setLooking(bool looking) { } } +/* void Head::setLookatPosition(glm::vec3 l) { _lookatPosition = l; } @@ -383,6 +328,7 @@ void Head::setLookatPosition(glm::vec3 l) { void Head::setGravity(glm::vec3 gravity) { _gravity = gravity; } +*/ glm::vec3 Head::getApproximateEyePosition() { return _leftEyePosition + (_rightEyePosition - _leftEyePosition) * ONE_HALF; @@ -402,11 +348,11 @@ void Head::render(bool lookingInMirror) { glScalef(_scale, _scale, _scale); if (lookingInMirror) { - glRotatef(_bodyYaw - _yaw, 0, 1, 0); - glRotatef(_pitch, 1, 0, 0); + glRotatef(_bodyYaw - _yaw, 0, 1, 0); + glRotatef(_pitch, 1, 0, 0); glRotatef(-_roll, 0, 0, 1); } else { - glRotatef(_bodyYaw + _yaw, 0, 1, 0); + glRotatef(_bodyYaw + _yaw, 0, 1, 0); glRotatef(_pitch, 1, 0, 0); glRotatef(_roll, 0, 0, 1); } @@ -524,12 +470,7 @@ void Head::renderEyeBalls() { 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)); - - //glm::vec3 U_rotationAxis = glm::vec3(0.0f, 0.0f, 1.0f); - //float U_angle = angleBetween(_orientation.getFront(), glm::vec3(1.0f, 0.0f, 0.0f)); - //glRotatef(U_angle, U_rotationAxis.x, U_rotationAxis.y, U_rotationAxis.z); 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); diff --git a/interface/src/Head.h b/interface/src/Head.h index bf1a5426de..0868d1f012 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -32,11 +32,10 @@ public: void render(bool lookingInMirror); void setNewTarget(float, float); void setSpringScale(float s) { _returnSpringScale = s; } - void setLookatPosition(glm::vec3 lookatPosition); + void setLookatPosition(glm::vec3 l ) { _lookatPosition = l; } void setLooking(bool looking); - void setGravity(glm::vec3 gravity); + void setGravity(glm::vec3 gravity) { _gravity = gravity; } void setBodyYaw(float y) { _bodyYaw = y; } - void copyFromHead(const Head &head); glm::vec3 getApproximateEyePosition(); From ade5b7bec38302150eaad1096fa495e0306400d8 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 17 May 2013 09:52:19 -0700 Subject: [PATCH 9/9] formatting changes --- interface/src/Camera.cpp | 9 --------- interface/src/Head.h | 2 +- libraries/avatars/src/Orientation.cpp | 16 ++++++++-------- libraries/avatars/src/Orientation.h | 8 ++++---- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 65e67c49da..f9aa0dda6f 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -122,15 +122,6 @@ void Camera::updateFollowMode(float deltaTime) { _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; - - - /* - //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; - */ - } diff --git a/interface/src/Head.h b/interface/src/Head.h index 0868d1f012..209ef0704d 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -40,7 +40,7 @@ public: glm::vec3 getApproximateEyePosition(); // Do you want head to try to return to center (depends on interface detected) - void setReturnToCenter(bool r) { _returnHeadToCenter = r; } + void setReturnToCenter(bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; } const bool getReturnToCenter() const { return _returnHeadToCenter; } float getAverageLoudness() {return _averageLoudness;}; diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp index 1f74cb7f80..6466eb802c 100755 --- a/libraries/avatars/src/Orientation.cpp +++ b/libraries/avatars/src/Orientation.cpp @@ -25,12 +25,12 @@ void Orientation::setToIdentity() { front = glm::vec3(IDENTITY_FRONT); } -void Orientation::setToPitchYawRoll(float p, float y, float r) { +void Orientation::setToPitchYawRoll(float pitch_change, float yaw_change, float roll_change) { setToIdentity(); - pitch(p); - yaw (y); - roll (r); + pitch(pitch_change); + yaw (yaw_change); + roll (roll_change); } @@ -102,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 ea1dbf16ac..82d6edc9e5 100755 --- a/libraries/avatars/src/Orientation.h +++ b/libraries/avatars/src/Orientation.h @@ -22,12 +22,12 @@ public: Orientation(); void set(Orientation); - void setToPitchYawRoll(float p, float y, float r); + 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);