diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 9dbfdbf07f..287325c090 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -130,7 +130,7 @@ int audioCallback (const void *inputBuffer, loudness /= BUFFER_LENGTH_SAMPLES; data->lastInputLoudness = loudness; - data->averagedInputLoudness = 0.66*data->averagedInputLoudness + 0.33*loudness; + // // If scope is turned on, copy input buffer to scope // @@ -510,9 +510,8 @@ error: } -void Audio::getInputLoudness(float * lastLoudness, float * averageLoudness) { - *lastLoudness = audioData->lastInputLoudness; - *averageLoudness = audioData->averagedInputLoudness; +float Audio::getInputLoudness() const { + return audioData->lastInputLoudness; } void Audio::render(int screenWidth, int screenHeight) diff --git a/interface/src/Audio.h b/interface/src/Audio.h index f983a315e0..f4bf594b0c 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -25,7 +25,7 @@ public: bool getMixerLoopbackFlag(); void setMixerLoopbackFlag(bool newMixerLoopbackFlag); - void getInputLoudness(float * lastLoudness, float * averageLoudness); + float getInputLoudness() const; void updateMixerParams(in_addr_t mixerAddress, in_port_t mixerPort); void setWalkingState(bool newWalkState); diff --git a/interface/src/AudioData.h b/interface/src/AudioData.h index ca7d5ec8b5..fdc15998f0 100644 --- a/interface/src/AudioData.h +++ b/interface/src/AudioData.h @@ -36,7 +36,6 @@ class AudioData { int wasStarved; float lastInputLoudness; - float averagedInputLoudness; bool mixerLoopbackFlag; bool playWalkSound; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 9770bcbce1..f6683b6a9a 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -566,6 +566,11 @@ void Head::simulate(float deltaTime) { _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; } @@ -740,16 +745,20 @@ void Head::renderHead(bool lookingInMirror) { } glPopMatrix(); - // _eyebrows - _head.audioAttack = 0.9 * _head.audioAttack + 0.1 * fabs(_audioLoudness - _head.lastLoudness); + + // Update audio attack data for facial animation (eyebrows and mouth) + _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 *= .90; + + // Render Eyebrows glPushMatrix(); glTranslatef(-_head.interBrowDistance / 2.0,0.4,0.45); for(side = 0; side < 2; side++) { @@ -1128,7 +1137,9 @@ void Head::updateHandMovement( float deltaTime ) { _bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; - setHandState(_mousePressed); + if (_isMine) { + _handState = _mousePressed; + } //--------------------------------------------------------------------- // if holding hands with another avatar, add a force to the hand... @@ -1263,7 +1274,7 @@ void Head::renderBody() { //--------------------------------------------------------- // if the hand is grasping, show it... //--------------------------------------------------------- - if (( _usingBodySprings ) && ( getHandState() == 1 )) { + if (( _usingBodySprings ) && ( _handState == 1 )) { glPushMatrix(); glTranslatef ( diff --git a/interface/src/main.cpp b/interface/src/main.cpp index d890a380a7..41ffdc1e92 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -160,8 +160,10 @@ bool perfStatsOn = false; // Do we want to display perfStats? int noiseOn = 0; // Whether to add random noise float noise = 1.0; // Overall magnitude scaling for random noise levels +bool gyroLook = false; // 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? +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 @@ -476,31 +478,16 @@ void updateAvatar(float frametime) headMouseY = min(headMouseY, HEIGHT); // Update render direction (pitch/yaw) based on measured gyro rates - const int MIN_YAW_RATE = 100; - const int MIN_PITCH_RATE = 100; - const float YAW_SENSITIVITY = 0.02; - const float PITCH_SENSITIVITY = 0.05; + const float MIN_YAW_RATE = 5; + const float YAW_SENSITIVITY = 1.0; - // Update render pitch and yaw rates based on keyPositions - const float KEY_YAW_SENSITIVITY = 2.0; - if (myAvatar.getDriveKeys(ROT_LEFT)) renderYawRate -= KEY_YAW_SENSITIVITY*frametime; - if (myAvatar.getDriveKeys(ROT_RIGHT)) renderYawRate += KEY_YAW_SENSITIVITY*frametime; + // If enabled, Update render pitch and yaw based on gyro data + if (::gyroLook) { + if (fabs(gyroYawRate) > MIN_YAW_RATE) { + myAvatar.addBodyYaw(-gyroYawRate * YAW_SENSITIVITY * frametime); + } + } - if (fabs(gyroYawRate) > MIN_YAW_RATE) - { - if (gyroYawRate > 0) - renderYawRate += (gyroYawRate - MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; - else - renderYawRate += (gyroYawRate + MIN_YAW_RATE) * YAW_SENSITIVITY * frametime; - } - if (fabs(gyroPitchRate) > MIN_PITCH_RATE) - { - if (gyroPitchRate > 0) - renderPitchRate += (gyroPitchRate - MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; - else - renderPitchRate += (gyroPitchRate + MIN_PITCH_RATE) * PITCH_SENSITIVITY * frametime; - } - float renderPitch = myAvatar.getRenderPitch(); // Decay renderPitch toward zero because we never look constantly up/down renderPitch *= (1.f - 2.0*frametime); @@ -514,11 +501,8 @@ void updateAvatar(float frametime) myAvatar.setRenderPitch(renderPitch + renderPitchRate); // Get audio loudness data from audio input device - float loudness, averageLoudness; #ifndef _WIN32 - audio.getInputLoudness(&loudness, &averageLoudness); - myAvatar.setLoudness(loudness); - myAvatar.setAverageLoudness(averageLoudness); + myAvatar.setLoudness(audio.getInputLoudness()); #endif // Update Avatar with latest camera and view frustum data... @@ -1072,6 +1056,11 @@ int setNoise(int state) { return iRet; } +int setGyroLook(int state) { + int iRet = setValue(state, &::gyroLook); + return iRet; +} + int setVoxels(int state) { return setValue(state, &::showingVoxels); } @@ -1190,16 +1179,20 @@ const char* getFrustumRenderModeName(int state) { } void initMenu() { - MenuColumn *menuColumnOptions, *menuColumnTools, *menuColumnDebug, *menuColumnFrustum; + MenuColumn *menuColumnOptions, *menuColumnRender, *menuColumnTools, *menuColumnDebug, *menuColumnFrustum; // Options menuColumnOptions = menu.addColumn("Options"); menuColumnOptions->addRow("Mirror (h)", setHead); - menuColumnOptions->addRow("Field (f)", setField); - menuColumnOptions->addRow("(N)oise", setNoise); - menuColumnOptions->addRow("(V)oxels", setVoxels); - menuColumnOptions->addRow("Stars (*)", setStars); - menuColumnOptions->addRow("(Q)uit", quitApp); + menuColumnOptions->addRow("Noise (n)", setNoise); + menuColumnOptions->addRow("Gyro Look", setGyroLook); + menuColumnOptions->addRow("Quit (q)", quitApp); + // Render + menuColumnRender = menu.addColumn("Render"); + menuColumnRender->addRow("Voxels (V)", setVoxels); + menuColumnRender->addRow("Stars (*)", setStars); + menuColumnRender->addRow("Field (f)", setField); + // Tools menuColumnTools = menu.addColumn("Tools"); menuColumnTools->addRow("Stats (/)", setStats); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c403a1683a..cb2171cbe5 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; }; - const float getHeadPitch() const { return _headPitch; }; - const float getHeadYaw() const { return _headYaw; }; - const float getHeadRoll() const { return _headRoll; }; + float getHeadPitch() const { return _headPitch; }; + float getHeadYaw() const { return _headYaw; }; + 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; }; - const float getHandState() const {return _handState; }; //@Philip - shouldn't this be an int or a char? + char getHandState() const {return _handState; }; // Instantaneous audio loudness to drive mouth/facial animation void setLoudness(float l) { _audioLoudness = l; }; - const float getLoudness() const {return _audioLoudness; }; + float getLoudness() const {return _audioLoudness; }; // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; };