From 9760b7d410b2ca4f5d3d363fa517709acddf31c7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 23 Apr 2013 09:47:52 -0700 Subject: [PATCH 1/5] First commit to re-enable gyros, removed various old head_mirror variables, now use 'lookingInMirror', etc. Local gyros now correctly drive own head. --- interface/src/Audio.cpp | 10 ++++++++- interface/src/Head.cpp | 50 ++++++++++++++++++++++------------------- interface/src/Head.h | 16 ++++++------- interface/src/main.cpp | 29 +++++++++--------------- 4 files changed, 55 insertions(+), 50 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 4e8c249f16..0d585ff5bf 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -250,8 +250,16 @@ int audioCallback (const void *inputBuffer, } // play whatever we have in the audio buffer + // // if we haven't fired off the flange effect, check if we should - int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredYaw()); + // + + // + // NOTE: PER - LastMeasuredHeadYaw is now relative to body position, represents the local + // rotation of the head relative to body, this may effect flange effect! + // + // + int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredHeadYaw()); if (!samplesLeftForFlange && lastYawMeasured > MIN_FLANGE_EFFECT_THRESHOLD) { // we should flange for one second diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index d1bbf5e65b..f6a3392027 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -241,7 +241,7 @@ void Head::reset() { //this pertains to moving the head with the glasses //--------------------------------------------------- -void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity) +void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity) // Using serial data, update avatar/render position and angles { const float PITCH_ACCEL_COUPLING = 0.5; @@ -270,19 +270,14 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h const float MIN_YAW = -85; if ((_head.pitch < MAX_PITCH) && (_head.pitch > MIN_PITCH)) - addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); + addHeadPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); - addRoll(-measured_roll_rate * HEAD_ROLL_SCALE * frametime); + addHeadRoll(measured_roll_rate * HEAD_ROLL_SCALE * frametime); - if (head_mirror) { - if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) - addYaw(-_head.yawRate * HEAD_ROTATION_SCALE * frametime); - addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); - } else { - if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) - addYaw(_head.yawRate * -HEAD_ROTATION_SCALE * frametime); - addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); - } + if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) + addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime); + + addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } void Head::addLean(float x, float z) { @@ -462,10 +457,6 @@ void Head::simulate(float deltaTime) { _bodyYaw += _bodyYawDelta * deltaTime; } - // we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation - _head.yaw = _bodyYaw; - _head.pitch = _bodyPitch; - _head.roll = _bodyRoll; //---------------------------------------------------------- // decay body yaw delta @@ -487,6 +478,15 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- _velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); + // + // Update Head information + // + + // we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation + //_head.yaw = _bodyYaw; + //_head.pitch = _bodyPitch; + //_head.roll = _bodyRoll; + if (!_head.noise) { // Decay back toward center _head.pitch *= (1.0f - DECAY*2*deltaTime); @@ -625,7 +625,7 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { -void Head::render(int faceToFace) { +void Head::render(int lookingInMirror) { //--------------------------------------------------- // show avatar position @@ -658,7 +658,7 @@ void Head::render(int faceToFace) { //--------------------------------------------------- // render head //--------------------------------------------------- - renderHead(faceToFace); + renderHead(lookingInMirror); //--------------------------------------------------------------------------- // if this is my avatar, then render my interactions with the other avatars @@ -695,9 +695,9 @@ void Head::render(int faceToFace) { } } - + -void Head::renderHead(int faceToFace) { +void Head::renderHead(int lookingInMirror) { int side = 0; glEnable(GL_DEPTH_TEST); @@ -723,9 +723,13 @@ void Head::renderHead(int faceToFace) { glScalef( 0.03, 0.03, 0.03 ); - glRotatef(_head.yaw, 0, 1, 0); - glRotatef(_head.pitch, 1, 0, 0); - glRotatef(_head.roll, 0, 0, 1); + if (lookingInMirror) { + glRotatef(_bodyYaw - _head.yaw, 0, 1, 0); + } else { + glRotatef(_bodyYaw + _head.yaw, 0, 1, 0); + } + glRotatef(_bodyPitch + _head.pitch, 1, 0, 0); + glRotatef(_bodyRoll + _head.roll, 0, 0, 1); glScalef(2.0, 2.0, 2.0); glColor3fv(skinColor); diff --git a/interface/src/Head.h b/interface/src/Head.h index 37488699b7..72ac2c1ec4 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -148,7 +148,7 @@ class Head : public AvatarData { Head* clone() const; void reset(); - void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); + void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); void setNoise (float mag) { _head.noise = mag; } void setPitch(float p) {_head.pitch = p; } void setYaw(float y) {_head.yaw = y; } @@ -160,14 +160,14 @@ class Head : public AvatarData { float getRenderPitch() {return _renderPitch;} void setLeanForward(float dist); void setLeanSideways(float dist); - void addPitch(float p) {_head.pitch -= p; } - void addYaw(float y){_head.yaw -= y; } - void addRoll(float r){_head.roll += r; } + void addHeadPitch(float p) {_head.pitch -= p; } + void addHeadYaw(float y){_head.yaw -= y; } + void addHeadRoll(float r){_head.roll += r; } void addLean(float x, float z); - float getPitch() {return _head.pitch;} - float getRoll() {return _head.roll;} - float getYaw() {return _head.yaw;} - float getLastMeasuredYaw() {return _head.yawRate;} + float getHeadPitch() {return _head.pitch;} + float getHeadRoll() {return _head.roll;} + float getHeadYaw() {return _head.yaw;} + float getLastMeasuredHeadYaw() {return _head.yawRate;} float getBodyYaw() {return _bodyYaw;}; void addBodyYaw(float y) {_bodyYaw += y;}; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 1c075a62d9..287138a6a0 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -96,8 +96,6 @@ int packetsPerSecond = 0; int bytesPerSecond = 0; int bytesCount = 0; -int headMirror = 1; // Whether to mirror own head when viewing it - int WIDTH = 1200; // Window size int HEIGHT = 800; int fullscreen = 0; @@ -163,7 +161,7 @@ int noiseOn = 0; // Whether to add random noise float noise = 1.0; // Overall magnitude scaling for random noise levels int displayLevels = 0; -int displayHead = 0; +int lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror? int displayField = 0; int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement @@ -459,7 +457,7 @@ void updateAvatar(float frametime) float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE); float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE ); - myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity); + myAvatar.UpdateGyros(frametime, &serialPort, &gravity); // // Update gyro-based mouse (X,Y on screen) @@ -819,7 +817,7 @@ void display(void) //-------------------------------------------------------- // camera settings //-------------------------------------------------------- - if ( displayHead ) { + if ( lookingInMirror ) { //----------------------------------------------- // set the camera to looking at my own face //----------------------------------------------- @@ -912,7 +910,7 @@ void display(void) drawGroundPlaneGrid( 5.0f, 9 ); // Draw cloud of dots - if (!displayHead) cloud.render(); + if (!lookingInMirror) cloud.render(); // Draw voxels if ( showingVoxels ) @@ -934,16 +932,16 @@ void display(void) } } - if ( !displayHead ) balls.render(); + if ( !lookingInMirror ) balls.render(); // Render the world box - if (!displayHead && statsOn) render_world_box(); + if (!lookingInMirror && statsOn) render_world_box(); // brad's frustum for debugging if (::frustumOn) renderViewFrustum(::viewFrustum); //Render my own avatar - myAvatar.render(true); + myAvatar.render(lookingInMirror); } glPopMatrix(); @@ -961,7 +959,7 @@ void display(void) if (audioScope.getState()) audioScope.render(); #endif - if (displayHeadMouse && !displayHead && statsOn) { + if (displayHeadMouse && !lookingInMirror && statsOn) { // 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); @@ -1057,7 +1055,7 @@ int setValue(int state, bool *value) { } int setHead(int state) { - return setValue(state, &displayHead); + return setValue(state, &lookingInMirror); } int setField(int state) { @@ -1090,10 +1088,6 @@ int setMenu(int state) { return setValue(state, &::menuOn); } -int setMirror(int state) { - return setValue(state, &headMirror); -} - int setDisplayFrustum(int state) { return setValue(state, &::frustumOn); } @@ -1202,7 +1196,6 @@ void initMenu() { menuColumnOptions->addRow("(H)ead", setHead); menuColumnOptions->addRow("Field (f)", setField); menuColumnOptions->addRow("(N)oise", setNoise); - menuColumnOptions->addRow("Mirror", setMirror); menuColumnOptions->addRow("(V)oxels", setVoxels); menuColumnOptions->addRow("Stars (*)", setStars); menuColumnOptions->addRow("(Q)uit", quitApp); @@ -1411,9 +1404,9 @@ void key(unsigned char k, int x, int y) } if (k == 'h') { - displayHead = !displayHead; + lookingInMirror = !lookingInMirror; #ifndef _WIN32 - audio.setMixerLoopbackFlag(displayHead); + audio.setMixerLoopbackFlag(lookingInMirror); #endif } From 2ef45e85121833890f3db93e0f4c598d47435e05 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 23 Apr 2013 11:15:11 -0700 Subject: [PATCH 2/5] Avatar head rotation, audio loudness (for facial animation) and hand state (grabbing or not) now sent in broadcast data. --- interface/src/Head.cpp | 72 ++++++++++++++-------------- interface/src/Head.h | 16 +------ libraries/avatars/src/AvatarData.cpp | 38 +++++++++++++++ libraries/avatars/src/AvatarData.h | 40 ++++++++++++++-- 4 files changed, 109 insertions(+), 57 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index f6a3392027..38543c3441 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -75,9 +75,9 @@ Head::Head(bool isMine) { _head.interPupilDistance = 0.6; _head.interBrowDistance = 0.75; _head.nominalPupilSize = 0.10; - _head.yaw = 0.0; - _head.pitch = 0.0; - _head.roll = 0.0; + //_head.yaw = 0.0; + //_head.pitch = 0.0; + //_head.roll = 0.0; _head.pitchRate = 0.0; _head.yawRate = 0.0; _head.rollRate = 0.0; @@ -106,7 +106,6 @@ Head::Head(bool isMine) { _head.eyeContactTarget = LEFT_EYE; _head.scale = 1.0; _head.audioAttack = 0.0; - _head.loudness = 0.0; _head.averageLoudness = 0.0; _head.lastLoudness = 0.0; _head.browAudioLift = 0.0; @@ -176,9 +175,9 @@ Head::Head(const Head &otherAvatar) { _head.interPupilDistance = otherAvatar._head.interPupilDistance; _head.interBrowDistance = otherAvatar._head.interBrowDistance; _head.nominalPupilSize = otherAvatar._head.nominalPupilSize; - _head.yaw = otherAvatar._head.yaw; - _head.pitch = otherAvatar._head.pitch; - _head.roll = otherAvatar._head.roll; + //_head.yaw = otherAvatar._head.yaw; + //_head.pitch = otherAvatar._head.pitch; + //_head.roll = otherAvatar._head.roll; _head.yawRate = otherAvatar._head.yawRate; _head.pitchRate = otherAvatar._head.pitchRate; _head.rollRate = otherAvatar._head.rollRate; @@ -207,7 +206,6 @@ Head::Head(const Head &otherAvatar) { _head.eyeContactTarget = otherAvatar._head.eyeContactTarget; _head.scale = otherAvatar._head.scale; _head.audioAttack = otherAvatar._head.audioAttack; - _head.loudness = otherAvatar._head.loudness; _head.averageLoudness = otherAvatar._head.averageLoudness; _head.lastLoudness = otherAvatar._head.lastLoudness; _head.browAudioLift = otherAvatar._head.browAudioLift; @@ -234,7 +232,7 @@ Head* Head::clone() const { } void Head::reset() { - _head.pitch = _head.yaw = _head.roll = 0; + _headPitch = _headYaw = _headRoll = 0; _head.leanForward = _head.leanSideways = 0; } @@ -269,12 +267,12 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, glm:: const float MAX_YAW = 85; const float MIN_YAW = -85; - if ((_head.pitch < MAX_PITCH) && (_head.pitch > MIN_PITCH)) + if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH)) addHeadPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); addHeadRoll(measured_roll_rate * HEAD_ROLL_SCALE * frametime); - if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) + if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime); addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); @@ -489,15 +487,15 @@ void Head::simulate(float deltaTime) { if (!_head.noise) { // Decay back toward center - _head.pitch *= (1.0f - DECAY*2*deltaTime); - _head.yaw *= (1.0f - DECAY*2*deltaTime); - _head.roll *= (1.0f - DECAY*2*deltaTime); + _headPitch *= (1.0f - DECAY*2*deltaTime); + _headYaw *= (1.0f - DECAY*2*deltaTime); + _headRoll *= (1.0f - DECAY*2*deltaTime); } else { // Move toward new target - _head.pitch += (_head.pitchTarget - _head.pitch)*10*deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; - _head.yaw += (_head.yawTarget - _head.yaw )*10*deltaTime; // (1.f - DECAY*deltaTime); - _head.roll *= (1.f - DECAY*deltaTime); + _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.f*deltaTime); @@ -539,15 +537,15 @@ void Head::simulate(float deltaTime) { 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] = -_head.pitch + eye_target_pitch_adjust; - _head.eyeballYaw[0] = _head.eyeballYaw[1] = -_head.yaw + eye_target_yaw_adjust; + _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) { - _head.pitch += (randFloat() - 0.5)*0.2*_head.noiseEnvelope; - _head.yaw += (randFloat() - 0.5)*0.3*_head.noiseEnvelope; + _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]; @@ -557,7 +555,7 @@ void Head::simulate(float deltaTime) { if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5)*10; } - if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _head.pitch) < 1.0) && (fabs(_head.yawTarget - _head.yaw) < 1.0)) { + 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); } @@ -724,12 +722,14 @@ void Head::renderHead(int lookingInMirror) { glScalef( 0.03, 0.03, 0.03 ); if (lookingInMirror) { - glRotatef(_bodyYaw - _head.yaw, 0, 1, 0); + glRotatef(_bodyYaw - _headYaw, 0, 1, 0); + glRotatef(_bodyPitch + _headPitch, 1, 0, 0); + glRotatef(_bodyRoll - _headRoll, 0, 0, 1); } else { - glRotatef(_bodyYaw + _head.yaw, 0, 1, 0); + glRotatef(_bodyYaw + _headYaw, 0, 1, 0); + glRotatef(_bodyPitch + _headPitch, 1, 0, 0); + glRotatef(_bodyRoll + _headRoll, 0, 0, 1); } - glRotatef(_bodyPitch + _head.pitch, 1, 0, 0); - glRotatef(_bodyRoll + _head.roll, 0, 0, 1); glScalef(2.0, 2.0, 2.0); glColor3fv(skinColor); @@ -749,8 +749,8 @@ void Head::renderHead(int lookingInMirror) { glPopMatrix(); // _eyebrows - _head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_head.loudness - _head.lastLoudness); - _head.lastLoudness = _head.loudness; + _head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_audioLoudness - _head.lastLoudness); + _head.lastLoudness = _audioLoudness; const float BROW_LIFT_THRESHOLD = 100; if (_head.audioAttack > BROW_LIFT_THRESHOLD) @@ -813,7 +813,7 @@ void Head::renderHead(int lookingInMirror) { glPushMatrix(); { glRotatef(_head.eyeballPitch[1], 1, 0, 0); - glRotatef(_head.eyeballYaw[1] + _head.yaw + _head.pupilConverge, 0, 1, 0); + glRotatef(_head.eyeballYaw[1] + _headYaw + _head.pupilConverge, 0, 1, 0); glTranslatef(0,0,.35); glRotatef(-75,1,0,0); glScalef(1.0, 0.4, 1.0); @@ -839,7 +839,7 @@ void Head::renderHead(int lookingInMirror) { glPushMatrix(); { glRotatef(_head.eyeballPitch[0], 1, 0, 0); - glRotatef(_head.eyeballYaw[0] + _head.yaw - _head.pupilConverge, 0, 1, 0); + glRotatef(_head.eyeballYaw[0] + _headYaw - _head.pupilConverge, 0, 1, 0); glTranslatef(0, 0, .35); glRotatef(-75, 1, 0, 0); glScalef(1.0, 0.4, 1.0); @@ -1137,18 +1137,19 @@ void Head::updateHandMovement() { _bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; + setHandState(_mousePressed); + //if holding hands, add a pull to the hand... if ( _usingBodySprings ) { if ( _closestOtherAvatar != -1 ) { if ( _mousePressed ) { - - + glm::vec3 handToHandVector( _otherAvatarHandPosition[ _closestOtherAvatar ]); handToHandVector -= _bone[ AVATAR_BONE_RIGHT_HAND ].position; //_bone[ AVATAR_BONE_RIGHT_HAND ].springyVelocity -= handPull; _bone[ AVATAR_BONE_RIGHT_HAND ].position = _otherAvatarHandPosition[ _closestOtherAvatar ]; - } + } } } @@ -1278,7 +1279,7 @@ void Head::renderBody() { } } - if (( _usingBodySprings ) && ( _mousePressed )) { + if (( _usingBodySprings ) && ( getHandState() )) { glColor4f( 1.0, 1.0, 0.5, 0.5 ); glPushMatrix(); glTranslatef @@ -1306,9 +1307,6 @@ void Head::renderBoneAsBlock( AvatarBoneID b ) { glPopMatrix(); } - - - void Head::SetNewHeadTarget(float pitch, float yaw) { _head.pitchTarget = pitch; _head.yawTarget = yaw; diff --git a/interface/src/Head.h b/interface/src/Head.h index 72ac2c1ec4..b20614dd75 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -100,9 +100,6 @@ struct AvatarBone struct AvatarHead { - float pitch; - float yaw; - float roll; float pitchRate; float yawRate; float rollRate; @@ -134,7 +131,7 @@ struct AvatarHead eyeContactTargets eyeContactTarget; // Sound loudness information - float loudness, lastLoudness; + float lastLoudness; float averageLoudness; float audioAttack; }; @@ -150,9 +147,6 @@ class Head : public AvatarData { void reset(); void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity); void setNoise (float mag) { _head.noise = mag; } - void setPitch(float p) {_head.pitch = p; } - void setYaw(float y) {_head.yaw = y; } - void setRoll(float r) {_head.roll = r; }; void setScale(float s) {_head.scale = s; }; void setRenderYaw(float y) {_renderYaw = y;} void setRenderPitch(float p) {_renderPitch = p;} @@ -160,13 +154,7 @@ class Head : public AvatarData { float getRenderPitch() {return _renderPitch;} void setLeanForward(float dist); void setLeanSideways(float dist); - void addHeadPitch(float p) {_head.pitch -= p; } - void addHeadYaw(float y){_head.yaw -= y; } - void addHeadRoll(float r){_head.roll += r; } void addLean(float x, float z); - float getHeadPitch() {return _head.pitch;} - float getHeadRoll() {return _head.roll;} - float getHeadYaw() {return _head.yaw;} float getLastMeasuredHeadYaw() {return _head.yawRate;} float getBodyYaw() {return _bodyYaw;}; void addBodyYaw(float y) {_bodyYaw += y;}; @@ -189,10 +177,8 @@ class Head : public AvatarData { void setHandMovementValues( glm::vec3 movement ); void updateHandMovement(); - float getLoudness() {return _head.loudness;}; float getAverageLoudness() {return _head.averageLoudness;}; void setAverageLoudness(float al) {_head.averageLoudness = al;}; - void setLoudness(float l) {_head.loudness = l;}; void SetNewHeadTarget(float, float); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d644937464..295348a098 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -34,9 +34,14 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo } AvatarData::AvatarData() : + _handPosition(0,0,0), _bodyYaw(-90.0), _bodyPitch(0.0), _bodyRoll(0.0), + _headYaw(0), + _headPitch(0), + _headRoll(0), + _handState(0), _cameraPosition(0,0,0), _cameraDirection(0,0,0), _cameraUp(0,0,0), @@ -63,15 +68,31 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // that can pack any type given the number of bytes // and return the number of bytes to push the pointer + // Body world position memcpy(destinationBuffer, &_bodyPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; + // Body rotation (NOTE: This needs to become a quaternion to save two bytes) destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + // Head rotation (NOTE: This needs to become a quaternion to save two bytes) + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headYaw); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headPitch); + destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headRoll); + + // Hand Position memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; + + // Hand State (0 = not grabbing, 1 = grabbing) + memcpy(destinationBuffer, &_handState, sizeof(char)); + destinationBuffer += sizeof(char); + + // Instantaneous audio loudness (used to drive facial animation) + memcpy(destinationBuffer, &_audioLoudness, sizeof(float)); + destinationBuffer += sizeof(float); // camera details memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition)); @@ -91,6 +112,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip)); destinationBuffer += sizeof(_cameraFarClip); + return destinationBuffer - bufferStart; } @@ -102,16 +124,32 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* startPosition = sourceBuffer; + // Body world position memcpy(&_bodyPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + // Body rotation (NOTE: This needs to become a quaternion to save two bytes) sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); + + // Head rotation (NOTE: This needs to become a quaternion to save two bytes) + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headYaw); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headPitch); + sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headRoll); + // Hand Position memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + // Hand State + memcpy(&_handState, sourceBuffer, sizeof(char)); + sourceBuffer += sizeof(char); + + // Instantaneous audio loudness (used to drive facial animation) + memcpy(&_audioLoudness, sourceBuffer, sizeof(float)); + sourceBuffer += sizeof(float); + // camera details memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition)); sourceBuffer += sizeof(_cameraPosition); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index ea735c62fe..588390e59c 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -27,16 +27,34 @@ public: int getBroadcastData(unsigned char* destinationBuffer); int parseData(unsigned char* sourceBuffer, int numBytes); + // Body Rotation float getBodyYaw(); - void setBodyYaw(float bodyYaw); - float getBodyPitch(); - void setBodyPitch(float bodyPitch); - float getBodyRoll(); + void setBodyYaw(float bodyYaw); + void setBodyPitch(float bodyPitch); void setBodyRoll(float bodyRoll); - // getters for camera details + // Head Rotation + void setHeadPitch(float p) {_headPitch = p; } + void setHeadYaw(float y) {_headYaw = y; } + void setHeadRoll(float r) {_headRoll = r; }; + float getHeadPitch() { return _headPitch; }; + float getHeadYaw() { return _headYaw; }; + float getHeadRoll() { return _headRoll; }; + void addHeadPitch(float p) {_headPitch -= p; } + void addHeadYaw(float y){_headYaw -= y; } + void addHeadRoll(float r){_headRoll += r; } + + // Hand State + void setHandState(char s) { _handState = s; }; + float getHandState() {return _handState; }; + + // Instantaneous audio loudness to drive mouth/facial animation + void setLoudness(float l) { _audioLoudness = l; }; + float getLoudness() {return _audioLoudness; }; + + // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; }; const glm::vec3& getCameraDirection() const { return _cameraDirection; } const glm::vec3& getCameraUp() const { return _cameraUp; } @@ -60,10 +78,22 @@ protected: glm::vec3 _bodyPosition; glm::vec3 _handPosition; + // Body rotation float _bodyYaw; float _bodyPitch; float _bodyRoll; + + // Head rotation (relative to body) + float _headYaw; + float _headPitch; + float _headRoll; + // Audio loudness (used to drive facial animation) + float _audioLoudness; + + // Hand state (are we grabbing something or not) + char _handState; + // camera details for the avatar glm::vec3 _cameraPosition; From 7aea9d1e61392a771403c3b421c6d25f3d996231 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 23 Apr 2013 11:21:36 -0700 Subject: [PATCH 3/5] Fixed :: prefix for local variables --- interface/src/main.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 287138a6a0..dff24b41dd 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -817,7 +817,7 @@ void display(void) //-------------------------------------------------------- // camera settings //-------------------------------------------------------- - if ( lookingInMirror ) { + if ( ::lookingInMirror ) { //----------------------------------------------- // set the camera to looking at my own face //----------------------------------------------- @@ -910,7 +910,7 @@ void display(void) drawGroundPlaneGrid( 5.0f, 9 ); // Draw cloud of dots - if (!lookingInMirror) cloud.render(); + if (!::lookingInMirror) cloud.render(); // Draw voxels if ( showingVoxels ) @@ -932,16 +932,16 @@ void display(void) } } - if ( !lookingInMirror ) balls.render(); + if ( !::lookingInMirror ) balls.render(); // Render the world box - if (!lookingInMirror && statsOn) render_world_box(); + if (!::lookingInMirror && statsOn) render_world_box(); // brad's frustum for debugging if (::frustumOn) renderViewFrustum(::viewFrustum); //Render my own avatar - myAvatar.render(lookingInMirror); + myAvatar.render(::lookingInMirror); } glPopMatrix(); @@ -959,7 +959,7 @@ void display(void) if (audioScope.getState()) audioScope.render(); #endif - if (displayHeadMouse && !lookingInMirror && statsOn) { + if (displayHeadMouse && !::lookingInMirror && statsOn) { // 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); @@ -1055,7 +1055,7 @@ int setValue(int state, bool *value) { } int setHead(int state) { - return setValue(state, &lookingInMirror); + return setValue(state, &::lookingInMirror); } int setField(int state) { @@ -1193,7 +1193,7 @@ void initMenu() { MenuColumn *menuColumnOptions, *menuColumnTools, *menuColumnDebug, *menuColumnFrustum; // Options menuColumnOptions = menu.addColumn("Options"); - menuColumnOptions->addRow("(H)ead", setHead); + menuColumnOptions->addRow("Mirror (h)", setHead); menuColumnOptions->addRow("Field (f)", setField); menuColumnOptions->addRow("(N)oise", setNoise); menuColumnOptions->addRow("(V)oxels", setVoxels); @@ -1404,9 +1404,9 @@ void key(unsigned char k, int x, int y) } if (k == 'h') { - lookingInMirror = !lookingInMirror; + ::lookingInMirror = !::lookingInMirror; #ifndef _WIN32 - audio.setMixerLoopbackFlag(lookingInMirror); + audio.setMixerLoopbackFlag(::lookingInMirror); #endif } From 5556686875c721c523e2b13aad13894d58d12cc6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 23 Apr 2013 11:59:43 -0700 Subject: [PATCH 4/5] Fixes from brad's review --- interface/src/Head.cpp | 50 +++++++++++++++--------------- interface/src/Head.h | 4 +-- interface/src/main.cpp | 2 +- libraries/avatars/src/AvatarData.h | 10 +++--- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 38543c3441..882728f0a3 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -487,19 +487,19 @@ void Head::simulate(float deltaTime) { if (!_head.noise) { // Decay back toward center - _headPitch *= (1.0f - DECAY*2*deltaTime); - _headYaw *= (1.0f - DECAY*2*deltaTime); - _headRoll *= (1.0f - DECAY*2*deltaTime); + _headPitch *= (1.0f - DECAY * 2 * deltaTime); + _headYaw *= (1.0f - DECAY * 2 * deltaTime); + _headRoll *= (1.0f - DECAY * 2 * deltaTime); } else { // 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); + _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.f*deltaTime); - _head.leanSideways *= (1.f - DECAY*30.f*deltaTime); + _head.leanForward *= (1.f - DECAY * 30 * deltaTime); + _head.leanSideways *= (1.f - DECAY * 30 * deltaTime); // Update where the avatar's eyes are // @@ -509,8 +509,8 @@ void Head::simulate(float deltaTime) { _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; + _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); @@ -544,32 +544,32 @@ void Head::simulate(float deltaTime) { 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; + _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.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); + 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; + _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; + _head.eyebrowRoll [1] *=-1; } } } @@ -619,11 +619,11 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { } } } - + -void Head::render(int lookingInMirror) { +void Head::render(bool lookingInMirror) { //--------------------------------------------------- // show avatar position @@ -695,7 +695,7 @@ void Head::render(int lookingInMirror) { -void Head::renderHead(int lookingInMirror) { +void Head::renderHead(bool lookingInMirror) { int side = 0; glEnable(GL_DEPTH_TEST); @@ -749,17 +749,17 @@ void Head::renderHead(int lookingInMirror) { glPopMatrix(); // _eyebrows - _head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_audioLoudness - _head.lastLoudness); + _head.audioAttack = 0.9 * _head.audioAttack + 0.1 * fabs(_audioLoudness - _head.lastLoudness); _head.lastLoudness = _audioLoudness; const float BROW_LIFT_THRESHOLD = 100; if (_head.audioAttack > BROW_LIFT_THRESHOLD) - _head.browAudioLift += sqrt(_head.audioAttack)/1000.0; + _head.browAudioLift += sqrt(_head.audioAttack) / 1000.0; _head.browAudioLift *= .90; glPushMatrix(); - glTranslatef(-_head.interBrowDistance/2.0,0.4,0.45); + glTranslatef(-_head.interBrowDistance / 2.0,0.4,0.45); for(side = 0; side < 2; side++) { glColor3fv(browColor); glPushMatrix(); diff --git a/interface/src/Head.h b/interface/src/Head.h index b20614dd75..190009d962 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -168,9 +168,9 @@ class Head : public AvatarData { AvatarMode getMode(); void setMousePressed( bool pressed ); - void render(int faceToFace); + void render(bool lookingInMirror); void renderBody(); - void renderHead( int faceToFace); + void renderHead(bool lookingInMirror); void simulate(float); void startHandMovement(); void stopHandMovement(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index dff24b41dd..df77265ea9 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -161,7 +161,7 @@ int noiseOn = 0; // Whether to add random noise float noise = 1.0; // Overall magnitude scaling for random noise levels int displayLevels = 0; -int lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror? +bool lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror? int displayField = 0; int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 588390e59c..4655873dcd 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -39,20 +39,20 @@ public: void setHeadPitch(float p) {_headPitch = p; } void setHeadYaw(float y) {_headYaw = y; } void setHeadRoll(float r) {_headRoll = r; }; - float getHeadPitch() { return _headPitch; }; - float getHeadYaw() { return _headYaw; }; - float getHeadRoll() { return _headRoll; }; + const float getHeadPitch() const { return _headPitch; }; + const float getHeadYaw() const { return _headYaw; }; + const float getHeadRoll() const { return _headRoll; }; void addHeadPitch(float p) {_headPitch -= p; } void addHeadYaw(float y){_headYaw -= y; } void addHeadRoll(float r){_headRoll += r; } // Hand State void setHandState(char s) { _handState = s; }; - float getHandState() {return _handState; }; + const float getHandState() const {return _handState; }; // Instantaneous audio loudness to drive mouth/facial animation void setLoudness(float l) { _audioLoudness = l; }; - float getLoudness() {return _audioLoudness; }; + const float getLoudness() const {return _audioLoudness; }; // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; }; From 90c56e796b764530200c8012b11fb33100d72a01 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 23 Apr 2013 12:07:12 -0700 Subject: [PATCH 5/5] One... last.... const.... --- interface/src/Head.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Head.h b/interface/src/Head.h index 190009d962..0893d7a372 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -155,7 +155,7 @@ class Head : public AvatarData { void setLeanForward(float dist); void setLeanSideways(float dist); void addLean(float x, float z); - float getLastMeasuredHeadYaw() {return _head.yawRate;} + float getLastMeasuredHeadYaw() const {return _head.yawRate;} float getBodyYaw() {return _bodyYaw;}; void addBodyYaw(float y) {_bodyYaw += y;};