aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvoavatar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llvoavatar.cpp')
-rw-r--r--linden/indra/newview/llvoavatar.cpp375
1 files changed, 277 insertions, 98 deletions
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index 7de2f9c..6b5f066 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -37,7 +37,7 @@
37 37
38#include "llvoavatar.h" 38#include "llvoavatar.h"
39 39
40#include "llglimmediate.h" 40#include "llrender.h"
41#include "audioengine.h" 41#include "audioengine.h"
42#include "imageids.h" 42#include "imageids.h"
43#include "indra_constants.h" 43#include "indra_constants.h"
@@ -95,7 +95,6 @@
95#include "llstatusbar.h" 95#include "llstatusbar.h"
96#include "lltargetingmotion.h" 96#include "lltargetingmotion.h"
97#include "lltexlayer.h" 97#include "lltexlayer.h"
98#include "lltoolbar.h"
99#include "lltoolgrab.h" // for needsRenderBeam 98#include "lltoolgrab.h" // for needsRenderBeam
100#include "lltoolmgr.h" // for needsRenderBeam 99#include "lltoolmgr.h" // for needsRenderBeam
101#include "lltoolmorph.h" 100#include "lltoolmorph.h"
@@ -117,20 +116,14 @@
117#include "llspatialpartition.h" 116#include "llspatialpartition.h"
118#include "llglslshader.h" 117#include "llglslshader.h"
119#include "llappviewer.h" 118#include "llappviewer.h"
120#include "lscript_byteformat.h" 119#include "llsky.h"
120#include "llanimstatelabels.h"
121 121
122//#include "vtune/vtuneapi.h" 122//#include "vtune/vtuneapi.h"
123 123
124//Ventrella 124#include "llgesturemgr.h" //needed to trigger the voice gesticulations
125#include "llgesturemgr.h" //needed to trigger the voice gestculations
126#include "llvoicevisualizer.h" 125#include "llvoicevisualizer.h"
127#include "llvoiceclient.h" 126#include "llvoiceclient.h"
128//end Ventrella
129
130// Direct imports, evil
131extern LLSky gSky;
132extern void set_avatar_character(void* charNameArg);
133extern BOOL gRenderForSelect;
134 127
135LLXmlTree LLVOAvatar::sXMLTree; 128LLXmlTree LLVOAvatar::sXMLTree;
136LLXmlTree LLVOAvatar::sSkeletonXMLTree; 129LLXmlTree LLVOAvatar::sSkeletonXMLTree;
@@ -686,7 +679,8 @@ LLVOAvatar::LLVOAvatar(
686 mTexHairColor( NULL ), 679 mTexHairColor( NULL ),
687 mTexEyeColor( NULL ), 680 mTexEyeColor( NULL ),
688 mNeedsSkin(FALSE), 681 mNeedsSkin(FALSE),
689 mUpdatePeriod(1) 682 mUpdatePeriod(1),
683 mFullyLoadedInitialized(FALSE)
690{ 684{
691 LLMemType mt(LLMemType::MTYPE_AVATAR); 685 LLMemType mt(LLMemType::MTYPE_AVATAR);
692 686
@@ -766,6 +760,10 @@ LLVOAvatar::LLVOAvatar(
766 mStepOnLand = TRUE; 760 mStepOnLand = TRUE;
767 mStepMaterial = 0; 761 mStepMaterial = 0;
768 762
763 mLipSyncActive = false;
764 mOohMorph = NULL;
765 mAahMorph = NULL;
766
769 //------------------------------------------------------------------------- 767 //-------------------------------------------------------------------------
770 // initialize joint, mesh and shape members 768 // initialize joint, mesh and shape members
771 //------------------------------------------------------------------------- 769 //-------------------------------------------------------------------------
@@ -950,10 +948,8 @@ LLVOAvatar::LLVOAvatar(
950 948
951 //VTPause(); // VTune 949 //VTPause(); // VTune
952 950
953 //Ventrella
954 mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) ); 951 mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
955 mCurrentGesticulationLevel = 0; 952 mCurrentGesticulationLevel = 0;
956 //END Ventrella
957} 953}
958 954
959//------------------------------------------------------------------------ 955//------------------------------------------------------------------------
@@ -1887,6 +1883,26 @@ void LLVOAvatar::buildCharacter()
1887 updateHeadOffset(); 1883 updateHeadOffset();
1888 1884
1889 //------------------------------------------------------------------------- 1885 //-------------------------------------------------------------------------
1886 // initialize lip sync morph pointers
1887 //-------------------------------------------------------------------------
1888 mOohMorph = getVisualParam( "Lipsync_Ooh" );
1889 mAahMorph = getVisualParam( "Lipsync_Aah" );
1890
1891 // If we don't have the Ooh morph, use the Kiss morph
1892 if (!mOohMorph)
1893 {
1894 llwarns << "Missing 'Ooh' morph for lipsync, using fallback." << llendl;
1895 mOohMorph = getVisualParam( "Express_Kiss" );
1896 }
1897
1898 // If we don't have the Aah morph, use the Open Mouth morph
1899 if (!mAahMorph)
1900 {
1901 llwarns << "Missing 'Aah' morph for lipsync, using fallback." << llendl;
1902 mAahMorph = getVisualParam( "Express_Open_Mouth" );
1903 }
1904
1905 //-------------------------------------------------------------------------
1890 // start default motions 1906 // start default motions
1891 //------------------------------------------------------------------------- 1907 //-------------------------------------------------------------------------
1892 startMotion( ANIM_AGENT_HEAD_ROT ); 1908 startMotion( ANIM_AGENT_HEAD_ROT );
@@ -2449,88 +2465,93 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
2449 // animate the character 2465 // animate the character
2450 // store off last frame's root position to be consistent with camera position 2466 // store off last frame's root position to be consistent with camera position
2451 LLVector3 root_pos_last = mRoot.getWorldPosition(); 2467 LLVector3 root_pos_last = mRoot.getWorldPosition();
2452
2453 BOOL detailed_update = updateCharacter(agent); 2468 BOOL detailed_update = updateCharacter(agent);
2469 bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
2454 2470
2455 { 2471 // disable voice visualizer when in mouselook
2456 //Ventrella 2472 mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) );
2457 bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel(); 2473 if ( voiceEnabled )
2458 // disable voice visualizer when in mouselook 2474 {
2459 mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) ); 2475 //----------------------------------------------------------------
2460 if ( voiceEnabled ) 2476 // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
2461 { 2477 //----------------------------------------------------------------
2462 //---------------------------------------------------------------- 2478 if( mIsSelf )
2463 // Only do gesture triggering for your own avatar, and only when you're in a proximal channel. 2479 {
2464 //---------------------------------------------------------------- 2480 //----------------------------------------------------------------------------------------
2465 if( mIsSelf ) 2481 // The following takes the voice signal and uses that to trigger gesticulations.
2482 //----------------------------------------------------------------------------------------
2483 int lastGesticulationLevel = mCurrentGesticulationLevel;
2484 mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
2485
2486 //---------------------------------------------------------------------------------------------------
2487 // If "current gesticulation level" changes, we catch this, and trigger the new gesture
2488 //---------------------------------------------------------------------------------------------------
2489 if ( lastGesticulationLevel != mCurrentGesticulationLevel )
2466 { 2490 {
2467 //---------------------------------------------------------------------------------------- 2491 if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
2468 // The following takes the voice signal and uses that to trigger gesticulations.
2469 //----------------------------------------------------------------------------------------
2470 int lastGesticulationLevel = mCurrentGesticulationLevel;
2471 mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
2472
2473 //---------------------------------------------------------------------------------------------------
2474 // If "current gesticulation level" changes, we catch this, and trigger the new gesture
2475 //---------------------------------------------------------------------------------------------------
2476 if ( lastGesticulationLevel != mCurrentGesticulationLevel )
2477 {
2478 if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
2479 {
2480 LLString gestureString = "unInitialized";
2481 if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
2482 else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
2483 else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
2484 else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; }
2485
2486 // this is the call that Karl S. created for triggering gestures from within the code.
2487 gGestureManager.triggerAndReviseString( gestureString );
2488 }
2489 }
2490
2491 } //if( mIsSelf )
2492
2493 //-----------------------------------------------------------------------------------------------------------------
2494 // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
2495 // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
2496 //
2497 // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
2498 // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
2499 //-----------------------------------------------------------------------------------------------------------------
2500 if ( gVoiceClient->getIsSpeaking( mID ) )
2501 {
2502 if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
2503 { 2492 {
2504 mVoiceVisualizer->setStartSpeaking(); 2493 LLString gestureString = "unInitialized";
2494 if ( mCurrentGesticulationLevel == 0 ) { gestureString = "/voicelevel1"; }
2495 else if ( mCurrentGesticulationLevel == 1 ) { gestureString = "/voicelevel2"; }
2496 else if ( mCurrentGesticulationLevel == 2 ) { gestureString = "/voicelevel3"; }
2497 else { llinfos << "oops - CurrentGesticulationLevel can be only 0, 1, or 2" << llendl; }
2505 2498
2506 //printf( "gAwayTimer.reset();\n" ); 2499 // this is the call that Karl S. created for triggering gestures from within the code.
2507 } 2500 gGestureManager.triggerAndReviseString( gestureString );
2508
2509 mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
2510
2511 if( mIsSelf )
2512 {
2513 gAgent.clearAFK();
2514 } 2501 }
2515 } 2502 }
2516 else 2503
2504 } //if( mIsSelf )
2505
2506 //-----------------------------------------------------------------------------------------------------------------
2507 // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
2508 // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
2509 //
2510 // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
2511 // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking.
2512 //-----------------------------------------------------------------------------------------------------------------
2513 if ( gVoiceClient->getIsSpeaking( mID ) )
2514 {
2515 if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
2516 {
2517 mVoiceVisualizer->setStartSpeaking();
2518
2519 //printf( "gAwayTimer.reset();\n" );
2520 }
2521
2522 mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
2523
2524 if( mIsSelf )
2525 {
2526 gAgent.clearAFK();
2527 }
2528 }
2529 else
2530 {
2531 if ( mVoiceVisualizer->getCurrentlySpeaking() )
2517 { 2532 {
2518 if ( mVoiceVisualizer->getCurrentlySpeaking() ) 2533 mVoiceVisualizer->setStopSpeaking();
2534
2535 if ( mLipSyncActive )
2519 { 2536 {
2520 mVoiceVisualizer->setStopSpeaking(); 2537 if( mOohMorph ) mOohMorph->setWeight(mOohMorph->getMinWeight(), FALSE);
2538 if( mAahMorph ) mAahMorph->setWeight(mAahMorph->getMinWeight(), FALSE);
2539
2540 mLipSyncActive = false;
2541 LLCharacter::updateVisualParams();
2542 dirtyMesh();
2521 } 2543 }
2522 } 2544 }
2523 2545 }
2524 //-------------------------------------------------------------------------------------------- 2546
2525 // here we get the approximate head position and set as sound source for the voice symbol 2547 //--------------------------------------------------------------------------------------------
2526 // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing) 2548 // here we get the approximate head position and set as sound source for the voice symbol
2527 //-------------------------------------------------------------------------------------------- 2549 // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
2528 LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] ); 2550 //--------------------------------------------------------------------------------------------
2529 mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset ); 2551 LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
2530 2552 mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
2531 }//if ( voiceEnabled ) 2553
2532 } 2554 }//if ( voiceEnabled )
2533 //End Ventrella
2534 2555
2535 if (LLVOAvatar::sJointDebug) 2556 if (LLVOAvatar::sJointDebug)
2536 { 2557 {
@@ -2704,6 +2725,76 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
2704 dirtyMesh(); 2725 dirtyMesh();
2705 } 2726 }
2706 2727
2728 // Use the Lipsync_Ooh and Lipsync_Aah morphs for lip sync
2729 if ( voiceEnabled && (gVoiceClient->lipSyncEnabled()) && gVoiceClient->getIsSpeaking( mID ) )
2730 {
2731 F32 ooh_morph_amount = 0.0f;
2732 F32 aah_morph_amount = 0.0f;
2733
2734 mVoiceVisualizer->lipSyncOohAah( ooh_morph_amount, aah_morph_amount );
2735
2736 if( mOohMorph )
2737 {
2738 F32 ooh_weight = mOohMorph->getMinWeight()
2739 + ooh_morph_amount * (mOohMorph->getMaxWeight() - mOohMorph->getMinWeight());
2740
2741 mOohMorph->setWeight( ooh_weight, FALSE );
2742 }
2743
2744 if( mAahMorph )
2745 {
2746 F32 aah_weight = mAahMorph->getMinWeight()
2747 + aah_morph_amount * (mAahMorph->getMaxWeight() - mAahMorph->getMinWeight());
2748
2749 mAahMorph->setWeight( aah_weight, FALSE );
2750 }
2751
2752 mLipSyncActive = true;
2753 LLCharacter::updateVisualParams();
2754 dirtyMesh();
2755 }
2756
2757 // update visibility when avatar is partially loaded
2758 if (updateIsFullyLoaded()) // changed?
2759 {
2760 if (isFullyLoaded())
2761 {
2762 deleteParticleSource();
2763 }
2764 else
2765 {
2766 LLPartSysData particle_parameters;
2767
2768 // fancy particle cloud designed by Brent
2769 particle_parameters.mPartData.mMaxAge = 4.f;
2770 particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
2771 particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
2772 particle_parameters.mPartData.mStartScale.mV[VY] = 1.0f;
2773 particle_parameters.mPartData.mEndScale.mV[VX] = 0.02f;
2774 particle_parameters.mPartData.mEndScale.mV[VY] = 0.02f;
2775 particle_parameters.mPartData.mStartColor = LLColor4(1, 1, 1, 0.5f);
2776 particle_parameters.mPartData.mEndColor = LLColor4(1, 1, 1, 0.0f);
2777 particle_parameters.mPartData.mStartScale.mV[VX] = 0.8f;
2778 LLViewerImage* cloud = gImageList.getImageFromFile("cloud-particle.j2c");
2779 particle_parameters.mPartImageID = cloud->getID();
2780 particle_parameters.mMaxAge = 0.f;
2781 particle_parameters.mPattern = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
2782 particle_parameters.mInnerAngle = 3.14159f;
2783 particle_parameters.mOuterAngle = 0.f;
2784 particle_parameters.mBurstRate = 0.02f;
2785 particle_parameters.mBurstRadius = 0.0f;
2786 particle_parameters.mBurstPartCount = 1;
2787 particle_parameters.mBurstSpeedMin = 0.1f;
2788 particle_parameters.mBurstSpeedMax = 1.f;
2789 particle_parameters.mPartData.mFlags = ( LLPartData::LL_PART_INTERP_COLOR_MASK | LLPartData::LL_PART_INTERP_SCALE_MASK |
2790 LLPartData::LL_PART_EMISSIVE_MASK | // LLPartData::LL_PART_FOLLOW_SRC_MASK |
2791 LLPartData::LL_PART_TARGET_POS_MASK );
2792
2793 setParticleSource(particle_parameters, getID());
2794 }
2795 }
2796
2797
2707 // update wind effect 2798 // update wind effect
2708 if ((LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)) 2799 if ((LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
2709 { 2800 {
@@ -3883,7 +3974,7 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
3883 if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) 3974 if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
3884 { //LOD changed or new mesh created, allocate new vertex buffer if needed 3975 { //LOD changed or new mesh created, allocate new vertex buffer if needed
3885 updateMeshData(); 3976 updateMeshData();
3886 mDirtyMesh = FALSE; 3977 mDirtyMesh = FALSE;
3887 mNeedsSkin = TRUE; 3978 mNeedsSkin = TRUE;
3888 mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); 3979 mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
3889 } 3980 }
@@ -3957,7 +4048,10 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
3957 } 4048 }
3958 4049
3959 // render collision normal 4050 // render collision normal
3960 if (sShowFootPlane && mDrawable.notNull()) 4051 // *NOTE: this is disabled (there is no UI for enabling sShowFootPlane) due
4052 // to DEV-14477. the code is left here to aid in tracking down the cause
4053 // of the crash in the future. -brad
4054 if (!gRenderForSelect && sShowFootPlane && mDrawable.notNull())
3961 { 4055 {
3962 LLVector3 slaved_pos = mDrawable->getPositionAgent(); 4056 LLVector3 slaved_pos = mDrawable->getPositionAgent();
3963 LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]); 4057 LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]);
@@ -3985,7 +4079,9 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
3985 gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); 4079 gGL.vertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]);
3986 gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); 4080 gGL.vertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]);
3987 4081
3988 }gGL.end(); 4082 }
4083 gGL.end();
4084 gGL.flush();
3989 } 4085 }
3990 //-------------------------------------------------------------------- 4086 //--------------------------------------------------------------------
3991 // render all geomety attached to the skeleton 4087 // render all geomety attached to the skeleton
@@ -4027,23 +4123,23 @@ U32 LLVOAvatar::renderTransparent()
4027 BOOL first_pass = FALSE; 4123 BOOL first_pass = FALSE;
4028 if( isWearingWearableType( WT_SKIRT ) ) 4124 if( isWearingWearableType( WT_SKIRT ) )
4029 { 4125 {
4030 glAlphaFunc(GL_GREATER,0.25f); 4126 gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);
4031 num_indices += mSkirtLOD.render(mAdjustedPixelArea, FALSE); 4127 num_indices += mSkirtLOD.render(mAdjustedPixelArea, FALSE);
4032 first_pass = FALSE; 4128 first_pass = FALSE;
4033 glAlphaFunc(GL_GREATER,0.01f); 4129 gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
4034 } 4130 }
4035 4131
4036 if (!mIsSelf || gAgent.needsRenderHead()) 4132 if (!mIsSelf || gAgent.needsRenderHead())
4037 { 4133 {
4038 if (LLPipeline::sImpostorRender) 4134 if (LLPipeline::sImpostorRender)
4039 { 4135 {
4040 glAlphaFunc(GL_GREATER, 0.5f); 4136 gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
4041 } 4137 }
4042 num_indices += mEyeLashLOD.render(mAdjustedPixelArea, first_pass); 4138 num_indices += mEyeLashLOD.render(mAdjustedPixelArea, first_pass);
4043 num_indices += mHairLOD.render(mAdjustedPixelArea, FALSE); 4139 num_indices += mHairLOD.render(mAdjustedPixelArea, FALSE);
4044 if (LLPipeline::sImpostorRender) 4140 if (LLPipeline::sImpostorRender)
4045 { 4141 {
4046 glAlphaFunc(GL_GREATER, 0.01f); 4142 gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
4047 } 4143 }
4048 } 4144 }
4049 4145
@@ -4136,7 +4232,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color)
4136 up *= mImpostorDim.mV[1]; 4232 up *= mImpostorDim.mV[1];
4137 4233
4138 LLGLEnable test(GL_ALPHA_TEST); 4234 LLGLEnable test(GL_ALPHA_TEST);
4139 glAlphaFunc(GL_GREATER, 0.f); 4235 gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f);
4140 4236
4141 gGL.color4f(1,1,1,1); 4237 gGL.color4f(1,1,1,1);
4142 gGL.color4ubv(color.mV); 4238 gGL.color4ubv(color.mV);
@@ -6637,6 +6733,89 @@ BOOL LLVOAvatar::isVisible()
6637} 6733}
6638 6734
6639 6735
6736// call periodically to keep isFullyLoaded up to date.
6737// returns true if the value has changed.
6738BOOL LLVOAvatar::updateIsFullyLoaded()
6739{
6740 // a "heuristic" to determine if we have enough avatar data to render
6741 // (to avoid rendering a "Ruth" - DEV-3168)
6742
6743 BOOL loading = FALSE;
6744
6745 // do we have a shape?
6746 if (visualParamWeightsAreDefault())
6747 {
6748 loading = TRUE;
6749 }
6750
6751 // are our texture settings still default?
6752 if ((getTEImage( TEX_HAIR )->getID() == IMG_DEFAULT))
6753 {
6754 loading = TRUE;
6755 }
6756
6757 // special case to keep nudity off orientation island -
6758 // this is fragilely dependent on the compositing system,
6759 // which gets available textures in the following order:
6760 //
6761 // 1) use the baked texture
6762 // 2) use the layerset
6763 // 3) use the previously baked texture
6764 //
6765 // on orientation island case (3) can show naked skin.
6766 // so we test for that here:
6767 //
6768 // if we were previously unloaded, and we don't have enough
6769 // texture info for our shirt/pants, stay unloaded:
6770 if (!mPreviousFullyLoaded)
6771 {
6772 if ((!isLocalTextureDataAvailable(mLowerBodyLayerSet)) &&
6773 (getTEImage(TEX_LOWER_BAKED)->getID() == IMG_DEFAULT_AVATAR))
6774 {
6775 loading = TRUE;
6776 }
6777
6778 if ((!isLocalTextureDataAvailable(mUpperBodyLayerSet)) &&
6779 (getTEImage(TEX_UPPER_BAKED)->getID() == IMG_DEFAULT_AVATAR))
6780 {
6781 loading = TRUE;
6782 }
6783 }
6784
6785
6786 // we wait a little bit before giving the all clear,
6787 // to let textures settle down
6788 const F32 PAUSE = 1.f;
6789 if (loading)
6790 mFullyLoadedTimer.reset();
6791
6792 mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE);
6793
6794
6795 // did our loading state "change" from last call?
6796 const S32 UPDATE_RATE = 30;
6797 BOOL changed =
6798 ((mFullyLoaded != mPreviousFullyLoaded) || // if the value is different from the previous call
6799 (!mFullyLoadedInitialized) || // if we've never been called before
6800 (mFullyLoadedFrameCounter % UPDATE_RATE == 0)); // every now and then issue a change
6801
6802 mPreviousFullyLoaded = mFullyLoaded;
6803 mFullyLoadedInitialized = TRUE;
6804 mFullyLoadedFrameCounter++;
6805
6806 return changed;
6807}
6808
6809
6810BOOL LLVOAvatar::isFullyLoaded()
6811{
6812 if (gSavedSettings.getBOOL("RenderUnloadedAvatar"))
6813 return TRUE;
6814 else
6815 return mFullyLoaded;
6816}
6817
6818
6640//----------------------------------------------------------------------------- 6819//-----------------------------------------------------------------------------
6641// findMotion() 6820// findMotion()
6642//----------------------------------------------------------------------------- 6821//-----------------------------------------------------------------------------
@@ -8289,12 +8468,12 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
8289} 8468}
8290 8469
8291// static 8470// static
8292void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels ) 8471void LLVOAvatar::getAnimLabels( LLDynamicArray<std::string>* labels )
8293{ 8472{
8294 S32 i; 8473 S32 i;
8295 for( i = 0; i < gUserAnimStatesCount; i++ ) 8474 for( i = 0; i < gUserAnimStatesCount; i++ )
8296 { 8475 {
8297 labels->put( gUserAnimStates[i].mLabel ); 8476 labels->put( LLAnimStateLabels::getStateLabel( gUserAnimStates[i].mName ) );
8298 } 8477 }
8299 8478
8300 // Special case to trigger away (AFK) state 8479 // Special case to trigger away (AFK) state
@@ -8302,13 +8481,13 @@ void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels )
8302} 8481}
8303 8482
8304// static 8483// static
8305void LLVOAvatar::getAnimNames( LLDynamicArray<const char*>* names ) 8484void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )
8306{ 8485{
8307 S32 i; 8486 S32 i;
8308 8487
8309 for( i = 0; i < gUserAnimStatesCount; i++ ) 8488 for( i = 0; i < gUserAnimStatesCount; i++ )
8310 { 8489 {
8311 names->put( gUserAnimStates[i].mName ); 8490 names->put( std::string(gUserAnimStates[i].mName) );
8312 } 8491 }
8313 8492
8314 // Special case to trigger away (AFK) state 8493 // Special case to trigger away (AFK) state
@@ -9507,7 +9686,7 @@ BOOL LLVOAvatar::updateLOD()
9507 if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) 9686 if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
9508 { //LOD changed or new mesh created, allocate new vertex buffer if needed 9687 { //LOD changed or new mesh created, allocate new vertex buffer if needed
9509 updateMeshData(); 9688 updateMeshData();
9510 mDirtyMesh = FALSE; 9689 mDirtyMesh = FALSE;
9511 mNeedsSkin = TRUE; 9690 mNeedsSkin = TRUE;
9512 mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); 9691 mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
9513 } 9692 }