summaryrefslogtreecommitdiff
path: root/indra/newview/llvoicevisualizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvoicevisualizer.cpp')
-rw-r--r--indra/newview/llvoicevisualizer.cpp256
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;