summaryrefslogtreecommitdiff
path: root/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llvoavatar.cpp')
-rw-r--r--indra/newview/llvoavatar.cpp218
1 files changed, 133 insertions, 85 deletions
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f3384c4a7e..0783468bb7 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -95,7 +95,6 @@
#include "llstatusbar.h"
#include "lltargetingmotion.h"
#include "lltexlayer.h"
-#include "lltoolbar.h"
#include "lltoolgrab.h" // for needsRenderBeam
#include "lltoolmgr.h" // for needsRenderBeam
#include "lltoolmorph.h"
@@ -117,20 +116,13 @@
#include "llspatialpartition.h"
#include "llglslshader.h"
#include "llappviewer.h"
-#include "lscript_byteformat.h"
+#include "llsky.h"
//#include "vtune/vtuneapi.h"
-//Ventrella
-#include "llgesturemgr.h" //needed to trigger the voice gestculations
+#include "llgesturemgr.h" //needed to trigger the voice gesticulations
#include "llvoicevisualizer.h"
#include "llvoiceclient.h"
-//end Ventrella
-
-// Direct imports, evil
-extern LLSky gSky;
-extern void set_avatar_character(void* charNameArg);
-extern BOOL gRenderForSelect;
LLXmlTree LLVOAvatar::sXMLTree;
LLXmlTree LLVOAvatar::sSkeletonXMLTree;
@@ -766,6 +758,10 @@ LLVOAvatar::LLVOAvatar(
mStepOnLand = TRUE;
mStepMaterial = 0;
+ mLipSyncActive = false;
+ mOohMorph = NULL;
+ mAahMorph = NULL;
+
//-------------------------------------------------------------------------
// initialize joint, mesh and shape members
//-------------------------------------------------------------------------
@@ -950,10 +946,8 @@ LLVOAvatar::LLVOAvatar(
//VTPause(); // VTune
- //Ventrella
mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
mCurrentGesticulationLevel = 0;
- //END Ventrella
}
//------------------------------------------------------------------------
@@ -1887,6 +1881,26 @@ void LLVOAvatar::buildCharacter()
updateHeadOffset();
//-------------------------------------------------------------------------
+ // initialize lip sync morph pointers
+ //-------------------------------------------------------------------------
+ mOohMorph = getVisualParam( "Lipsync_Ooh" );
+ mAahMorph = getVisualParam( "Lipsync_Aah" );
+
+ // If we don't have the Ooh morph, use the Kiss morph
+ if (!mOohMorph)
+ {
+ llwarns << "Missing 'Ooh' morph for lipsync, using fallback." << llendl;
+ mOohMorph = getVisualParam( "Express_Kiss" );
+ }
+
+ // If we don't have the Aah morph, use the Open Mouth morph
+ if (!mAahMorph)
+ {
+ llwarns << "Missing 'Aah' morph for lipsync, using fallback." << llendl;
+ mAahMorph = getVisualParam( "Express_Open_Mouth" );
+ }
+
+ //-------------------------------------------------------------------------
// start default motions
//-------------------------------------------------------------------------
startMotion( ANIM_AGENT_HEAD_ROT );
@@ -2449,88 +2463,93 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
// animate the character
// store off last frame's root position to be consistent with camera position
LLVector3 root_pos_last = mRoot.getWorldPosition();
-
BOOL detailed_update = updateCharacter(agent);
+ bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
- {
- //Ventrella
- bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
- // disable voice visualizer when in mouselook
- mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) );
- if ( voiceEnabled )
- {
- //----------------------------------------------------------------
- // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
- //----------------------------------------------------------------
- if( mIsSelf )
+ // disable voice visualizer when in mouselook
+ mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) );
+ if ( voiceEnabled )
+ {
+ //----------------------------------------------------------------
+ // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
+ //----------------------------------------------------------------
+ if( mIsSelf )
+ {
+ //----------------------------------------------------------------------------------------
+ // The following takes the voice signal and uses that to trigger gesticulations.
+ //----------------------------------------------------------------------------------------
+ int lastGesticulationLevel = mCurrentGesticulationLevel;
+ mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
+
+ //---------------------------------------------------------------------------------------------------
+ // If "current gesticulation level" changes, we catch this, and trigger the new gesture
+ //---------------------------------------------------------------------------------------------------
+ if ( lastGesticulationLevel != mCurrentGesticulationLevel )
{
- //----------------------------------------------------------------------------------------
- // The following takes the voice signal and uses that to trigger gesticulations.
- //----------------------------------------------------------------------------------------
- int lastGesticulationLevel = mCurrentGesticulationLevel;
- mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
-
- //---------------------------------------------------------------------------------------------------
- // If "current gesticulation level" changes, we catch this, and trigger the new gesture
- //---------------------------------------------------------------------------------------------------
- if ( lastGesticulationLevel != mCurrentGesticulationLevel )
+ if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
{
- if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
- {
- LLString gestureString = "unInitialized";
- if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
- else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
- else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
- else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; }
-
- // this is the call that Karl S. created for triggering gestures from within the code.
- gGestureManager.triggerAndReviseString( gestureString );
- }
- }
-
- } //if( mIsSelf )
-
- //-----------------------------------------------------------------------------------------------------------------
- // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
- // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
- //
- // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
- // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
- //-----------------------------------------------------------------------------------------------------------------
- if ( gVoiceClient->getIsSpeaking( mID ) )
- {
- if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
- {
- mVoiceVisualizer->setStartSpeaking();
+ LLString gestureString = "unInitialized";
+ if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
+ else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
+ else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
+ else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; }
- //printf( "gAwayTimer.reset();\n" );
- }
-
- mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
-
- if( mIsSelf )
- {
- gAgent.clearAFK();
+ // this is the call that Karl S. created for triggering gestures from within the code.
+ gGestureManager.triggerAndReviseString( gestureString );
}
}
- else
+
+ } //if( mIsSelf )
+
+ //-----------------------------------------------------------------------------------------------------------------
+ // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
+ // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
+ //
+ // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
+ // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
+ //-----------------------------------------------------------------------------------------------------------------
+ if ( gVoiceClient->getIsSpeaking( mID ) )
+ {
+ if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
{
- if ( mVoiceVisualizer->getCurrentlySpeaking() )
+ mVoiceVisualizer->setStartSpeaking();
+
+ //printf( "gAwayTimer.reset();\n" );
+ }
+
+ mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
+
+ if( mIsSelf )
+ {
+ gAgent.clearAFK();
+ }
+ }
+ else
+ {
+ if ( mVoiceVisualizer->getCurrentlySpeaking() )
+ {
+ mVoiceVisualizer->setStopSpeaking();
+
+ if ( mLipSyncActive )
{
- mVoiceVisualizer->setStopSpeaking();
+ if( mOohMorph ) mOohMorph->setWeight(mOohMorph->getMinWeight(), FALSE);
+ if( mAahMorph ) mAahMorph->setWeight(mAahMorph->getMinWeight(), FALSE);
+
+ mLipSyncActive = false;
+ LLCharacter::updateVisualParams();
+ dirtyMesh();
}
}
-
- //--------------------------------------------------------------------------------------------
- // here we get the approximate head position and set as sound source for the voice symbol
- // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
- //--------------------------------------------------------------------------------------------
- LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
- mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
-
- }//if ( voiceEnabled )
- }
- //End Ventrella
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // here we get the approximate head position and set as sound source for the voice symbol
+ // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
+ //--------------------------------------------------------------------------------------------
+ LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
+ mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
+
+ }//if ( voiceEnabled )
if (LLVOAvatar::sJointDebug)
{
@@ -2704,6 +2723,35 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
dirtyMesh();
}
+ // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
+ if ( voiceEnabled && (gVoiceClient->lipSyncEnabled() > 0) && gVoiceClient->getIsSpeaking( mID ) )
+ {
+ F32 ooh_morph_amount = 0.0f;
+ F32 aah_morph_amount = 0.0f;
+
+ mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount );
+
+ if( mOohMorph )
+ {
+ F32 ooh_weight = mOohMorph->getMinWeight()
+ + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight());
+
+ mOohMorph->setWeight( ooh_weight, FALSE );
+ }
+
+ if( mAahMorph )
+ {
+ F32 aah_weight = mAahMorph->getMinWeight()
+ + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight());
+
+ mAahMorph->setWeight( aah_weight, FALSE );
+ }
+
+ mLipSyncActive = true;
+ LLCharacter::updateVisualParams();
+ dirtyMesh();
+ }
+
// update wind effect
if ((LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
{
@@ -3883,7 +3931,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
updateMeshData();
- mDirtyMesh = FALSE;
+ mDirtyMesh = FALSE;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}
@@ -9507,7 +9555,7 @@ BOOL LLVOAvatar::updateLOD()
if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
updateMeshData();
- mDirtyMesh = FALSE;
+ mDirtyMesh = FALSE;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}