diff options
Diffstat (limited to 'indra/newview/llvoicevisualizer.cpp')
| -rw-r--r-- | indra/newview/llvoicevisualizer.cpp | 256 |
1 files changed, 209 insertions, 47 deletions
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp index 8d813f47aa..47060720e7 100644 --- a/indra/newview/llvoicevisualizer.cpp +++ b/indra/newview/llvoicevisualizer.cpp @@ -2,30 +2,25 @@ * @file llvoicevisualizer.cpp * @brief Draws in-world speaking indicators. * - * $LicenseInfo:firstyear=2000&license=viewergpl$ - * - * Copyright (c) 2000-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2000&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -41,11 +36,10 @@ #include "llvoicevisualizer.h" #include "llviewercamera.h" #include "llviewerobject.h" -#include "llimagegl.h" -#include "llviewerimage.h" -#include "llviewerimagelist.h" +#include "llviewertexture.h" +#include "llviewertexturelist.h" #include "llvoiceclient.h" -#include "llglimmediate.h" +#include "llrender.h" //brent's wave image //29de489d-0491-fb00-7dab-f9e686d31e83 @@ -79,6 +73,35 @@ const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE = 1.0f; const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL + +//------------------------------------------------------------------ +// handles parameter updates +//------------------------------------------------------------------ +static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue) +{ + // Note: Ignore the specific event value, we look up the ones we want + LLVoiceVisualizer::setPreferences(); + return true; +} + +//------------------------------------------------------------------ +// Initialize the statics +//------------------------------------------------------------------ +bool LLVoiceVisualizer::sPrefsInitialized = false; +BOOL LLVoiceVisualizer::sLipSyncEnabled = FALSE; +F32* LLVoiceVisualizer::sOoh = NULL; +F32* LLVoiceVisualizer::sAah = NULL; +U32 LLVoiceVisualizer::sOohs = 0; +U32 LLVoiceVisualizer::sAahs = 0; +F32 LLVoiceVisualizer::sOohAahRate = 0.0f; +F32* LLVoiceVisualizer::sOohPowerTransfer = NULL; +U32 LLVoiceVisualizer::sOohPowerTransfers = 0; +F32 LLVoiceVisualizer::sOohPowerTransfersf = 0.0f; +F32* LLVoiceVisualizer::sAahPowerTransfer = NULL; +U32 LLVoiceVisualizer::sAahPowerTransfers = 0; +F32 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f; + + //----------------------------------------------- // constructor //----------------------------------------------- @@ -87,6 +110,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) { mCurrentTime = mTimer.getTotalSeconds(); mPreviousTime = mCurrentTime; + mStartTime = mCurrentTime; mVoiceSourceWorldPosition = LLVector3( 0.0f, 0.0f, 0.0f ); mSpeakingAmplitude = 0.0f; mCurrentlySpeaking = false; @@ -98,26 +122,44 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type ) mTimer.reset(); - LLUUID sound_level_img[] = + const char* sound_level_img[] = { - LLUUID(gSavedSettings.getString("VoiceImageLevel0")), - LLUUID(gSavedSettings.getString("VoiceImageLevel1")), - LLUUID(gSavedSettings.getString("VoiceImageLevel2")), - LLUUID(gSavedSettings.getString("VoiceImageLevel3")), - LLUUID(gSavedSettings.getString("VoiceImageLevel4")), - LLUUID(gSavedSettings.getString("VoiceImageLevel5")), - LLUUID(gSavedSettings.getString("VoiceImageLevel6")) + "voice_meter_dot.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c", + "voice_meter_rings.j2c" }; for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++) { mSoundSymbol.mWaveFadeOutStartTime [i] = mCurrentTime; - mSoundSymbol.mTexture [i] = gImageList.getImageByID(sound_level_img[i]); + mSoundSymbol.mTexture [i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI); mSoundSymbol.mWaveActive [i] = false; mSoundSymbol.mWaveOpacity [i] = 1.0f; mSoundSymbol.mWaveExpansion [i] = 1.0f; } - + + mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); + + // The first instance loads the initial state from prefs. + if (!sPrefsInitialized) + { + setPreferences(); + + // Set up our listener to get updates on all prefs values we care about. + gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2)); + + sPrefsInitialized = true; + } + }//--------------------------------------------------- //--------------------------------------------------- @@ -144,6 +186,7 @@ void LLVoiceVisualizer::setVoiceEnabled( bool v ) //--------------------------------------------------- void LLVoiceVisualizer::setStartSpeaking() { + mStartTime = mTimer.getTotalSeconds(); mCurrentlySpeaking = true; mSoundSymbol.mActive = true; @@ -176,6 +219,122 @@ void LLVoiceVisualizer::setSpeakingAmplitude( F32 a ) //--------------------------------------------------- +void LLVoiceVisualizer::setPreferences( ) +{ + sLipSyncEnabled = gSavedSettings.getBOOL("LipSyncEnabled"); + sOohAahRate = gSavedSettings.getF32("LipSyncOohAahRate"); + + std::string oohString = gSavedSettings.getString("LipSyncOoh"); + lipStringToF32s (oohString, sOoh, sOohs); + + std::string aahString = gSavedSettings.getString("LipSyncAah"); + lipStringToF32s (aahString, sAah, sAahs); + + std::string oohPowerString = gSavedSettings.getString("LipSyncOohPowerTransfer"); + lipStringToF32s (oohPowerString, sOohPowerTransfer, sOohPowerTransfers); + sOohPowerTransfersf = (F32) sOohPowerTransfers; + + std::string aahPowerString = gSavedSettings.getString("LipSyncAahPowerTransfer"); + lipStringToF32s (aahPowerString, sAahPowerTransfer, sAahPowerTransfers); + sAahPowerTransfersf = (F32) sAahPowerTransfers; + +}//--------------------------------------------------- + + +//--------------------------------------------------- +// convert a string of digits to an array of floats. +// the result for each digit is the value of the +// digit multiplied by 0.11 +//--------------------------------------------------- +void LLVoiceVisualizer::lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ) +{ + delete[] out_F32s; // get rid of the current array + + count_F32s = in_string.length(); + if (count_F32s == 0) + { + // we don't like zero length arrays + + count_F32s = 1; + out_F32s = new F32[1]; + out_F32s[0] = 0.0f; + } + else + { + out_F32s = new F32[count_F32s]; + + for (U32 i=0; i<count_F32s; i++) + { + // we convert the characters 0 to 9 to their numeric value + // anything else we take the low order four bits with a ceiling of 9 + + U8 digit = in_string[i]; + U8 four_bits = digit % 16; + if (four_bits > 9) + { + four_bits = 9; + } + out_F32s[i] = 0.11f * (F32) four_bits; + } + } + +}//--------------------------------------------------- + + +//-------------------------------------------------------------------------- +// find the amount to blend the ooh and aah mouth morphs +//-------------------------------------------------------------------------- +void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah ) +{ + if( ( sLipSyncEnabled == TRUE ) && mCurrentlySpeaking ) + { + U32 transfer_index = (U32) (sOohPowerTransfersf * mSpeakingAmplitude); + if (transfer_index >= sOohPowerTransfers) + { + transfer_index = sOohPowerTransfers - 1; + } + F32 transfer_ooh = sOohPowerTransfer[transfer_index]; + + transfer_index = (U32) (sAahPowerTransfersf * mSpeakingAmplitude); + if (transfer_index >= sAahPowerTransfers) + { + transfer_index = sAahPowerTransfers - 1; + } + F32 transfer_aah = sAahPowerTransfer[transfer_index]; + + F64 current_time = mTimer.getTotalSeconds(); + F64 elapsed_time = current_time - mStartTime; + U32 elapsed_frames = (U32) (elapsed_time * sOohAahRate); + U32 elapsed_oohs = elapsed_frames % sOohs; + U32 elapsed_aahs = elapsed_frames % sAahs; + + ooh = transfer_ooh * sOoh[elapsed_oohs]; + aah = transfer_aah * sAah[elapsed_aahs]; + + /* + llinfos << " elapsed frames " << elapsed_frames + << " ooh " << ooh + << " aah " << aah + << " transfer ooh" << transfer_ooh + << " transfer aah" << transfer_aah + << " start time " << mStartTime + << " current time " << current_time + << " elapsed time " << elapsed_time + << " elapsed oohs " << elapsed_oohs + << " elapsed aahs " << elapsed_aahs + << llendl; + */ + } + else + { + ooh = 0.0f; + aah = 0.0f; + } + +}//--------------------------------------------------- + + +//--------------------------------------------------- // this method is inherited from HUD Effect //--------------------------------------------------- void LLVoiceVisualizer::render() @@ -198,13 +357,15 @@ void LLVoiceVisualizer::render() //--------------------------------------------------------------- // some gl state //--------------------------------------------------------------- - LLGLEnable blend( GL_BLEND ); + LLGLSPipelineAlpha alpha_blend; + LLGLDepthTest depth(GL_TRUE, GL_FALSE); //------------------------------------------------------------- // create coordinates of the geometry for the dot //------------------------------------------------------------- - LLVector3 l = gCamera->getLeftAxis() * DOT_SIZE; - LLVector3 u = gCamera->getUpAxis() * DOT_SIZE; + LLViewerCamera* camera = LLViewerCamera::getInstance(); + LLVector3 l = camera->getLeftAxis() * DOT_SIZE; + LLVector3 u = camera->getUpAxis() * DOT_SIZE; LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u; LLVector3 bottomRight = mSoundSymbol.mPosition - l - u; @@ -214,20 +375,20 @@ void LLVoiceVisualizer::render() //----------------------------- // bind texture 0 (the dot) //----------------------------- - mSoundSymbol.mTexture[0]->bind(); + gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[0]); //------------------------------------------------------------- // now render the dot //------------------------------------------------------------- gGL.color4fv( LLColor4( 1.0f, 1.0f, 1.0f, DOT_OPACITY ).mV ); - gGL.begin( GL_TRIANGLE_STRIP ); + gGL.begin( LLRender::TRIANGLE_STRIP ); gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); gGL.end(); - gGL.begin( GL_TRIANGLE_STRIP ); + gGL.begin( LLRender::TRIANGLE_STRIP ); gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); @@ -330,8 +491,8 @@ void LLVoiceVisualizer::render() F32 width = i * WAVE_WIDTH_SCALE * mSoundSymbol.mWaveExpansion[i]; F32 height = i * WAVE_HEIGHT_SCALE * mSoundSymbol.mWaveExpansion[i]; - LLVector3 l = gCamera->getLeftAxis() * width; - LLVector3 u = gCamera->getUpAxis() * height; + LLVector3 l = camera->getLeftAxis() * width; + LLVector3 u = camera->getUpAxis() * height; LLVector3 bottomLeft = mSoundSymbol.mPosition + l - u; LLVector3 bottomRight = mSoundSymbol.mPosition - l - u; @@ -339,18 +500,19 @@ void LLVoiceVisualizer::render() LLVector3 topRight = mSoundSymbol.mPosition - l + u; gGL.color4fv( LLColor4( red, green, blue, mSoundSymbol.mWaveOpacity[i] ).mV ); - mSoundSymbol.mTexture[i]->bind(); + gGL.getTexUnit(0)->bind(mSoundSymbol.mTexture[i]); + //--------------------------------------------------- // now, render the mofo //--------------------------------------------------- - gGL.begin( GL_TRIANGLE_STRIP ); + gGL.begin( LLRender::TRIANGLE_STRIP ); gGL.texCoord2i( 0, 0 ); gGL.vertex3fv( bottomLeft.mV ); gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); gGL.end(); - gGL.begin( GL_TRIANGLE_STRIP ); + gGL.begin( LLRender::TRIANGLE_STRIP ); gGL.texCoord2i( 1, 0 ); gGL.vertex3fv( bottomRight.mV ); gGL.texCoord2i( 1, 1 ); gGL.vertex3fv( topRight.mV ); gGL.texCoord2i( 0, 1 ); gGL.vertex3fv( topLeft.mV ); @@ -386,8 +548,8 @@ VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel() //----------------------------------------------------------------------------------------- F32 range = mMaxGesticulationAmplitude - mMinGesticulationAmplitude; - if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.66666f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; } - else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.33333f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; } + if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.5f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_HIGH; } + else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.25f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_MEDIUM; } else if ( mSpeakingAmplitude > mMinGesticulationAmplitude + range * 0.00000f ) { gesticulationLevel = VOICE_GESTICULATION_LEVEL_LOW; } return gesticulationLevel; |
