diff options
Diffstat (limited to 'linden/indra/newview/llvoavatar.cpp')
-rw-r--r-- | linden/indra/newview/llvoavatar.cpp | 375 |
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 | ||
131 | extern LLSky gSky; | ||
132 | extern void set_avatar_character(void* charNameArg); | ||
133 | extern BOOL gRenderForSelect; | ||
134 | 127 | ||
135 | LLXmlTree LLVOAvatar::sXMLTree; | 128 | LLXmlTree LLVOAvatar::sXMLTree; |
136 | LLXmlTree LLVOAvatar::sSkeletonXMLTree; | 129 | LLXmlTree 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. | ||
6738 | BOOL 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 | |||
6810 | BOOL 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 |
8292 | void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels ) | 8471 | void 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 |
8305 | void LLVOAvatar::getAnimNames( LLDynamicArray<const char*>* names ) | 8484 | void 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 | } |