llvoavatar.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include <algorithm>
00035 #include <vector>
00036 #include "llstl.h"
00037 
00038 #include "llvoavatar.h"
00039 
00040 #include "audioengine.h"
00041 #include "imageids.h"
00042 #include "indra_constants.h"
00043 #include "llchat.h"
00044 #include "llfontgl.h"
00045 #include "llprimitive.h"
00046 #include "lltextureentry.h"
00047 #include "message.h"
00048 #include "noise.h"
00049 #include "sound_ids.h"
00050 #include "lltimer.h"
00051 #include "timing.h"
00052 
00053 #include "llagent.h"                    //  Get state values from here
00054 #include "llviewercontrol.h"
00055 #include "llcriticaldamp.h"
00056 #include "lldir.h"
00057 #include "lldrawable.h"
00058 #include "lldrawpoolavatar.h"
00059 #include "lldrawpoolalpha.h"
00060 #include "lldrawpoolbump.h"
00061 #include "lldriverparam.h"
00062 #include "lleditingmotion.h"
00063 #include "llemote.h"
00064 #include "llface.h"
00065 #include "llfasttimer.h"
00066 #include "llfirstuse.h"
00067 #include "llfloatercustomize.h"
00068 #include "llfloatertools.h"
00069 #include "llgldbg.h"
00070 #include "llhandmotion.h"
00071 #include "llheadrotmotion.h"
00072 #include "llhudeffectbeam.h"
00073 #include "llhudeffectlookat.h"
00074 #include "llhudeffecttrail.h"
00075 #include "llhudmanager.h"
00076 #include "llhudtext.h"
00077 #include "llinventorymodel.h"
00078 #include "llinventoryview.h"
00079 #include "llkeyframefallmotion.h"
00080 #include "llkeyframemotion.h"
00081 #include "llkeyframemotionparam.h"
00082 #include "llkeyframestandmotion.h"
00083 #include "llkeyframewalkmotion.h"
00084 #include "llmenugl.h"
00085 #include "llmutelist.h"
00086 #include "llnetmap.h"
00087 #include "llnotify.h"
00088 #include "llquantize.h"
00089 #include "llregionhandle.h"
00090 #include "llresmgr.h"
00091 #include "llselectmgr.h"
00092 #include "llsky.h"
00093 #include "llsprite.h"
00094 #include "llstatusbar.h"
00095 #include "lltargetingmotion.h"
00096 #include "lltexlayer.h"
00097 #include "lltoolbar.h"
00098 #include "lltoolgrab.h"         // for needsRenderBeam
00099 #include "lltoolmgr.h"          // for needsRenderBeam
00100 #include "lltoolmorph.h"
00101 #include "lltrustnet.h"
00102 #include "llviewercamera.h"
00103 #include "llviewerimagelist.h"
00104 #include "llviewerinventory.h"
00105 #include "llviewermenu.h"
00106 #include "llviewerobjectlist.h"
00107 #include "llviewerparcelmgr.h"
00108 #include "llviewerregion.h"
00109 #include "llviewerstats.h"
00110 #include "llviewerwindow.h"
00111 #include "llvosky.h"
00112 #include "llvovolume.h"
00113 #include "llwearable.h"
00114 #include "llwearablelist.h"
00115 #include "llworld.h"
00116 #include "pipeline.h"
00117 #include "llglslshader.h"
00118 #include "viewer.h"
00119 #include "lscript_byteformat.h"
00120 
00121 //#include "vtune/vtuneapi.h"
00122 
00123 //Ventrella
00124 #include "llgesturemgr.h" //needed to trigger the voice gestculations
00125 #include "llvoicevisualizer.h" 
00126 #include "llvoiceclient.h"
00127 //end Ventrella
00128 
00129 // Direct imports, evil
00130 extern LLSky gSky;
00131 extern void set_avatar_character(void* charNameArg);
00132 extern BOOL gRenderForSelect;
00133 
00134 LLXmlTree LLVOAvatar::sXMLTree;
00135 LLXmlTree LLVOAvatar::sSkeletonXMLTree;
00136 LLVOAvatarSkeletonInfo* LLVOAvatar::sSkeletonInfo = NULL;
00137 LLVOAvatarInfo*                 LLVOAvatar::sAvatarInfo = NULL;
00138 
00139 BOOL gDebugAvatarRotation = FALSE;
00140 
00141 //extern BOOL gVelocityInterpolate;
00142 
00143 //-----------------------------------------------------------------------------
00144 // Constants
00145 //-----------------------------------------------------------------------------
00146 const F32 MIN_PIXEL_AREA_FOR_COMPOSITE = 200.f;
00147 
00148 F32 SHADOW_OFFSET_AMT = 0.03f;
00149 
00150 #define DELTA_TIME_MIN                  0.01f   // we clamp measured deltaTime to this
00151 #define DELTA_TIME_MAX                  0.2f    // range to insure stability of computations.
00152 
00153 const F32 PELVIS_LAG_FLYING             = 0.22f;// pelvis follow half life while flying
00154 
00155 const F32 PELVIS_LAG_WALKING    = 0.4f; // ...while walking
00156 
00157 const F32 PELVIS_LAG_MOUSELOOK = 0.15f;
00158 const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f;
00159 
00160 const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this!
00161 
00162 #define PELVIS_ROT_THRESHOLD_SLOW       60.0f   // amount of deviation allowed between
00163 #define PELVIS_ROT_THRESHOLD_FAST       2.0f    // the pelvis and the view direction
00164                                                                                         // when moving fast & slow
00165 
00166 const F32 MIN_SPEED_PELVIS_FOLLOW = 0.1f;
00167 
00168 #define TORSO_NOISE_AMOUNT              1.f     // Amount of deviation from up-axis, in degrees
00169 #define TORSO_NOISE_SPEED               0.2f    // Time scale factor on torso noise.
00170 
00171 const F32 BREATHE_ROT_MOTION_STRENGTH = 0.05f;
00172 
00173 const F32 BREATHE_SCALE_MOTION_STRENGTH = 0.005f;
00174 
00175 #define PELVIS_NOISE_FACTOR             0.5f    // amount of random noise
00176 
00177 #define AUDIO_STEP_PRI                  0xC0000000
00178 #define AUDIO_STEP_LO_SPEED             0.01f   // as average speed goes from lo to hi,
00179 #define AUDIO_STEP_HI_SPEED             3.0f    // from lo to hi
00180 #define AUDIO_STEP_LO_GAIN              0.15f   // the resulting gain will ramp linearly
00181 #define AUDIO_STEP_HI_GAIN              0.15f
00182 
00183 const F32 DAMPED_MOTION_TIME_SCALE = 0.15f;
00184 
00185 const F32 LOOKAT_CAMERA_DIST_SQUARED = 25.f;
00186 
00187 #define AVATAR_HEADER           "Linden Avatar 1.0"
00188 #define AVATAR_SECTION          "[avatar]"
00189 
00190 #define AVATAR_DEFAULT_CHAR     "avatar"
00191 
00192 const F32 MIN_SHADOW_HEIGHT = 0.f;
00193 const F32 MAX_SHADOW_HEIGHT = 0.3f;
00194 
00195 #define MIN_REQUIRED_PIXEL_AREA_BODY_NOISE (10000.f)
00196 #define MIN_REQUIRED_PIXEL_AREA_BREATHE (10000.f)
00197 #define MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX (40.f)
00198 
00199 const S32 LOCTEX_IMAGE_SIZE_SELF = 512;
00200 const S32 LOCTEX_IMAGE_AREA_SELF = LOCTEX_IMAGE_SIZE_SELF * LOCTEX_IMAGE_SIZE_SELF;
00201 const S32 LOCTEX_IMAGE_SIZE_OTHER = LOCTEX_IMAGE_SIZE_SELF / 4;  // The size of local textures for other (!mIsSelf) avatars
00202 const S32 LOCTEX_IMAGE_AREA_OTHER = LOCTEX_IMAGE_SIZE_OTHER * LOCTEX_IMAGE_SIZE_OTHER;
00203 
00204 const F32 HEAD_MOVEMENT_AVG_TIME = 0.9f;
00205 
00206 const S32 MORPH_MASK_REQUESTED_DISCARD = 0;
00207 const S32 MIN_PIXEL_AREA_BUMP = 500;
00208 
00209 // Discard level at which to switch to baked textures
00210 // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB
00211 const S32 SWITCH_TO_BAKED_DISCARD = 5;
00212 
00213 const F32 FOOT_COLLIDE_FUDGE = 0.04f;
00214 
00215 const F32 HOVER_EFFECT_MAX_SPEED = 3.f;
00216 const F32 HOVER_EFFECT_STRENGTH = 0.f;
00217 F32 UNDERWATER_EFFECT_STRENGTH = 0.1f;
00218 const F32 UNDERWATER_FREQUENCY_DAMP = 0.33f;
00219 const F32 APPEARANCE_MORPH_TIME = 0.65f;
00220 const F32 CAMERA_SHAKE_ACCEL_THRESHOLD_SQUARED = 5.f * 5.f;
00221 const F32 TIME_BEFORE_MESH_CLEANUP = 5.f; // seconds
00222 const S32 AVATAR_RELEASE_THRESHOLD = 10; // number of avatar instances before releasing memory
00223 const F32 FOOT_GROUND_COLLISION_TOLERANCE = 0.25f;
00224 const F32 AVATAR_LOD_TWEAK_RANGE = 0.7f;
00225 const S32 MAX_LOD_CHANGES_PER_FRAME = 2;
00226 const S32 MAX_BUBBLE_CHAT_LENGTH = 1023;
00227 const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
00228 const F32 CHAT_FADE_TIME = 8.0;
00229 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
00230 const S32 MAX_BUBBLES = 7;
00231 
00232 S32 LLVOAvatar::sMaxVisible = 50;
00233 
00234 LLVOAvatar::ETextureIndex LLVOAvatar::sBakedTextureIndices[BAKED_TEXTURE_COUNT] = 
00235 {
00236         LLVOAvatar::TEX_HEAD_BAKED,
00237         LLVOAvatar::TEX_UPPER_BAKED,
00238         LLVOAvatar::TEX_LOWER_BAKED,
00239         LLVOAvatar::TEX_EYES_BAKED,
00240         LLVOAvatar::TEX_SKIRT_BAKED
00241 };
00242 
00243 //-----------------------------------------------------------------------------
00244 // Utility functions
00245 //-----------------------------------------------------------------------------
00246 
00247 static F32 calc_bouncy_animation(F32 x)
00248 {
00249         return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f;
00250 }
00251 
00252 //-----------------------------------------------------------------------------
00253 // Static Data
00254 //-----------------------------------------------------------------------------
00255 S32 LLVOAvatar::sMaxOtherAvatarsToComposite = 1;  // Only this many avatars (other than yourself) can be composited at a time.  Set in initClass().
00256 LLMap< LLGLenum, LLGLuint*> LLVOAvatar::sScratchTexNames;
00257 LLMap< LLGLenum, F32*> LLVOAvatar::sScratchTexLastBindTime;
00258 S32 LLVOAvatar::sScratchTexBytes = 0;
00259 S32     LLVOAvatar::sNumVisibleAvatars = 0;
00260 S32     LLVOAvatar::sNumLODChangesThisFrame = 0;
00261 
00262 LLUUID LLVOAvatar::sStepSoundOnLand = LLUUID("e8af4a28-aa83-4310-a7c4-c047e15ea0df");
00263 LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] =
00264 {
00265         LLUUID(SND_STONE_RUBBER),
00266         LLUUID(SND_METAL_RUBBER),
00267         LLUUID(SND_GLASS_RUBBER),
00268         LLUUID(SND_WOOD_RUBBER),
00269         LLUUID(SND_FLESH_RUBBER),
00270         LLUUID(SND_RUBBER_PLASTIC),
00271         LLUUID(SND_RUBBER_RUBBER)
00272 };
00273 
00274 S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS;
00275 BOOL LLVOAvatar::sRenderGroupTitles = TRUE;
00276 S32 LLVOAvatar::sNumVisibleChatBubbles = 0;
00277 BOOL LLVOAvatar::sDebugInvisible = FALSE;
00278 BOOL LLVOAvatar::sShowAttachmentPoints = FALSE;
00279 BOOL LLVOAvatar::sShowAnimationDebug = FALSE;
00280 BOOL LLVOAvatar::sShowFootPlane = FALSE;
00281 BOOL LLVOAvatar::sShowCollisionVolumes = FALSE;
00282 BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
00283 BOOL LLVOAvatar::sAvatarLoadTest = FALSE;
00284 F32 LLVOAvatar::sLODFactor = 1.f;
00285 BOOL LLVOAvatar::sJointDebug = FALSE;
00286 
00287 S32 LLVOAvatar::sCurJoint = 0;
00288 S32 LLVOAvatar::sCurVolume = 0;
00289 
00290 struct LLAvatarTexData
00291 {
00292         LLAvatarTexData( const LLUUID& id, LLVOAvatar::ELocTexIndex index )
00293                 : mAvatarID(id), mIndex(index) {}
00294         LLUUID                          mAvatarID;
00295         LLVOAvatar::ELocTexIndex        mIndex;
00296 };
00297 
00298 struct LLTextureMaskData
00299 {
00300         LLTextureMaskData( const LLUUID& id )
00301                 : mAvatarID(id), mLastDiscardLevel(S32_MAX) {}
00302         LLUUID                          mAvatarID;
00303         S32                                     mLastDiscardLevel;
00304 };
00305 
00306 
00307 //-----------------------------------------------------------------------------
00308 // class LLBodyNoiseMotion
00309 //-----------------------------------------------------------------------------
00310 class LLBodyNoiseMotion :
00311         public LLMotion
00312 {
00313 public:
00314         // Constructor
00315         LLBodyNoiseMotion(const LLUUID &id) : LLMotion(id) {mName = "body_noise";}
00316 
00317         // Destructor
00318         virtual ~LLBodyNoiseMotion() { }
00319 
00320 public:
00321         //-------------------------------------------------------------------------
00322         // functions to support MotionController and MotionRegistry
00323         //-------------------------------------------------------------------------
00324         // static constructor
00325         // all subclasses must implement such a function and register it
00326         static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); }
00327 
00328 public:
00329         //-------------------------------------------------------------------------
00330         // animation callbacks to be implemented by subclasses
00331         //-------------------------------------------------------------------------
00332 
00333         // motions must specify whether or not they loop
00334         virtual BOOL getLoop() { return TRUE; }
00335 
00336         // motions must report their total duration
00337         virtual F32 getDuration() { return 0.0; }
00338 
00339         // motions must report their "ease in" duration
00340         virtual F32 getEaseInDuration() { return 0.0; }
00341 
00342         // motions must report their "ease out" duration.
00343         virtual F32 getEaseOutDuration() { return 0.0; }
00344 
00345         // motions must report their priority
00346         virtual LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; }
00347 
00348         virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; }
00349 
00350         // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
00351         virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BODY_NOISE; }
00352 
00353         // run-time (post constructor) initialization,
00354         // called after parameters have been set
00355         // must return true to indicate success and be available for activation
00356         virtual LLMotionInitStatus onInitialize(LLCharacter *character)
00357         {
00358                 if( !mTorsoState.setJoint( character->getJoint("mTorso") ))
00359                 {
00360                         return STATUS_FAILURE;
00361                 }
00362 
00363                 mTorsoState.setUsage(LLJointState::ROT);
00364 
00365                 addJointState( &mTorsoState );
00366                 return STATUS_SUCCESS;
00367         }
00368 
00369         // called when a motion is activated
00370         // must return TRUE to indicate success, or else
00371         // it will be deactivated
00372         virtual BOOL onActivate() { return TRUE; }
00373 
00374         // called per time step
00375         // must return TRUE while it is active, and
00376         // must return FALSE when the motion is completed.
00377         virtual BOOL onUpdate(F32 time, U8* joint_mask)
00378         {
00379                 F32 nx[2];
00380                 nx[0]=time*TORSO_NOISE_SPEED;
00381                 nx[1]=0.0f;
00382                 F32 ny[2];
00383                 ny[0]=0.0f;
00384                 ny[1]=time*TORSO_NOISE_SPEED;
00385                 F32 noiseX = noise2(nx);
00386                 F32 noiseY = noise2(ny);
00387 
00388                 F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f;
00389                 F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f;
00390                 LLQuaternion tQn;
00391                 tQn.setQuat( rx, ry, 0.0f );
00392                 mTorsoState.setRotation( tQn );
00393 
00394                 return TRUE;
00395         }
00396 
00397         // called when a motion is deactivated
00398         virtual void onDeactivate() {}
00399 
00400 public:
00401         //-------------------------------------------------------------------------
00402         // joint states to be animated
00403         //-------------------------------------------------------------------------
00404         LLJointState            mTorsoState;
00405 };
00406 
00407 //-----------------------------------------------------------------------------
00408 // class LLBreatheMotionRot
00409 //-----------------------------------------------------------------------------
00410 class LLBreatheMotionRot :
00411         public LLMotion
00412 {
00413 public:
00414         // Constructor
00415         LLBreatheMotionRot(const LLUUID &id) :
00416                 LLMotion(id),
00417                 mBreatheRate(1.f),
00418                 mCharacter(NULL)
00419         {
00420                 mName = "breathe_rot";
00421         }
00422 
00423         // Destructor
00424         virtual ~LLBreatheMotionRot() { }
00425 
00426 public:
00427         //-------------------------------------------------------------------------
00428         // functions to support MotionController and MotionRegistry
00429         //-------------------------------------------------------------------------
00430         // static constructor
00431         // all subclasses must implement such a function and register it
00432         static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); }
00433 
00434 public:
00435         //-------------------------------------------------------------------------
00436         // animation callbacks to be implemented by subclasses
00437         //-------------------------------------------------------------------------
00438 
00439         // motions must specify whether or not they loop
00440         virtual BOOL getLoop() { return TRUE; }
00441 
00442         // motions must report their total duration
00443         virtual F32 getDuration() { return 0.0; }
00444 
00445         // motions must report their "ease in" duration
00446         virtual F32 getEaseInDuration() { return 0.0; }
00447 
00448         // motions must report their "ease out" duration.
00449         virtual F32 getEaseOutDuration() { return 0.0; }
00450 
00451         // motions must report their priority
00452         virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; }
00453 
00454         virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
00455 
00456         // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
00457         virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; }
00458 
00459         // run-time (post constructor) initialization,
00460         // called after parameters have been set
00461         // must return true to indicate success and be available for activation
00462         virtual LLMotionInitStatus onInitialize(LLCharacter *character)
00463         {               
00464                 mCharacter = character;
00465                 bool success = true;
00466 
00467                 if ( !mChestState.setJoint( character->getJoint( "mChest" ) ) ) { success = false; }
00468 
00469                 if ( success )
00470                 {
00471                         mChestState.setUsage(LLJointState::ROT);
00472                         addJointState( &mChestState );
00473                 }
00474 
00475                 if ( success )
00476                 {
00477                         return STATUS_SUCCESS;
00478                 }
00479                 else
00480                 {
00481                         return STATUS_FAILURE;
00482                 }
00483         }
00484 
00485         // called when a motion is activated
00486         // must return TRUE to indicate success, or else
00487         // it will be deactivated
00488         virtual BOOL onActivate() { return TRUE; }
00489 
00490         // called per time step
00491         // must return TRUE while it is active, and
00492         // must return FALSE when the motion is completed.
00493         virtual BOOL onUpdate(F32 time, U8* joint_mask)
00494         {
00495                 mBreatheRate = 1.f;
00496 
00497                 F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH);
00498 
00499                 mChestState.setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f)));
00500 
00501                 return TRUE;
00502         }
00503 
00504         // called when a motion is deactivated
00505         virtual void onDeactivate() {}
00506 
00507 public:
00508         //-------------------------------------------------------------------------
00509         // joint states to be animated
00510         //-------------------------------------------------------------------------
00511         LLJointState            mChestState;    
00512         F32                                     mBreatheRate;
00513         LLCharacter*            mCharacter;
00514 };
00515 
00516 //-----------------------------------------------------------------------------
00517 // class LLPelvisFixMotion
00518 //-----------------------------------------------------------------------------
00519 class LLPelvisFixMotion :
00520         public LLMotion
00521 {
00522 public:
00523         // Constructor
00524         LLPelvisFixMotion(const LLUUID &id) : LLMotion(id), mCharacter(NULL) {mName = "pelvis_fix";}
00525 
00526         // Destructor
00527         virtual ~LLPelvisFixMotion() { }
00528 
00529 public:
00530         //-------------------------------------------------------------------------
00531         // functions to support MotionController and MotionRegistry
00532         //-------------------------------------------------------------------------
00533         // static constructor
00534         // all subclasses must implement such a function and register it
00535         static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); }
00536 
00537 public:
00538         //-------------------------------------------------------------------------
00539         // animation callbacks to be implemented by subclasses
00540         //-------------------------------------------------------------------------
00541 
00542         // motions must specify whether or not they loop
00543         virtual BOOL getLoop() { return TRUE; }
00544 
00545         // motions must report their total duration
00546         virtual F32 getDuration() { return 0.0; }
00547 
00548         // motions must report their "ease in" duration
00549         virtual F32 getEaseInDuration() { return 0.5f; }
00550 
00551         // motions must report their "ease out" duration.
00552         virtual F32 getEaseOutDuration() { return 0.5f; }
00553 
00554         // motions must report their priority
00555         virtual LLJoint::JointPriority getPriority() { return LLJoint::LOW_PRIORITY; }
00556 
00557         virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
00558 
00559         // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
00560         virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX; }
00561 
00562         // run-time (post constructor) initialization,
00563         // called after parameters have been set
00564         // must return true to indicate success and be available for activation
00565         virtual LLMotionInitStatus onInitialize(LLCharacter *character)
00566         {
00567                 mCharacter = character;
00568 
00569                 if (!mPelvisState.setJoint( character->getJoint("mPelvis")))
00570                 {
00571                         return STATUS_FAILURE;
00572                 }
00573 
00574                 mPelvisState.setUsage(LLJointState::POS);
00575 
00576                 addJointState( &mPelvisState );
00577                 return STATUS_SUCCESS;
00578         }
00579 
00580         // called when a motion is activated
00581         // must return TRUE to indicate success, or else
00582         // it will be deactivated
00583         virtual BOOL onActivate() { return TRUE; }
00584 
00585         // called per time step
00586         // must return TRUE while it is active, and
00587         // must return FALSE when the motion is completed.
00588         virtual BOOL onUpdate(F32 time, U8* joint_mask)
00589         {
00590                 mPelvisState.setPosition(LLVector3::zero);
00591 
00592                 return TRUE;
00593         }
00594 
00595         // called when a motion is deactivated
00596         virtual void onDeactivate() {}
00597 
00598 public:
00599         //-------------------------------------------------------------------------
00600         // joint states to be animated
00601         //-------------------------------------------------------------------------
00602         LLJointState            mPelvisState;
00603         LLCharacter*            mCharacter;
00604 };
00605 
00606 //-----------------------------------------------------------------------------
00607 // LLVOAvatar()
00608 //-----------------------------------------------------------------------------
00609 LLVOAvatar::LLVOAvatar(
00610         const LLUUID& id,
00611         const LLPCode pcode,
00612         LLViewerRegion* regionp)
00613         :
00614         LLViewerObject(id, pcode, regionp),
00615         mHUDTargetZoom(1.f),
00616         mHUDCurZoom(1.f),
00617         mLastHeadBakedID( IMG_DEFAULT_AVATAR ),
00618         mLastUpperBodyBakedID( IMG_DEFAULT_AVATAR ),
00619         mLastLowerBodyBakedID( IMG_DEFAULT_AVATAR ),
00620         mLastEyesBakedID( IMG_DEFAULT_AVATAR ),
00621         mLastSkirtBakedID( IMG_DEFAULT_AVATAR ),
00622         mIsDummy(FALSE),
00623         mSpecialRenderMode(0),
00624         mTurning(FALSE),
00625         mPelvisToFoot(0.f),
00626         mLastSkeletonSerialNum( 0 ),
00627         mHeadOffset(),
00628         mIsSitting(FALSE),
00629         mTimeVisible(),
00630         mTyping(FALSE),
00631         mMeshValid(FALSE),
00632         mVisible(FALSE),
00633         mWindFreq(0.f),
00634         mRipplePhase( 0.f ),
00635         mBelowWater(FALSE),
00636         mAppearanceAnimSetByUser(FALSE),
00637         mLastAppearanceBlendTime(0.f),
00638         mAppearanceAnimating(FALSE),
00639         mHeadLayerSet( NULL ),
00640         mUpperBodyLayerSet( NULL ),
00641         mLowerBodyLayerSet( NULL ),
00642         mEyesLayerSet( NULL ),
00643         mSkirtLayerSet( NULL ),
00644         mRenderPriority(1.0f),
00645         mNameString(),
00646         mTitle(),
00647         mNameAway(FALSE),
00648         mNameBusy(FALSE),
00649         mNameMute(FALSE),
00650         mNameAppearance(FALSE),
00651         mLastRegionHandle(0),
00652         mRegionCrossingCount(0),
00653         mFirstTEMessageReceived( FALSE ),
00654         mFirstAppearanceMessageReceived( FALSE ),
00655         mHeadBakedLoaded(FALSE),
00656         mHeadMaskDiscard(-1),
00657         mUpperBakedLoaded(FALSE),
00658         mUpperMaskDiscard(-1),
00659         mLowerBakedLoaded(FALSE),
00660         mLowerMaskDiscard(-1),
00661         mEyesBakedLoaded(FALSE),
00662         mSkirtBakedLoaded(FALSE),
00663         mHeadMaskTexName(0),
00664         mUpperMaskTexName(0),
00665         mLowerMaskTexName(0),
00666         mCulled( FALSE ),
00667         mTexSkinColor( NULL ),
00668         mTexHairColor( NULL ),
00669         mTexEyeColor( NULL )
00670 {
00671         LLMemType mt(LLMemType::MTYPE_AVATAR);
00672         
00673         //VTResume();  // VTune
00674         
00675         // mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
00676         bool needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
00677         mVoiceVisualizer = ( LLVoiceVisualizer *)gHUDManager->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
00678 
00679         lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
00680 
00681         mPelvisp = NULL;
00682 
00683         for( S32 i=0; i<LOCTEX_NUM_ENTRIES; i++ )
00684         {
00685                 mLocalTextureBaked[i] = FALSE;
00686                 mLocalTextureDiscard[i] = MAX_DISCARD_LEVEL+1;
00687         }
00688 
00689         mDirtyMesh = TRUE;      // Dirty geometry, need to regenerate.
00690         mShadow0Facep = NULL;
00691         mShadow1Facep = NULL;
00692         mHeadp = NULL;
00693 
00694         mIsBuilt = FALSE;
00695 
00696         mNumJoints = 0;
00697         mSkeleton = NULL;
00698         mScreenp = NULL;
00699 
00700         mNumCollisionVolumes = 0;
00701         mCollisionVolumes = NULL;
00702 
00703         // set up animation variables
00704         mSpeed = 0.f;
00705         setAnimationData("Speed", &mSpeed);
00706 
00707         strcpy(mAvatarDefinition, AVATAR_DEFAULT_CHAR);         /* Flawfinder: ignore */
00708 
00709         if (id == gAgentID)
00710         {
00711                 mIsSelf = TRUE;
00712                 gAgent.setAvatarObject(this);
00713                 lldebugs << "Marking avatar as self " << id << llendl;
00714         }
00715         else
00716         {
00717                 mIsSelf = FALSE;
00718         }
00719 
00720         setNumTEs(TEX_NUM_ENTRIES);
00721 
00722         mbCanSelect = TRUE;
00723 
00724         mSignaledAnimations.clear();
00725         mPlayingAnimations.clear();
00726 
00727         mWasOnGroundLeft = FALSE;
00728         mWasOnGroundRight = FALSE;
00729 
00730         mTimeLast = 0.0f;
00731         mSpeedAccum = 0.0f;
00732 
00733         mRippleTimeLast = 0.f;
00734 
00735         mShadowImageID = LLUUID( gViewerArt.getString("foot_shadow.tga"));
00736         mShadowImagep = gImageList.getImage(mShadowImageID);
00737         mShadowImagep->bind();
00738         mShadowImagep->setClamp(TRUE, TRUE);
00739         
00740         mInAir = FALSE;
00741 
00742         mStepOnLand = TRUE;
00743         mStepMaterial = 0;
00744 
00745         //-------------------------------------------------------------------------
00746         // initialize joint, mesh and shape members
00747         //-------------------------------------------------------------------------
00748         mRoot.setName( "mRoot" );
00749 
00750         // skinned mesh objects
00751         mHairLOD.setName("mHairLOD");
00752         mHairMesh0.setName("mHairMesh0");
00753         mHairMesh0.setMeshID(MESH_ID_HAIR);
00754         mHairMesh1.setName("mHairMesh1");
00755         mHairMesh2.setName("mHairMesh2");
00756         mHairMesh3.setName("mHairMesh3");
00757         mHairMesh4.setName("mHairMesh4");
00758         mHairMesh5.setName("mHairMesh5");
00759         
00760         mHairMesh0.setIsTransparent(TRUE);
00761         mHairMesh1.setIsTransparent(TRUE);
00762         mHairMesh2.setIsTransparent(TRUE);
00763         mHairMesh3.setIsTransparent(TRUE);
00764         mHairMesh4.setIsTransparent(TRUE);
00765         mHairMesh5.setIsTransparent(TRUE);
00766 
00767         mHeadLOD.setName("mHeadLOD");
00768         mHeadMesh0.setName("mHeadMesh0");
00769         mHeadMesh0.setMeshID(MESH_ID_HEAD);
00770         mHeadMesh1.setName("mHeadMesh1");
00771         mHeadMesh2.setName("mHeadMesh2");
00772         mHeadMesh3.setName("mHeadMesh3");
00773         mHeadMesh4.setName("mHeadMesh4");
00774         
00775         mEyeLashLOD.setName("mEyeLashLOD");
00776         mEyeLashMesh0.setName("mEyeLashMesh0");
00777         mEyeLashMesh0.setMeshID(MESH_ID_HEAD);
00778         mEyeLashMesh0.setIsTransparent(TRUE);
00779 
00780         mUpperBodyLOD.setName("mUpperBodyLOD");
00781         mUpperBodyMesh0.setName("mUpperBodyMesh0");
00782         mUpperBodyMesh0.setMeshID(MESH_ID_UPPER_BODY);
00783         mUpperBodyMesh1.setName("mUpperBodyMesh1");
00784         mUpperBodyMesh2.setName("mUpperBodyMesh2");
00785         mUpperBodyMesh3.setName("mUpperBodyMesh3");
00786         mUpperBodyMesh4.setName("mUpperBodyMesh4");
00787 
00788         mLowerBodyLOD.setName("mLowerBodyLOD");
00789         mLowerBodyMesh0.setName("mLowerBodyMesh0");
00790         mLowerBodyMesh0.setMeshID(MESH_ID_LOWER_BODY);
00791         mLowerBodyMesh1.setName("mLowerBodyMesh1");
00792         mLowerBodyMesh2.setName("mLowerBodyMesh2");
00793         mLowerBodyMesh3.setName("mLowerBodyMesh3");
00794         mLowerBodyMesh4.setName("mLowerBodyMesh4");
00795 
00796         mEyeBallLeftLOD.setName("mEyeBallLeftLOD");
00797         mEyeBallLeftMesh0.setName("mEyeBallLeftMesh0");
00798         mEyeBallLeftMesh1.setName("mEyeBallLeftMesh1");
00799 
00800         mEyeBallRightLOD.setName("mEyeBallRightLOD");
00801         mEyeBallRightMesh0.setName("mEyeBallRightMesh0");
00802         mEyeBallRightMesh1.setName("mEyeBallRightMesh1");
00803 
00804         mSkirtLOD.setName("mSkirtLOD");
00805         mSkirtMesh0.setName("mSkirtMesh0");
00806         mSkirtMesh0.setMeshID(MESH_ID_SKIRT);
00807         mSkirtMesh1.setName("mSkirtMesh1");
00808         mSkirtMesh2.setName("mSkirtMesh2");
00809         mSkirtMesh3.setName("mSkirtMesh3");
00810         mSkirtMesh4.setName("mSkirtMesh4");
00811 
00812         mSkirtMesh0.setIsTransparent(TRUE);
00813         mSkirtMesh1.setIsTransparent(TRUE);
00814         mSkirtMesh2.setIsTransparent(TRUE);
00815         mSkirtMesh3.setIsTransparent(TRUE);
00816         mSkirtMesh4.setIsTransparent(TRUE);
00817 
00818         // set the pick names for the avatar
00819         mHeadMesh0.setPickName( LLViewerJoint::PN_0 );
00820         mHeadMesh1.setPickName( LLViewerJoint::PN_0 );
00821         mHeadMesh2.setPickName( LLViewerJoint::PN_0 );
00822         mHeadMesh3.setPickName( LLViewerJoint::PN_0 );
00823         mHeadMesh4.setPickName( LLViewerJoint::PN_0 );
00824         mEyeLashMesh0.setPickName( LLViewerJoint::PN_0 );
00825 
00826         mUpperBodyMesh0.setPickName( LLViewerJoint::PN_1 );
00827         mUpperBodyMesh1.setPickName( LLViewerJoint::PN_1 );
00828         mUpperBodyMesh2.setPickName( LLViewerJoint::PN_1 );
00829         mUpperBodyMesh3.setPickName( LLViewerJoint::PN_1 );
00830         mUpperBodyMesh4.setPickName( LLViewerJoint::PN_1 );
00831 
00832         mLowerBodyMesh0.setPickName( LLViewerJoint::PN_2 );
00833         mLowerBodyMesh1.setPickName( LLViewerJoint::PN_2 );
00834         mLowerBodyMesh2.setPickName( LLViewerJoint::PN_2 );
00835         mLowerBodyMesh3.setPickName( LLViewerJoint::PN_2 );
00836         mLowerBodyMesh4.setPickName( LLViewerJoint::PN_2 );
00837 
00838         mEyeBallLeftMesh0.setPickName( LLViewerJoint::PN_3 );
00839         mEyeBallLeftMesh1.setPickName( LLViewerJoint::PN_3 );
00840         mEyeBallRightMesh0.setPickName( LLViewerJoint::PN_3 );
00841         mEyeBallRightMesh1.setPickName( LLViewerJoint::PN_3 );
00842 
00843         mHairMesh0.setPickName( LLViewerJoint::PN_4);
00844         mHairMesh1.setPickName( LLViewerJoint::PN_4);
00845         mHairMesh2.setPickName( LLViewerJoint::PN_4);
00846         mHairMesh3.setPickName( LLViewerJoint::PN_4);
00847         mHairMesh4.setPickName( LLViewerJoint::PN_4);
00848         mHairMesh5.setPickName( LLViewerJoint::PN_4);
00849 
00850         mSkirtMesh0.setPickName( LLViewerJoint::PN_5 );
00851         mSkirtMesh1.setPickName( LLViewerJoint::PN_5 );
00852         mSkirtMesh2.setPickName( LLViewerJoint::PN_5 );
00853         mSkirtMesh3.setPickName( LLViewerJoint::PN_5 );
00854         mSkirtMesh4.setPickName( LLViewerJoint::PN_5 );
00855 
00856         // material settings
00857 
00858         mEyeBallLeftMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
00859         mEyeBallLeftMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
00860         mEyeBallRightMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
00861         mEyeBallRightMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
00862 
00863         //-------------------------------------------------------------------------
00864         // register motions
00865         //-------------------------------------------------------------------------
00866         if (LLCharacter::sInstances.size() == 1)
00867         {
00868                 LLKeyframeMotion::setVFS(gStaticVFS);
00869                 addMotion( ANIM_AGENT_BUSY,                                             LLNullMotion::create );
00870                 addMotion( ANIM_AGENT_CROUCH,                                   LLKeyframeStandMotion::create );
00871                 addMotion( ANIM_AGENT_CROUCHWALK,                               LLKeyframeWalkMotion::create );
00872                 addMotion( ANIM_AGENT_EXPRESS_AFRAID,                   LLEmote::create );
00873                 addMotion( ANIM_AGENT_EXPRESS_ANGER,                    LLEmote::create );
00874                 addMotion( ANIM_AGENT_EXPRESS_BORED,                    LLEmote::create );
00875                 addMotion( ANIM_AGENT_EXPRESS_CRY,                              LLEmote::create );
00876                 addMotion( ANIM_AGENT_EXPRESS_DISDAIN,                  LLEmote::create );
00877                 addMotion( ANIM_AGENT_EXPRESS_EMBARRASSED,              LLEmote::create );
00878                 addMotion( ANIM_AGENT_EXPRESS_FROWN,                    LLEmote::create );
00879                 addMotion( ANIM_AGENT_EXPRESS_KISS,                             LLEmote::create );
00880                 addMotion( ANIM_AGENT_EXPRESS_LAUGH,                    LLEmote::create );
00881                 addMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH,               LLEmote::create );
00882                 addMotion( ANIM_AGENT_EXPRESS_REPULSED,                 LLEmote::create );
00883                 addMotion( ANIM_AGENT_EXPRESS_SAD,                              LLEmote::create );
00884                 addMotion( ANIM_AGENT_EXPRESS_SHRUG,                    LLEmote::create );
00885                 addMotion( ANIM_AGENT_EXPRESS_SMILE,                    LLEmote::create );
00886                 addMotion( ANIM_AGENT_EXPRESS_SURPRISE,                 LLEmote::create );
00887                 addMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT,               LLEmote::create );
00888                 addMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE,               LLEmote::create );
00889                 addMotion( ANIM_AGENT_EXPRESS_WINK,                             LLEmote::create );
00890                 addMotion( ANIM_AGENT_EXPRESS_WORRY,                    LLEmote::create );
00891                 addMotion( ANIM_AGENT_RUN,                                              LLKeyframeWalkMotion::create );
00892                 addMotion( ANIM_AGENT_STAND,                                    LLKeyframeStandMotion::create );
00893                 addMotion( ANIM_AGENT_STAND_1,                                  LLKeyframeStandMotion::create );
00894                 addMotion( ANIM_AGENT_STAND_2,                                  LLKeyframeStandMotion::create );
00895                 addMotion( ANIM_AGENT_STAND_3,                                  LLKeyframeStandMotion::create );
00896                 addMotion( ANIM_AGENT_STAND_4,                                  LLKeyframeStandMotion::create );
00897                 addMotion( ANIM_AGENT_STANDUP,                                  LLKeyframeFallMotion::create );
00898                 addMotion( ANIM_AGENT_TURNLEFT,                                 LLKeyframeWalkMotion::create );
00899                 addMotion( ANIM_AGENT_TURNRIGHT,                                LLKeyframeWalkMotion::create );
00900                 addMotion( ANIM_AGENT_WALK,                                             LLKeyframeWalkMotion::create );
00901         
00902                 // motions without a start/stop bit
00903                 addMotion( ANIM_AGENT_BODY_NOISE,                               LLBodyNoiseMotion::create );
00904                 addMotion( ANIM_AGENT_BREATHE_ROT,                              LLBreatheMotionRot::create );
00905                 addMotion( ANIM_AGENT_EDITING,                                  LLEditingMotion::create );
00906                 addMotion( ANIM_AGENT_EYE,                                              LLEyeMotion::create     );
00907                 addMotion( ANIM_AGENT_FEMALE_WALK,                              LLKeyframeWalkMotion::create );
00908                 addMotion( ANIM_AGENT_FLY_ADJUST,                               LLFlyAdjustMotion::create );
00909                 addMotion( ANIM_AGENT_HAND_MOTION,                              LLHandMotion::create );
00910                 addMotion( ANIM_AGENT_HEAD_ROT,                                 LLHeadRotMotion::create );
00911                 addMotion( ANIM_AGENT_PELVIS_FIX,                               LLPelvisFixMotion::create );
00912                 addMotion( ANIM_AGENT_SIT_FEMALE,                               LLKeyframeMotion::create );
00913                 addMotion( ANIM_AGENT_TARGET,                                   LLTargetingMotion::create );
00914                 addMotion( ANIM_AGENT_WALK_ADJUST,                              LLWalkAdjustMotion::create );
00915         }
00916 
00917         if (gNoRender)
00918         {
00919                 return;
00920         }
00921         buildCharacter();
00922 
00923         // preload specific motions here
00924         createMotion( ANIM_AGENT_CUSTOMIZE);
00925         createMotion( ANIM_AGENT_CUSTOMIZE_DONE);
00926 
00927         //VTPause();  // VTune
00928         
00929         //Ventrella
00930         mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) );
00931         mCurrentGesticulationLevel = 0;         
00932         //END Ventrella
00933 }
00934 
00935 //------------------------------------------------------------------------
00936 // LLVOAvatar::~LLVOAvatar()
00937 //------------------------------------------------------------------------
00938 LLVOAvatar::~LLVOAvatar()
00939 {
00940         lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
00941 
00942         if (mIsSelf)
00943         {
00944                 gAgent.setAvatarObject(NULL);
00945         }
00946 
00947         mRoot.removeAllChildren();
00948 
00949         delete [] mSkeleton;
00950         mSkeleton = NULL;
00951 
00952         delete mScreenp;
00953         mScreenp = NULL;
00954         
00955         delete [] mCollisionVolumes;
00956         mCollisionVolumes = NULL;
00957 
00958 
00959         mNumJoints = 0;
00960 
00961         delete mHeadLayerSet;
00962         mHeadLayerSet = NULL;
00963 
00964         delete mUpperBodyLayerSet;
00965         mUpperBodyLayerSet = NULL;
00966 
00967         delete mLowerBodyLayerSet;
00968         mLowerBodyLayerSet = NULL;
00969 
00970         delete mEyesLayerSet;
00971         mEyesLayerSet = NULL;
00972 
00973         delete mSkirtLayerSet;
00974         mSkirtLayerSet = NULL;
00975 
00976         mAttachmentPoints.deleteAllData();
00977 
00978         delete mTexSkinColor;
00979         mTexSkinColor = NULL;
00980         delete mTexHairColor;
00981         mTexHairColor = NULL;
00982         delete mTexEyeColor;
00983         mTexEyeColor = NULL;
00984 
00985         std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());
00986         
00987         mDead = TRUE;
00988         
00989         // Clean up class data
00990         LLVOAvatar::cullAvatarsByPixelArea();
00991 
00992         mAnimationSources.clear();
00993 
00994         lldebugs << "LLVOAvatar Destructor end" << llendl;
00995 }
00996 
00997 void LLVOAvatar::markDead()
00998 {
00999         if (mNameText)
01000         {
01001                 mNameText->markDead();
01002                 mNameText = NULL;
01003                 sNumVisibleChatBubbles--;
01004         }
01005 
01006         mVoiceVisualizer->markDead();
01007 
01008         mBeam = NULL;
01009         LLViewerObject::markDead();
01010 }
01011 
01012 
01013 BOOL LLVOAvatar::isFullyBaked()
01014 {
01015         if (mIsDummy) return TRUE;
01016         if (getNumTEs() == 0) return FALSE;
01017         
01018         BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR );
01019         BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
01020         BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
01021         BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR );
01022         BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );
01023 
01024         if (isWearingWearableType(WT_SKIRT))
01025         {
01026                 return head_baked && upper_baked && lower_baked && eyes_baked && skirt_baked;
01027         }
01028         else
01029         {
01030                 return head_baked && upper_baked && lower_baked && eyes_baked;
01031         }
01032 }
01033 
01034 void LLVOAvatar::deleteLayerSetCaches()
01035 {
01036         if( mHeadLayerSet )                     mHeadLayerSet->deleteCaches();
01037         if( mUpperBodyLayerSet )        mUpperBodyLayerSet->deleteCaches();
01038         if( mLowerBodyLayerSet )        mLowerBodyLayerSet->deleteCaches();
01039         if( mEyesLayerSet )                     mEyesLayerSet->deleteCaches();
01040         if( mSkirtLayerSet )            mSkirtLayerSet->deleteCaches();
01041 }
01042 
01043 // static 
01044 BOOL LLVOAvatar::areAllNearbyInstancesBaked()
01045 {
01046         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
01047                 iter != LLCharacter::sInstances.end(); ++iter)
01048         {
01049                 LLVOAvatar* inst = (LLVOAvatar*) *iter;
01050                 if( inst->isDead() )
01051                 {
01052                         continue;
01053                 }
01054                 else
01055                 if( inst->getPixelArea() < MIN_PIXEL_AREA_FOR_COMPOSITE )
01056                 {
01057                         return TRUE;  // Assumes sInstances is sorted by pixel area.
01058                 }
01059                 else
01060                 if( !inst->isFullyBaked() )
01061                 {
01062                         return FALSE;
01063                 }
01064         }
01065         return TRUE;
01066 }
01067 
01068 // static 
01069 void LLVOAvatar::dumpScratchTextureByteCount()
01070 {
01071         llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;
01072 }
01073 
01074 // static
01075 void LLVOAvatar::dumpBakedStatus()
01076 {
01077         LLVector3d camera_pos_global = gAgent.getCameraPositionGlobal();
01078 
01079         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
01080                 iter != LLCharacter::sInstances.end(); ++iter)
01081         {
01082                 LLVOAvatar* inst = (LLVOAvatar*) *iter;
01083                 llinfos << "Avatar ";
01084 
01085                 LLNameValue* firstname = inst->getNVPair("FirstName");
01086                 LLNameValue* lastname = inst->getNVPair("LastName");
01087 
01088                 if( firstname )
01089                 {
01090                         llcont << firstname->getString();
01091                 }
01092                 if( lastname )
01093                 {
01094                         llcont << " " << lastname->getString();
01095                 }
01096 
01097                 llcont << " " << inst->mID;
01098 
01099                 if( inst->isDead() )
01100                 {
01101                         llcont << " DEAD ("<< inst->getNumRefs() << " refs)";
01102                 }
01103 
01104                 if( inst->mIsSelf )
01105                 {
01106                         llcont << " (self)";
01107                 }
01108 
01109 
01110                 F64 dist_to_camera = (inst->getPositionGlobal() - camera_pos_global).magVec();
01111                 llcont << " " << dist_to_camera << "m ";
01112 
01113                 llcont << " " << inst->mPixelArea << " pixels";
01114 
01115                 if( inst->isVisible() )
01116                 {
01117                         llcont << " (visible)";
01118                 }
01119                 else
01120                 {
01121                         llcont << " (not visible)";
01122                 }
01123 
01124                 if( inst->isFullyBaked() )
01125                 {
01126                         llcont << " Baked";
01127                 }
01128                 else
01129                 {
01130                         llcont << " Unbaked (";
01131                         if( inst->getTEImage( TEX_HEAD_BAKED )->getID()  == IMG_DEFAULT_AVATAR )
01132                         {
01133                                 llcont << " head";
01134                         }
01135 
01136                         if( inst->getTEImage( TEX_UPPER_BAKED )->getID() == IMG_DEFAULT_AVATAR )
01137                         {
01138                                 llcont << " upper";
01139                         }
01140 
01141                         if( inst->getTEImage( TEX_LOWER_BAKED )->getID() == IMG_DEFAULT_AVATAR )
01142                         {
01143                                 llcont << " lower";
01144                         }
01145 
01146                         if( inst->getTEImage( TEX_EYES_BAKED )->getID()  == IMG_DEFAULT_AVATAR )
01147                         {
01148                                 llcont << " eyes";
01149                         }
01150 
01151                         if (inst->isWearingWearableType(WT_SKIRT))
01152                         {
01153                                 if( inst->getTEImage( TEX_SKIRT_BAKED )->getID()  == IMG_DEFAULT_AVATAR )
01154                                 {
01155                                         llcont << " skirt";
01156                                 }
01157                         }
01158 
01159                         llcont << " ) " << inst->getUnbakedPixelAreaRank() << "/" << LLVOAvatar::sMaxOtherAvatarsToComposite;
01160                         if( inst->isCulled() )
01161                         {
01162                                 llcont << " culled";
01163                         }
01164                 }
01165                 llcont << llendl;
01166 /*
01167                 if( inst->isDead() )
01168                 {
01169                         llinfos << "DEAD LIST " << llendl;
01170 
01171                         
01172                         for( S32 i = 0; i < inst->mOwners.count(); i++ )
01173                         {
01174                                 llinfos << i << llendl;
01175                                 LLPointer<LLViewerObject>* owner = (LLPointer<LLViewerObject>*)(inst->mOwners[i]);
01176                                 LLPointer<LLViewerObject>* cur;
01177                                 if( !owner->mName.isEmpty() )
01178                                 {
01179                                         llinfos << "    " << owner->mName << llendl;
01180                                 }
01181 
01182                                 LLViewerObject* key_vo;
01183                                 for( key_vo = gObjectList.mActiveObjects.getFirstKey(); key_vo; key_vo = gObjectList.mActiveObjects.getNextKey() )
01184                                 {
01185                                         cur = &(gObjectList.mActiveObjects.getCurrentDataWithoutIncrement());
01186                                         if( cur == owner )
01187                                         {
01188                                                 llinfos << "    gObjectList.mActiveObjects" << llendl;
01189                                         }
01190                                 }
01191 
01192                                 for( key_vo = gObjectList.mAvatarObjects.getFirstKey(); key_vo; key_vo = gObjectList.mAvatarObjects.getNextKey() )
01193                                 {
01194                                         cur = &(gObjectList.mAvatarObjects.getCurrentDataWithoutIncrement());   
01195                                         if( cur == owner )
01196                                         {
01197                                                 llinfos << "    gObjectList.mAvatarObjects" << llendl;
01198                                         }
01199                                 }
01200 
01201                                 LLUUID id;
01202                                 for( id = gObjectList.mDeadObjects.getFirstKey(); id; id = gObjectList.mDeadObjects.getNextKey() )
01203                                 {
01204                                         cur = &(gObjectList.mDeadObjects.getCurrentDataWithoutIncrement());
01205                                         if( cur == owner )
01206                                         {
01207                                                 llinfos << "    gObjectList.mDeadObjects" << llendl;
01208                                         }
01209                                 }
01210 
01211 
01212                                 for( id = gObjectList.mUUIDObjectMap.getFirstKey(); id; id = gObjectList.mUUIDObjectMap.getNextKey() )
01213                                 {
01214                                         cur = &(gObjectList.mUUIDObjectMap.getCurrentDataWithoutIncrement());
01215                                         if( cur == owner )
01216                                         {
01217                                                 llinfos << "    gObjectList.mUUIDObjectMap" << llendl;
01218                                         }
01219                                 }
01220 
01221                                 S32 j;
01222                                 S32 k;
01223                                 for( j = 0; j < 16; j++ )
01224                                 {
01225                                         for( k = 0; k < 10; k++ )
01226                                         {
01227                                                 cur = &(gObjectList.mCloseObjects[j][k]);
01228                                                 if( cur == owner )
01229                                                 {
01230                                                         llinfos << "    gObjectList.mCloseObjects" << llendl;
01231                                                 }
01232                                         }
01233                                 }
01234 
01235                                 for( j = 0; j < gObjectList.mObjects.count(); j++ )
01236                                 {
01237                                         cur = &(gObjectList.mObjects[j]);
01238                                         if( cur == owner )
01239                                         {
01240                                                 llinfos << "    gObjectList.mObjects" << llendl;
01241                                         }
01242                                 }
01243 
01244                                 for( j = 0; j < gObjectList.mMapObjects.count(); j++ )
01245                                 {
01246                                         cur = &(gObjectList.mMapObjects[j]);
01247                                         if( cur == owner )
01248                                         {
01249                                                 llinfos << "    gObjectList.mMapObjects" << llendl;
01250                                         }
01251                                 }
01252                         }
01253                 }
01254                 */
01255         }
01256 }
01257 
01258 //static
01259 void LLVOAvatar::cleanupVertexPrograms()
01260 {
01261 }
01262 
01263 //static
01264 void LLVOAvatar::initVertexPrograms()
01265 {
01266 }
01267 
01268 //static
01269 void LLVOAvatar::restoreGL()
01270 {
01271         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
01272                 iter != LLCharacter::sInstances.end(); ++iter)
01273         {
01274                 LLVOAvatar* inst = (LLVOAvatar*) *iter;
01275                 inst->setCompositeUpdatesEnabled( TRUE );
01276                 inst->invalidateComposite( inst->mHeadLayerSet,         FALSE );
01277                 inst->invalidateComposite( inst->mLowerBodyLayerSet,    FALSE );
01278                 inst->invalidateComposite( inst->mUpperBodyLayerSet,    FALSE );
01279                 inst->invalidateComposite( inst->mEyesLayerSet, FALSE );
01280                 inst->invalidateComposite( inst->mSkirtLayerSet,        FALSE );
01281                 inst->updateMeshTextures();
01282         }
01283 }
01284 
01285 //static
01286 void LLVOAvatar::destroyGL()
01287 {
01288         deleteCachedImages();
01289         cleanupVertexPrograms();
01290 }
01291 
01292 // static
01293 void LLVOAvatar::deleteCachedImages()
01294 {
01295         if (LLTexLayerSet::sHasCaches)
01296         {
01297                 lldebugs << "Deleting layer set caches" << llendl;
01298                 for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
01299                 iter != LLCharacter::sInstances.end(); ++iter)
01300                 {
01301                         LLVOAvatar* inst = (LLVOAvatar*) *iter;
01302                         inst->deleteLayerSetCaches();
01303                 }
01304                 LLTexLayerSet::sHasCaches = FALSE;
01305         }
01306         
01307         for( GLuint* namep = (GLuint*)sScratchTexNames.getFirstData(); 
01308                  namep; 
01309                  namep = (GLuint*)sScratchTexNames.getNextData() )
01310         {
01311                 glDeleteTextures(1, namep );
01312                 stop_glerror();
01313         }
01314 
01315         if( sScratchTexBytes )
01316         {
01317                 lldebugs << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << llendl;
01318 
01319                 sScratchTexNames.deleteAllData();
01320                 LLVOAvatar::sScratchTexLastBindTime.deleteAllData();
01321                 LLImageGL::sGlobalTextureMemory -= sScratchTexBytes;
01322                 sScratchTexBytes = 0;
01323         }
01324 
01325         gTexStaticImageList.deleteCachedImages();
01326 }
01327 
01328 
01329 //------------------------------------------------------------------------
01330 // static
01331 // LLVOAvatar::initClass()
01332 //------------------------------------------------------------------------
01333 void LLVOAvatar::initClass()
01334 { 
01335         LLVOAvatar::sMaxOtherAvatarsToComposite = gSavedSettings.getS32("AvatarCompositeLimit");
01336 
01337         char xmlFile[MAX_PATH];         /* Flawfinder: ignore */
01338 
01339         snprintf(xmlFile, MAX_PATH, "%s_lad.xml", gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR).c_str());               /* Flawfinder: ignore */
01340         BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
01341         if (!success)
01342         {
01343                 llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
01344         }
01345 
01346         // now sanity check xml file
01347         LLXmlTreeNode* root = sXMLTree.getRoot();
01348         if (!root) 
01349         {
01350                 llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
01351                 return;
01352         }
01353 
01354         //-------------------------------------------------------------------------
01355         // <linden_avatar version="1.0"> (root)
01356         //-------------------------------------------------------------------------
01357         if( !root->hasName( "linden_avatar" ) )
01358         {
01359                 llerrs << "Invalid avatar file header: " << xmlFile << llendl;
01360         }
01361         
01362         LLString version;
01363         static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
01364         if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
01365         {
01366                 llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
01367         }
01368 
01369         S32 wearable_def_version = 1;
01370         static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
01371         root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
01372         LLWearable::setCurrentDefinitionVersion( wearable_def_version );
01373 
01374         LLString mesh_file_name;
01375 
01376         LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
01377         if (!skeleton_node)
01378         {
01379                 llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
01380                 return;
01381         }
01382         
01383         LLString skeleton_file_name;
01384         static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
01385         if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
01386         {
01387                 llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
01388         }
01389         
01390         std::string skeleton_path;
01391         skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
01392         if (!parseSkeletonFile(skeleton_path))
01393         {
01394                 llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
01395         }
01396 
01397         // Process XML data
01398 
01399         // avatar_skeleton.xml
01400         llassert(!sSkeletonInfo);
01401         sSkeletonInfo = new LLVOAvatarSkeletonInfo;
01402         if (!sSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
01403         {
01404                 llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
01405         }
01406         // parse avatar_lad.xml
01407         llassert(!sAvatarInfo);
01408         sAvatarInfo = new LLVOAvatarInfo;
01409         if (!sAvatarInfo->parseXmlSkeletonNode(root))
01410         {
01411                 llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
01412         }
01413         if (!sAvatarInfo->parseXmlMeshNodes(root))
01414         {
01415                 llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
01416         }
01417         if (!sAvatarInfo->parseXmlColorNodes(root))
01418         {
01419                 llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
01420         }
01421         if (!sAvatarInfo->parseXmlLayerNodes(root))
01422         {
01423                 llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
01424         }
01425         if (!sAvatarInfo->parseXmlDriverNodes(root))
01426         {
01427                 llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
01428         }
01429 }
01430 
01431 
01432 void LLVOAvatar::cleanupClass()
01433 {
01434         delete sAvatarInfo;
01435         sAvatarInfo = NULL;
01436         delete sSkeletonInfo;
01437         sSkeletonInfo = NULL;
01438         sSkeletonXMLTree.cleanup();
01439         sXMLTree.cleanup();
01440 }
01441 
01442 
01443 void LLVOAvatar::updateSpatialExtents(LLVector3& newMin, LLVector3 &newMax)
01444 {
01445         LLVector3 center = getRenderPosition();
01446         LLVector3 size = getScale();
01447         //maximum amount an animation can move avatar from drawable position
01448         LLVector3 animation_buffer(5, 5, 5);
01449 
01450         newMin.setVec((center-size)-animation_buffer);
01451         newMax.setVec(center+size+animation_buffer);
01452         mDrawable->setPositionGroup((newMin + newMax) * 0.5f);
01453 }
01454 
01455 
01456 //-----------------------------------------------------------------------------
01457 // parseSkeletonFile()
01458 //-----------------------------------------------------------------------------
01459 BOOL LLVOAvatar::parseSkeletonFile(const LLString& filename)
01460 {
01461         LLMemType mt(LLMemType::MTYPE_AVATAR);
01462         
01463         //-------------------------------------------------------------------------
01464         // parse the file
01465         //-------------------------------------------------------------------------
01466         BOOL success = sSkeletonXMLTree.parseFile( filename, FALSE );
01467 
01468         if (!success)
01469         {
01470                 llerrs << "Can't parse skeleton file: " << filename << llendl;
01471                 return FALSE;
01472         }
01473 
01474         // now sanity check xml file
01475         LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
01476         if (!root) 
01477         {
01478                 llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
01479         }
01480 
01481         if( !root->hasName( "linden_skeleton" ) )
01482         {
01483                 llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
01484         }
01485 
01486         LLString version;
01487         static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
01488         if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
01489         {
01490                 llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
01491         }
01492 
01493         return TRUE;
01494 }
01495 
01496 //-----------------------------------------------------------------------------
01497 // setupBone()
01498 //-----------------------------------------------------------------------------
01499 BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent)
01500 {
01501         LLMemType mt(LLMemType::MTYPE_AVATAR);
01502         
01503         LLViewerJoint* joint = NULL;
01504 
01505         if (info->mIsJoint)
01506         {
01507                 joint = (LLViewerJoint*)getCharacterJoint(sCurJoint);
01508                 if (!joint)
01509                 {
01510                         llwarns << "Too many bones" << llendl;
01511                         return FALSE;
01512                 }
01513                 joint->setName( info->mName );
01514         }
01515         else // collision volume
01516         {
01517                 if (sCurVolume >= (S32)mNumCollisionVolumes)
01518                 {
01519                         llwarns << "Too many bones" << llendl;
01520                         return FALSE;
01521                 }
01522                 joint = (LLViewerJoint*)(&mCollisionVolumes[sCurVolume]);
01523 
01524                 joint->setName( info->mName );
01525         }
01526 
01527         // add to parent
01528         if (parent)
01529         {
01530                 parent->addChild( joint );
01531         }
01532 
01533         joint->setPosition(info->mPos);
01534 
01535         joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
01536                                                          info->mRot.mV[VZ], LLQuaternion::XYZ));
01537 
01538         joint->setScale(info->mScale);
01539 
01540 
01541         if (info->mIsJoint)
01542         {
01543                 joint->setSkinOffset( info->mPivot );
01544                 sCurJoint++;
01545         }
01546         else // collision volume
01547         {
01548                 sCurVolume++;
01549         }
01550 
01551         // setup children
01552         LLVOAvatarBoneInfo::child_list_t::iterator iter;
01553         for (iter = info->mChildList.begin(); iter != info->mChildList.end(); iter++)
01554         {
01555                 LLVOAvatarBoneInfo *child_info = *iter;
01556                 if (!setupBone(child_info, joint))
01557                 {
01558                         return FALSE;
01559                 }
01560         }
01561 
01562         return TRUE;
01563 }
01564 
01565 //-----------------------------------------------------------------------------
01566 // buildSkeleton()
01567 //-----------------------------------------------------------------------------
01568 BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info)
01569 {
01570         LLMemType mt(LLMemType::MTYPE_AVATAR);
01571         
01572         //-------------------------------------------------------------------------
01573         // allocate joints
01574         //-------------------------------------------------------------------------
01575         if (!allocateCharacterJoints(info->mNumBones))
01576         {
01577                 llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
01578                 return FALSE;
01579         }
01580         
01581         //-------------------------------------------------------------------------
01582         // allocate volumes
01583         //-------------------------------------------------------------------------
01584         if (info->mNumCollisionVolumes)
01585         {
01586                 if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
01587                 {
01588                         llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
01589                         return FALSE;
01590                 }
01591         }
01592 
01593         sCurJoint = 0;
01594         sCurVolume = 0;
01595 
01596         LLVOAvatarSkeletonInfo::bone_info_list_t::iterator iter;
01597         for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); iter++)
01598         {
01599                 LLVOAvatarBoneInfo *info = *iter;
01600                 if (!setupBone(info, NULL))
01601                 {
01602                         llerrs << "Error parsing bone in skeleton file" << llendl;
01603                         return FALSE;
01604                 }
01605         }
01606 
01607         // add special-purpose "screen" joint
01608         if (mIsSelf)
01609         {
01610                 mScreenp = new LLViewerJoint("mScreen", NULL);
01611                 // for now, put screen at origin, as it is only used during special
01612                 // HUD rendering mode
01613                 F32 aspect = gCamera->getAspect();
01614                 LLVector3 scale(1.f, aspect, 1.f);
01615                 mScreenp->setScale(scale);
01616                 mScreenp->setWorldPosition(LLVector3::zero);
01617         }
01618 
01619         return TRUE;
01620 }
01621 
01622 //-----------------------------------------------------------------------------
01623 // LLVOAvatar::buildCharacter()
01624 // Deferred initialization and rebuild of the avatar.
01625 //-----------------------------------------------------------------------------
01626 extern BOOL gPrintMessagesThisFrame;
01627 void LLVOAvatar::buildCharacter()
01628 {
01629         LLMemType mt(LLMemType::MTYPE_AVATAR);
01630         
01631         //-------------------------------------------------------------------------
01632         // remove all references to our existing skeleton
01633         // so we can rebuild it
01634         //-------------------------------------------------------------------------
01635         flushAllMotions();
01636 
01637         //-------------------------------------------------------------------------
01638         // remove all of mRoot's children
01639         //-------------------------------------------------------------------------
01640         mRoot.removeAllChildren();
01641         mIsBuilt = FALSE;
01642 
01643         //-------------------------------------------------------------------------
01644         // clear mesh data
01645         //-------------------------------------------------------------------------
01646         mHairMesh0.setMesh(NULL);
01647         mHairMesh1.setMesh(NULL);
01648         mHairMesh2.setMesh(NULL);
01649         mHairMesh3.setMesh(NULL);
01650         mHairMesh4.setMesh(NULL);
01651         mHairMesh5.setMesh(NULL);
01652 
01653         mHeadMesh0.setMesh(NULL);
01654         mHeadMesh1.setMesh(NULL);
01655         mHeadMesh2.setMesh(NULL);
01656         mHeadMesh3.setMesh(NULL);
01657         mHeadMesh4.setMesh(NULL);
01658 
01659         mEyeLashMesh0.setMesh(NULL);
01660 
01661         mUpperBodyMesh0.setMesh(NULL);
01662         mUpperBodyMesh1.setMesh(NULL);
01663         mUpperBodyMesh2.setMesh(NULL);
01664         mUpperBodyMesh3.setMesh(NULL);
01665         mUpperBodyMesh4.setMesh(NULL);
01666 
01667         mLowerBodyMesh0.setMesh(NULL);
01668         mLowerBodyMesh1.setMesh(NULL);
01669         mLowerBodyMesh2.setMesh(NULL);
01670         mLowerBodyMesh3.setMesh(NULL);
01671         mLowerBodyMesh4.setMesh(NULL);
01672 
01673         mEyeBallLeftMesh0.setMesh(NULL);
01674         mEyeBallLeftMesh1.setMesh(NULL);
01675         mEyeBallRightMesh0.setMesh(NULL);
01676         mEyeBallRightMesh1.setMesh(NULL);
01677 
01678         mSkirtMesh0.setMesh(NULL);
01679         mSkirtMesh1.setMesh(NULL);
01680         mSkirtMesh2.setMesh(NULL);
01681         mSkirtMesh3.setMesh(NULL);
01682         mSkirtMesh4.setMesh(NULL);      
01683 
01684         //-------------------------------------------------------------------------
01685         // (re)load our skeleton and meshes
01686         //-------------------------------------------------------------------------
01687         LLTimer timer;
01688 
01689         BOOL status = loadAvatar();
01690         stop_glerror();
01691 
01692         if (gNoRender)
01693         {
01694                 // Still want to load the avatar skeleton so visual parameters work.
01695                 return;
01696         }
01697 
01698 //      gPrintMessagesThisFrame = TRUE;
01699         lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
01700 
01701         if ( ! status )
01702         {
01703                 if ( mIsSelf )
01704                 {
01705                         llerrs << "Unable to load user's avatar" << llendl;
01706                         //set_avatar_character( &LLString(AVATAR_DEFAULT_CHAR));
01707                 }
01708                 else
01709                 {
01710                         llwarns << "Unable to load other's avatar" << llendl;
01711                 }
01712                 return;
01713         }
01714 
01715         //-------------------------------------------------------------------------
01716         // initialize "well known" joint pointers
01717         //-------------------------------------------------------------------------
01718         mPelvisp                = (LLViewerJoint*)mRoot.findJoint("mPelvis");
01719         mTorsop                 = (LLViewerJoint*)mRoot.findJoint("mTorso");
01720         mChestp                 = (LLViewerJoint*)mRoot.findJoint("mChest");
01721         mNeckp                  = (LLViewerJoint*)mRoot.findJoint("mNeck");
01722         mHeadp                  = (LLViewerJoint*)mRoot.findJoint("mHead");
01723         mSkullp                 = (LLViewerJoint*)mRoot.findJoint("mSkull");
01724         mHipLeftp               = (LLViewerJoint*)mRoot.findJoint("mHipLeft");
01725         mHipRightp              = (LLViewerJoint*)mRoot.findJoint("mHipRight");
01726         mKneeLeftp              = (LLViewerJoint*)mRoot.findJoint("mKneeLeft");
01727         mKneeRightp             = (LLViewerJoint*)mRoot.findJoint("mKneeRight");
01728         mAnkleLeftp             = (LLViewerJoint*)mRoot.findJoint("mAnkleLeft");
01729         mAnkleRightp    = (LLViewerJoint*)mRoot.findJoint("mAnkleRight");
01730         mFootLeftp              = (LLViewerJoint*)mRoot.findJoint("mFootLeft");
01731         mFootRightp             = (LLViewerJoint*)mRoot.findJoint("mFootRight");
01732         mWristLeftp             = (LLViewerJoint*)mRoot.findJoint("mWristLeft");
01733         mWristRightp    = (LLViewerJoint*)mRoot.findJoint("mWristRight");
01734         mEyeLeftp               = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
01735         mEyeRightp              = (LLViewerJoint*)mRoot.findJoint("mEyeRight");
01736 
01737         //-------------------------------------------------------------------------
01738         // Make sure "well known" pointers exist
01739         //-------------------------------------------------------------------------
01740         if (!(mPelvisp && 
01741                 mTorsop &&
01742                 mChestp &&
01743                 mNeckp &&
01744                 mHeadp &&
01745                 mSkullp &&
01746                 mHipLeftp &&
01747                 mHipRightp &&
01748                 mKneeLeftp &&
01749                 mKneeRightp &&
01750                 mAnkleLeftp &&
01751                 mAnkleRightp &&
01752                 mFootLeftp &&
01753                 mFootRightp &&
01754                 mWristLeftp &&
01755                 mWristRightp &&
01756                 mEyeLeftp &&
01757                 mEyeRightp))
01758         {
01759                 llerrs << "Failed to create avatar." << llendl;
01760                 return;
01761         }
01762 
01763         //-------------------------------------------------------------------------
01764         // initialize the pelvis
01765         //-------------------------------------------------------------------------
01766         mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
01767         
01768         //-------------------------------------------------------------------------
01769         // set head offset from pelvis
01770         //-------------------------------------------------------------------------
01771         updateHeadOffset();
01772 
01773         //-------------------------------------------------------------------------
01774         // start default motions
01775         //-------------------------------------------------------------------------
01776         startMotion( ANIM_AGENT_HEAD_ROT );
01777         startMotion( ANIM_AGENT_EYE );
01778         startMotion( ANIM_AGENT_BODY_NOISE );
01779         startMotion( ANIM_AGENT_BREATHE_ROT );
01780         startMotion( ANIM_AGENT_HAND_MOTION );
01781         startMotion( ANIM_AGENT_PELVIS_FIX );
01782 
01783         //-------------------------------------------------------------------------
01784         // restart any currently active motions
01785         //-------------------------------------------------------------------------
01786         processAnimationStateChanges();
01787 
01788         mIsBuilt = TRUE;
01789         stop_glerror();
01790 
01791         //-------------------------------------------------------------------------
01792         // build the attach and detach menus
01793         //-------------------------------------------------------------------------
01794         if (mIsSelf)
01795         {
01796                 gAttachBodyPartPieMenus[0] = NULL;
01797                 gAttachBodyPartPieMenus[1] = new LLPieMenu("Right Arm >");
01798                 gAttachBodyPartPieMenus[2] = new LLPieMenu("Head >");
01799                 gAttachBodyPartPieMenus[3] = new LLPieMenu("Left Arm >");
01800                 gAttachBodyPartPieMenus[4] = NULL;
01801                 gAttachBodyPartPieMenus[5] = new LLPieMenu("Left Leg >");
01802                 gAttachBodyPartPieMenus[6] = new LLPieMenu("Torso >");
01803                 gAttachBodyPartPieMenus[7] = new LLPieMenu("Right Leg >");
01804 
01805                 gDetachBodyPartPieMenus[0] = NULL;
01806                 gDetachBodyPartPieMenus[1] = new LLPieMenu("Right Arm >");
01807                 gDetachBodyPartPieMenus[2] = new LLPieMenu("Head >");
01808                 gDetachBodyPartPieMenus[3] = new LLPieMenu("Left Arm >");
01809                 gDetachBodyPartPieMenus[4] = NULL;
01810                 gDetachBodyPartPieMenus[5] = new LLPieMenu("Left Leg >");
01811                 gDetachBodyPartPieMenus[6] = new LLPieMenu("Torso >");
01812                 gDetachBodyPartPieMenus[7] = new LLPieMenu("Right Leg >");
01813 
01814                 for (S32 i = 0; i < 8; i++)
01815                 {
01816                         if (gAttachBodyPartPieMenus[i])
01817                         {
01818                                 gAttachPieMenu->appendMenu( gAttachBodyPartPieMenus[i] );
01819                         }
01820                         else
01821                         {
01822                                 BOOL attachment_found = FALSE;
01823                                 for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); 
01824                                         attachment;
01825                                         attachment = mAttachmentPoints.getNextData())
01826                                 {
01827                                         if (attachment->getGroup() == i)
01828                                         {
01829                                                 LLMenuItemCallGL* item;
01830                                                 item = new LLMenuItemCallGL(attachment->getName(), 
01831                                                         NULL, 
01832                                                         object_selected_and_point_valid);
01833                                                 item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment));
01834                                                 
01835                                                 gAttachPieMenu->append(item);
01836 
01837                                                 attachment_found = TRUE;
01838                                                 break;
01839 
01840                                         }
01841                                 }
01842 
01843                                 if (!attachment_found)
01844                                 {
01845                                         gAttachPieMenu->appendSeparator();
01846                                 }
01847                         }
01848 
01849                         if (gDetachBodyPartPieMenus[i])
01850                         {
01851                                 gDetachPieMenu->appendMenu( gDetachBodyPartPieMenus[i] );
01852                         }
01853                         else
01854                         {
01855                                 BOOL attachment_found = FALSE;
01856                                 for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); 
01857                                         attachment;
01858                                         attachment = mAttachmentPoints.getNextData())
01859                                 {
01860                                         if (attachment->getGroup() == i)
01861                                         {
01862                                                 gDetachPieMenu->append(new LLMenuItemCallGL(attachment->getName(), 
01863                                                         &handle_detach_from_avatar, object_attached, attachment));
01864 
01865                                                 attachment_found = TRUE;
01866                                                 break;
01867                                         }
01868                                 }
01869 
01870                                 if (!attachment_found)
01871                                 {
01872                                         gDetachPieMenu->appendSeparator();
01873                                 }
01874                         }
01875                 }
01876 
01877                 // add screen attachments
01878                 for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); 
01879                         attachment;
01880                         attachment = mAttachmentPoints.getNextData())
01881                 {
01882                         if (attachment->getGroup() == 8)
01883                         {
01884                                 LLMenuItemCallGL* item;
01885                                 item = new LLMenuItemCallGL(attachment->getName(), 
01886                                         NULL, 
01887                                         object_selected_and_point_valid);
01888                                 item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment));
01889                                 gAttachScreenPieMenu->append(item);
01890                                 gDetachScreenPieMenu->append(new LLMenuItemCallGL(attachment->getName(), 
01891                                                         &handle_detach_from_avatar, object_attached, attachment));
01892                         }
01893                 }
01894 
01895                 for (S32 pass = 0; pass < 2; pass++)
01896                 {
01897                         for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); 
01898                                 attachment;
01899                                 attachment = mAttachmentPoints.getNextData())
01900                         {
01901                                 if (attachment->getIsHUDAttachment() != (pass == 1))
01902                                 {
01903                                         continue;
01904                                 }
01905                                 LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), 
01906                                         NULL, &object_selected_and_point_valid, &attach_label, attachment);
01907                                 item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment));
01908                                 gAttachSubMenu->append(item);
01909 
01910                                 gDetachSubMenu->append(new LLMenuItemCallGL(attachment->getName(), 
01911                                         &handle_detach_from_avatar, object_attached, &detach_label, attachment));
01912                                 
01913                         }
01914                         if (pass == 0)
01915                         {
01916                                 // put separator between non-hud and hud attachments
01917                                 gAttachSubMenu->appendSeparator();
01918                                 gDetachSubMenu->appendSeparator();
01919                         }
01920                 }
01921 
01922                 for (S32 group = 0; group < 8; group++)
01923                 {
01924                         // skip over groups that don't have sub menus
01925                         if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group])
01926                         {
01927                                 continue;
01928                         }
01929 
01930                         std::multimap<S32, LLViewerJointAttachment*> attachment_pie_menu_map;
01931 
01932                         // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number
01933                         for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); 
01934                                 attachment;
01935                                 attachment = mAttachmentPoints.getNextData())
01936                         {
01937                                 if(attachment->getGroup() == group)
01938                                 {
01939                                         // use multimap to provide a partial order off of the pie slice key
01940                                         attachment_pie_menu_map.insert(std::pair<S32, LLViewerJointAttachment*>(attachment->getPieSlice(), attachment));
01941                                 }
01942                         }
01943 
01944                         // add in requested order to pie menu, inserting separators as necessary
01945                         std::multimap<S32, LLViewerJointAttachment*>::iterator attach_it;
01946                         S32 cur_pie_slice = 0;
01947                         for (attach_it = attachment_pie_menu_map.begin(); attach_it != attachment_pie_menu_map.end(); ++attach_it)
01948                         {
01949                                 S32 requested_pie_slice = attach_it->first;
01950                                 while (cur_pie_slice < requested_pie_slice)
01951                                 {
01952                                         gAttachBodyPartPieMenus[group]->appendSeparator();
01953                                         gDetachBodyPartPieMenus[group]->appendSeparator();
01954                                         cur_pie_slice++;
01955                                 }
01956 
01957                                 LLViewerJointAttachment* attachment = attach_it->second;
01958 
01959                                 LLMenuItemCallGL* item = new LLMenuItemCallGL(attachment->getName(), 
01960                                         NULL, object_selected_and_point_valid);
01961                                 gAttachBodyPartPieMenus[group]->append(item);
01962                                 item->addListener(gMenuHolder->getListenerByName("Object.AttachToAvatar"), "on_click", mAttachmentPoints.reverseLookup(attachment));
01963                                 gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), 
01964                                         &handle_detach_from_avatar, object_attached, attachment));
01965 
01966                                 cur_pie_slice++;
01967                         }
01968                 }
01969         }
01970 
01971         mMeshValid = TRUE;
01972 }
01973 
01974 
01975 //-----------------------------------------------------------------------------
01976 // releaseMeshData()
01977 //-----------------------------------------------------------------------------
01978 void LLVOAvatar::releaseMeshData()
01979 {
01980         LLMemType mt(LLMemType::MTYPE_AVATAR);
01981         
01982         if (sInstances.size() < AVATAR_RELEASE_THRESHOLD || mIsDummy)
01983         {
01984                 return;
01985         }
01986 
01987         //llinfos << "Releasing" << llendl;
01988 
01989         // cleanup mesh data
01990         mHairLOD.setValid(FALSE, TRUE);
01991         mHeadLOD.setValid(FALSE, TRUE);
01992         mEyeLashLOD.setValid(FALSE, TRUE);
01993         mUpperBodyLOD.setValid(FALSE, TRUE);
01994         mLowerBodyLOD.setValid(FALSE, TRUE);
01995         mEyeBallLeftLOD.setValid(FALSE, TRUE);
01996         mEyeBallRightLOD.setValid(FALSE, TRUE);
01997         mSkirtLOD.setValid(FALSE, TRUE);
01998 
01999         //cleanup data
02000         if (mDrawable.notNull())
02001         {
02002                 LLFace* facep = mDrawable->getFace(0);
02003                 facep->setSize(0, 0);
02004         }
02005         
02006         for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData();
02007                 attachmentPoint;
02008                 attachmentPoint = mAttachmentPoints.getNextData())
02009         {
02010                 if (!attachmentPoint->getIsHUDAttachment())
02011                 {
02012                         attachmentPoint->setAttachmentVisibility(FALSE);
02013                 }
02014         }
02015         mMeshValid = FALSE;
02016 }
02017 
02018 //-----------------------------------------------------------------------------
02019 // restoreMeshData()
02020 //-----------------------------------------------------------------------------
02021 void LLVOAvatar::restoreMeshData()
02022 {
02023         LLMemType mt(LLMemType::MTYPE_AVATAR);
02024         
02025         //llinfos << "Restoring" << llendl;
02026         mMeshValid = TRUE;
02027         updateJointLODs();
02028 
02029         if (mIsSelf)
02030         {
02031                 updateAttachmentVisibility(gAgent.getCameraMode());
02032         }
02033         else
02034         {
02035                 for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData();
02036                         attachmentPoint;
02037                         attachmentPoint = mAttachmentPoints.getNextData())
02038                 {
02039                         if (!attachmentPoint->getIsHUDAttachment())
02040                         {
02041                                 attachmentPoint->setAttachmentVisibility(TRUE);
02042                         }
02043                 }
02044         }
02045 
02046         // force mesh update as LOD might not have changed to trigger this
02047         gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
02048 }
02049 
02050 //-----------------------------------------------------------------------------
02051 // updateMeshData()
02052 //-----------------------------------------------------------------------------
02053 void LLVOAvatar::updateMeshData()
02054 {
02055         if (mDrawable.notNull())
02056         {
02057                 LLFace* facep = mDrawable->getFace(0);
02058 
02059                 U32 num_vertices = 0;
02060                 U32 num_indices = 0;
02061 
02062                 // this order is determined by number of LODS
02063                 // if a mesh earlier in this list changed LODs while a later mesh doesn't,
02064                 // the later mesh's index offset will be inaccurate
02065                 mEyeBallLeftLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02066                 mEyeBallRightLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02067                 mEyeLashLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02068                 mHeadLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02069                 mLowerBodyLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02070                 mSkirtLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02071                 mUpperBodyLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02072                 mHairLOD.updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
02073 
02074                 // resize immediately
02075                 facep->setSize(num_vertices, num_indices);
02076 
02077                 facep->mVertexBuffer = new LLVertexBufferAvatar();
02078                 facep->mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE);
02079                 facep->setGeomIndex(0);
02080                 facep->setIndicesIndex(0);
02081                 
02082                 // This is a hack! Avatars have their own pool, so we are detecting
02083                 //   the case of more than one avatar in the pool (thus > 0 instead of >= 0)
02084                 if (facep->getGeomIndex() > 0)
02085                 {
02086                         llerrs << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << llendl;
02087                 }
02088 
02089                 mEyeBallLeftLOD.updateFaceData(facep, mAdjustedPixelArea);
02090                 mEyeBallRightLOD.updateFaceData(facep, mAdjustedPixelArea);
02091                 mEyeLashLOD.updateFaceData(facep, mAdjustedPixelArea);
02092                 mHeadLOD.updateFaceData(facep, mAdjustedPixelArea);
02093                 mLowerBodyLOD.updateFaceData(facep, mAdjustedPixelArea);
02094                 mSkirtLOD.updateFaceData(facep, mAdjustedPixelArea);
02095                 mUpperBodyLOD.updateFaceData(facep, mAdjustedPixelArea);
02096                 mHairLOD.updateFaceData(facep, mAdjustedPixelArea, TRUE);
02097         }
02098 }
02099 
02100 //------------------------------------------------------------------------
02101 
02102 //------------------------------------------------------------------------
02103 // The viewer can only suggest a good size for the agent,
02104 // the simulator will keep it inside a reasonable range.
02105 void LLVOAvatar::computeBodySize() 
02106 {
02107         LLVector3 pelvis_scale = mPelvisp->getScale();
02108 
02109         // some of the joints have not been cached
02110         LLVector3 skull = mSkullp->getPosition();
02111         LLVector3 skull_scale = mSkullp->getScale();
02112 
02113         LLVector3 neck = mNeckp->getPosition();
02114         LLVector3 neck_scale = mNeckp->getScale();
02115 
02116         LLVector3 chest = mChestp->getPosition();
02117         LLVector3 chest_scale = mChestp->getScale();
02118 
02119         // the rest of the joints have been cached
02120         LLVector3 head = mHeadp->getPosition();
02121         LLVector3 head_scale = mHeadp->getScale();
02122 
02123         LLVector3 torso = mTorsop->getPosition();
02124         LLVector3 torso_scale = mTorsop->getScale();
02125 
02126         LLVector3 hip = mHipLeftp->getPosition();
02127         LLVector3 hip_scale = mHipLeftp->getScale();
02128 
02129         LLVector3 knee = mKneeLeftp->getPosition();
02130         LLVector3 knee_scale = mKneeLeftp->getScale();
02131 
02132         LLVector3 ankle = mAnkleLeftp->getPosition();
02133         LLVector3 ankle_scale = mAnkleLeftp->getScale();
02134 
02135         LLVector3 foot  = mFootLeftp->getPosition();
02136 
02137         mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
02138                                         knee.mV[VZ] * hip_scale.mV[VZ] -
02139                                         ankle.mV[VZ] * knee_scale.mV[VZ] -
02140                                         foot.mV[VZ] * ankle_scale.mV[VZ];
02141 
02142         mBodySize.mV[VZ] = mPelvisToFoot +
02143                                            // the sqrt(2) correction below is an approximate
02144                                            // correction to get to the top of the head
02145                                            F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + 
02146                                            head.mV[VZ] * neck_scale.mV[VZ] + 
02147                                            neck.mV[VZ] * chest_scale.mV[VZ] + 
02148                                            chest.mV[VZ] * torso_scale.mV[VZ] + 
02149                                            torso.mV[VZ] * pelvis_scale.mV[VZ]; 
02150 
02151         // TODO -- measure the real depth and width
02152         mBodySize.mV[VX] = DEFAULT_AGENT_DEPTH;
02153         mBodySize.mV[VY] = DEFAULT_AGENT_WIDTH;
02154 
02155 /* debug spam
02156         std::cout << "skull = " << skull << std::endl;                          // adebug
02157         std::cout << "head = " << head << std::endl;                            // adebug
02158         std::cout << "head_scale = " << head_scale << std::endl;        // adebug
02159         std::cout << "neck = " << neck << std::endl;                            // adebug
02160         std::cout << "neck_scale = " << neck_scale << std::endl;        // adebug
02161         std::cout << "chest = " << chest << std::endl;                          // adebug
02162         std::cout << "chest_scale = " << chest_scale << std::endl;      // adebug
02163         std::cout << "torso = " << torso << std::endl;                          // adebug
02164         std::cout << "torso_scale = " << torso_scale << std::endl;      // adebug
02165         std::cout << std::endl; // adebug
02166 
02167         std::cout << "pelvis_scale = " << pelvis_scale << std::endl;// adebug
02168         std::cout << std::endl; // adebug
02169 
02170         std::cout << "hip = " << hip << std::endl;                                      // adebug
02171         std::cout << "hip_scale = " << hip_scale << std::endl;          // adebug
02172         std::cout << "ankle = " << ankle << std::endl;                          // adebug
02173         std::cout << "ankle_scale = " << ankle_scale << std::endl;      // adebug
02174         std::cout << "foot = " << foot << std::endl;                            // adebug
02175         std::cout << "mBodySize = " << mBodySize << std::endl;          // adebug
02176         std::cout << "mPelvisToFoot = " << mPelvisToFoot << std::endl;  // adebug
02177         std::cout << std::endl;         // adebug
02178 */
02179 }
02180 
02181 //------------------------------------------------------------------------
02182 // LLVOAvatar::processUpdateMessage()
02183 //------------------------------------------------------------------------
02184 U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
02185                                                                                   void **user_data,
02186                                                                                   U32 block_num, const EObjectUpdateType update_type,
02187                                                                                   LLDataPacker *dp)
02188 {
02189         LLMemType mt(LLMemType::MTYPE_AVATAR);
02190         
02191         LLVector3 old_vel = getVelocity();
02192         // Do base class updates...
02193         U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
02194 
02195         //llinfos << getRotation() << llendl;
02196         //llinfos << getPosition() << llendl;
02197         if (update_type == OUT_FULL )
02198         {
02199                 if( !mIsSelf || !mFirstTEMessageReceived )
02200                 {
02201 //                      dumpAvatarTEs( "PRE   processUpdateMessage()" );
02202                         unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
02203 //                      dumpAvatarTEs( "POST  processUpdateMessage()" );
02204 
02205                         if( !mFirstTEMessageReceived )
02206                         {
02207                                 onFirstTEMessageReceived();
02208                         }
02209 
02210                         // Disable updates to composites.  We'll decide whether we need to do
02211                         // any updates after we find out whether this update message has any
02212                         // "baked" (pre-composited) textures.
02213                         setCompositeUpdatesEnabled( FALSE );
02214                         updateMeshTextures(); 
02215                         setCompositeUpdatesEnabled( TRUE );
02216                 }
02217         }
02218 
02219         return retval;
02220 }
02221 
02222 // virtual
02223 S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
02224 {
02225         // The core setTETexture() method requests images, so we need
02226         // to redirect certain avatar texture requests to different sims.
02227         if (isTextureIndexBaked(te))
02228         {
02229                 LLHost target_host = getObjectHost();
02230                 return setTETextureCore(te, uuid, target_host);
02231         }
02232         else
02233         {
02234                 return setTETextureCore(te, uuid, LLHost::invalid);
02235         }
02236 }
02237 
02238 
02239 // setTEImage
02240 
02241 //------------------------------------------------------------------------
02242 // idleUpdate()
02243 //------------------------------------------------------------------------
02244 BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
02245 {
02246         LLMemType mt(LLMemType::MTYPE_AVATAR);
02247         LLFastTimer t(LLFastTimer::FTM_AVATAR_UPDATE);
02248         
02249         if (isDead())
02250         {
02251                 llinfos << "Warning!  Idle on dead avatar" << llendl;
02252                 return TRUE;
02253         }
02254 
02255         if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
02256         {
02257                 return TRUE;
02258         }
02259         
02260         // force immediate pixel area update on avatars using last frames data (before drawable or camera updates)
02261         setPixelAreaAndAngle(gAgent);
02262 
02263         // Update the LOD of the joints
02264         //static const F32 UPDATE_TIME = .5f;
02265         
02266         // force asynchronous drawable update
02267         if(mDrawable.notNull() && !gNoRender)
02268         {       
02269                 LLFastTimer t(LLFastTimer::FTM_JOINT_UPDATE);
02270         
02271                 if (mIsSitting && getParent())
02272                 {
02273                         LLViewerObject *root_object = (LLViewerObject*)getRoot();
02274                         LLDrawable* drawablep = root_object->mDrawable;
02275                         // if this object hasn't already been updated by another avatar...
02276                         if (drawablep) // && !drawablep->isState(LLDrawable::EARLY_MOVE))
02277                         {
02278                                 if (root_object->isSelected())
02279                                 {
02280                                         gPipeline.updateMoveNormalAsync(drawablep);
02281                                 }
02282                                 else
02283                                 {
02284                                         gPipeline.updateMoveDampedAsync(drawablep);
02285                                 }
02286                         }
02287                 }
02288                 else 
02289                 {
02290                         gPipeline.updateMoveDampedAsync(mDrawable);
02291                 }
02292         }
02293 
02294         //--------------------------------------------------------------------
02295         // set alpha flag depending on state
02296         //--------------------------------------------------------------------
02297 
02298         if (mIsSelf)
02299         {
02300                 LLViewerObject::idleUpdate(agent, world, time);
02301                 
02302                 // trigger fidget anims
02303                 if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS))
02304                 {
02305                         agent.fidget();
02306                 }
02307         }
02308         else
02309         {
02310                 // Should override the idleUpdate stuff and leave out the angular update part.
02311                 LLQuaternion rotation = getRotation();
02312                 LLViewerObject::idleUpdate(agent, world, time);
02313                 setRotation(rotation);
02314         }
02315 
02316         // attach objects that were waiting for a drawable
02317         lazyAttach();
02318         
02319         // animate the character
02320         // store off last frame's root position to be consistent with camera position
02321         LLVector3 root_pos_last = mRoot.getWorldPosition();
02322 
02323         updateCharacter(agent);
02324         
02325         //Ventrella
02326         bool voiceEnabled = gVoiceClient->getVoiceEnabled( mID ) && gVoiceClient->inProximalChannel();
02327         // disable voice visualizer when in mouselook
02328         mVoiceVisualizer->setVoiceEnabled( voiceEnabled && !(mIsSelf && gAgent.cameraMouselook()) );
02329         if ( voiceEnabled )
02330         {               
02331                 //----------------------------------------------------------------
02332                 // Only do gesture triggering for your own avatar, and only when you're in a proximal channel.
02333                 //----------------------------------------------------------------
02334                 if( mIsSelf )
02335                 {
02336                         //----------------------------------------------------------------------------------------
02337                         // The following takes the voice signal and uses that to trigger gesticulations. 
02338                         //----------------------------------------------------------------------------------------
02339                         int lastGesticulationLevel = mCurrentGesticulationLevel;
02340                         mCurrentGesticulationLevel = mVoiceVisualizer->getCurrentGesticulationLevel();
02341                         
02342                         //---------------------------------------------------------------------------------------------------
02343                         // If "current gesticulation level" changes, we catch this, and trigger the new gesture
02344                         //---------------------------------------------------------------------------------------------------
02345                         if ( lastGesticulationLevel != mCurrentGesticulationLevel )
02346                         {
02347                                 if ( mCurrentGesticulationLevel != VOICE_GESTICULATION_LEVEL_OFF )
02348                                 {
02349                                         LLString gestureString = "unInitialized";
02350                                                         if ( mCurrentGesticulationLevel == 0 )  { gestureString = "/voicelevel1";       }
02351                                         else    if ( mCurrentGesticulationLevel == 1 )  { gestureString = "/voicelevel2";       }
02352                                         else    if ( mCurrentGesticulationLevel == 2 )  { gestureString = "/voicelevel3";       }
02353                                         else    { printf( "oops - CurrentGesticulationLevel can be only 0, 1, or 2\n" ); }
02354                                         
02355                                         // this is the call that Karl S. created for triggering gestures from within the code.
02356                                         gGestureManager.triggerAndReviseString( gestureString );
02357                                 }
02358                         }
02359                         
02360                 } //if( mIsSelf )
02361 
02362                 //-----------------------------------------------------------------------------------------------------------------
02363                 // If the avatar is speaking, then the voice amplitude signal is passed to the voice visualizer.
02364                 // Also, here we trigger voice visualizer start and stop speaking, so it can animate the voice symbol.
02365                 //
02366                 // Notice the calls to "gAwayTimer.reset()". This resets the timer that determines how long the avatar has been
02367                 // "away", so that the avatar doesn't lapse into away-mode (and slump over) while the user is still talking. 
02368                 //-----------------------------------------------------------------------------------------------------------------
02369                 if ( gVoiceClient->getIsSpeaking( mID ) )
02370                 {
02371                         if ( ! mVoiceVisualizer->getCurrentlySpeaking() )
02372                         {
02373                                 mVoiceVisualizer->setStartSpeaking();
02374                                 
02375                                 //printf( "gAwayTimer.reset();\n" );
02376                         }
02377 
02378                         mVoiceVisualizer->setSpeakingAmplitude( gVoiceClient->getCurrentPower( mID ) );
02379 
02380                         if( mIsSelf )
02381                         {
02382                                 gAgent.clearAFK();
02383                         }
02384                 }
02385                 else
02386                 {
02387                         if ( mVoiceVisualizer->getCurrentlySpeaking() )
02388                         {
02389                                 mVoiceVisualizer->setStopSpeaking();
02390                         }
02391                 }
02392 
02393                 //--------------------------------------------------------------------------------------------
02394                 // here we get the approximate head position and set as sound source for the voice symbol
02395                 // (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
02396                 //--------------------------------------------------------------------------------------------
02397                 LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
02398                 mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
02399 
02400         }//if ( voiceEnabled )
02401         //End  Ventrella
02402         
02403                 
02404         if (LLVOAvatar::sJointDebug)
02405         {
02406                 llinfos << getFullname() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << llendl;
02407         }
02408 
02409         LLJoint::sNumUpdates = 0;
02410         LLJoint::sNumTouches = 0;
02411 
02412         if (gNoRender)
02413         {
02414                 return TRUE;
02415         }
02416 
02417         // *NOTE: this is necessary for the floating name text above your head.
02418         if (mDrawable.notNull())
02419         {
02420                 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE);
02421         }
02422 
02423         // update attachments positions
02424         {
02425                 LLFastTimer t(LLFastTimer::FTM_ATTACHMENT_UPDATE);
02426                 for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData();
02427                         attachment;
02428                         attachment = mAttachmentPoints.getNextData())
02429                 {
02430                         LLViewerObject *attached_object = attachment->getObject();
02431 
02432                         BOOL visibleAttachment = isVisible() || !(attached_object && attached_object->mDrawable->getSpatialBridge()
02433                                                                                   && (attached_object->mDrawable->getSpatialBridge()->getRadius() < 2.0));
02434 
02435                         if (visibleAttachment && attached_object && !attached_object->isDead() && attachment->getValid())
02436                         {
02437                                 // if selecting any attachments, update all of them as non-damped
02438                                 if (gSelectMgr->getSelection()->getObjectCount() && gSelectMgr->getSelection()->isAttachment())
02439                                 {
02440                                         gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
02441                                 }
02442                                 else
02443                                 {
02444                                         gPipeline.updateMoveDampedAsync(attached_object->mDrawable);
02445                                 }
02446                                 attached_object->updateText();
02447                         }
02448                 }
02449         }
02450         
02451         //force a move if sitting on an active object
02452         if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
02453         {
02454                 gPipeline.markMoved(mDrawable, TRUE);
02455         }
02456 
02457         // update morphing params
02458         if (mAppearanceAnimating)
02459         {
02460                 ESex avatar_sex = getSex();
02461                 F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32();
02462                 if (appearance_anim_time >= APPEARANCE_MORPH_TIME)
02463                 {
02464                         mAppearanceAnimating = FALSE;
02465                         for (LLVisualParam *param = getFirstVisualParam(); 
02466                                  param;
02467                                  param = getNextVisualParam())
02468                         {
02469                                 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
02470                                 {
02471                                         param->stopAnimating(mAppearanceAnimSetByUser);
02472                                 }
02473                         }
02474                         updateVisualParams();
02475                         if (mIsSelf)
02476                         {
02477                                 gAgent.sendAgentSetAppearance();
02478                         }
02479                 }
02480                 else
02481                 {
02482                         F32 blend_frac = calc_bouncy_animation(appearance_anim_time / APPEARANCE_MORPH_TIME);
02483                         F32 last_blend_frac = calc_bouncy_animation(mLastAppearanceBlendTime / APPEARANCE_MORPH_TIME);
02484                         F32 morph_amt;
02485                         if (last_blend_frac == 1.f)
02486                         {
02487                                 morph_amt = 1.f;
02488                         }
02489                         else
02490                         {
02491                                 morph_amt = (blend_frac - last_blend_frac) / (1.f - last_blend_frac);
02492                         }
02493 
02494                         LLVisualParam *param;
02495 
02496                         // animate only top level params
02497                         for (param = getFirstVisualParam();
02498                                  param;
02499                                  param = getNextVisualParam())
02500                         {
02501                                 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
02502                                 {
02503                                         param->animate(morph_amt, mAppearanceAnimSetByUser);
02504                                 }
02505                         }
02506 
02507                         // apply all params
02508                         for (param = getFirstVisualParam();
02509                                  param;
02510                                  param = getNextVisualParam())
02511                         {
02512                                 param->apply(avatar_sex);
02513                         }
02514 
02515                         mLastAppearanceBlendTime = appearance_anim_time;
02516                 }
02517                 dirtyMesh();
02518         }
02519 
02520         // update wind effect
02521         if ((LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH))
02522         {
02523                 F32 hover_strength = 0.f;
02524                 F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast;
02525                 mRippleTimeLast = mRippleTimer.getElapsedTimeF32();
02526                 LLVector3 velocity = getVelocity();
02527                 F32 speed = velocity.magVec();
02528                 //RN: velocity varies too much frame to frame for this to work
02529                 mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(0.02f));
02530                 mLastVel = velocity;
02531                 LLVector4 wind;
02532                 wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity);
02533 
02534                 if (mInAir)
02535                 {
02536                         hover_strength = HOVER_EFFECT_STRENGTH * llmax(0.f, HOVER_EFFECT_MAX_SPEED - speed);
02537                 }
02538 
02539                 if (mBelowWater)
02540                 {
02541                         // TODO: make cloth flow more gracefully when underwater
02542                         hover_strength += UNDERWATER_EFFECT_STRENGTH;
02543                 }
02544 
02545                 wind.mV[VZ] += hover_strength;
02546                 wind.normVec();
02547 
02548                 wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f);
02549                 F32 interp;
02550                 if (wind.mV[VW] > mWindVec.mV[VW])
02551                 {
02552                         interp = LLCriticalDamp::getInterpolant(0.2f);
02553                 }
02554                 else
02555                 {
02556                         interp = LLCriticalDamp::getInterpolant(0.4f);
02557                 }
02558                 mWindVec = lerp(mWindVec, wind, interp);
02559         
02560                 F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f);
02561                 mWindFreq = lerp(mWindFreq, wind_freq, interp); 
02562 
02563                 if (mBelowWater)
02564                 {
02565                         mWindFreq *= UNDERWATER_FREQUENCY_DAMP;
02566                 }
02567 
02568                 mRipplePhase += (time_delta * mWindFreq);
02569                 if (mRipplePhase > F_TWO_PI)
02570                 {
02571                         mRipplePhase = fmodf(mRipplePhase, F_TWO_PI);
02572                 }
02573         }
02574 
02575         // update chat bubble
02576         //--------------------------------------------------------------------
02577         // draw text label over characters head
02578         //--------------------------------------------------------------------
02579         if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME)
02580         {
02581                 mChats.clear();
02582         }
02583         
02584         const F32 time_visible = mTimeVisible.getElapsedTimeF32();
02585         const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime"); // seconds
02586         const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds
02587         BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping);
02588         BOOL render_name =      visible_chat ||
02589                                                 (isVisible() &&
02590                                                 ((sRenderName == RENDER_NAME_ALWAYS) ||
02591                                                 (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
02592         // If it's your own avatar, don't draw in mouselook, and don't
02593         // draw if we're specifically hiding our own name.
02594         if (mIsSelf)
02595         {
02596                 render_name = render_name
02597                                                 && !gAgent.cameraMouselook()
02598                                                 && (visible_chat || !gSavedSettings.getBOOL("RenderNameHideSelf"));
02599         }
02600 
02601         if ( render_name )
02602         {
02603                 BOOL new_name = FALSE;
02604                 if (visible_chat != mVisibleChat)
02605                 {
02606                         mVisibleChat = visible_chat;
02607                         new_name = TRUE;
02608                 }
02609 
02610                 // First Calculate Alpha
02611                 // If alpha > 0, create mNameText if necessary, otherwise delete it
02612                 {
02613                         F32 alpha = 0.f;
02614                         if (mAppAngle > 5.f)
02615                         {
02616                                 const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
02617                                 if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
02618                                 {
02619                                         alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
02620                                 }
02621                                 else
02622                                 {
02623                                         // ...not fading, full alpha
02624                                         alpha = 1.f;
02625                                 }
02626                         }
02627                         else if (mAppAngle > 2.f)
02628                         {
02629                                 // far away is faded out also
02630                                 alpha = (mAppAngle-2.f)/3.f;
02631                         }
02632 
02633                         if (alpha > 0.f)
02634                         {
02635                                 if (!mNameText)
02636                                 {
02637                                         mNameText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
02638                                         mNameText->setMass(10.f);
02639                                         mNameText->setSourceObject(this);
02640                                         mNameText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP);
02641                                         mNameText->setVisibleOffScreen(TRUE);
02642                                         mNameText->setMaxLines(11);
02643                                         mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
02644                                         mNameText->setUseBubble(TRUE);
02645                                         sNumVisibleChatBubbles++;
02646                                         new_name = TRUE;
02647                                 }
02648                                 
02649                                 LLColor4 avatar_name_color = gColors.getColor( "AvatarNameColor" );
02650                                 avatar_name_color.setAlpha(alpha);
02651                                 mNameText->setColor(avatar_name_color);
02652                                 
02653                                 LLQuaternion root_rot = mRoot.getWorldRotation();
02654                                 mNameText->setUsePixelSize(TRUE);
02655                                 LLVector3 pixel_right_vec;
02656                                 LLVector3 pixel_up_vec;
02657                                 gCamera->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
02658                                 LLVector3 camera_to_av = root_pos_last - gCamera->getOrigin();
02659                                 camera_to_av.normVec();
02660                                 LLVector3 local_camera_at = camera_to_av * ~root_rot;
02661                                 LLVector3 local_camera_up = camera_to_av % gCamera->getLeftAxis();
02662                                 local_camera_up.normVec();
02663                                 local_camera_up = local_camera_up * ~root_rot;
02664                         
02665                                 local_camera_up.scaleVec(mBodySize * 0.5f);
02666                                 local_camera_at.scaleVec(mBodySize * 0.5f);
02667 
02668                                 LLVector3 name_position = mRoot.getWorldPosition() + 
02669                                         (local_camera_up * root_rot) -
02670                                         (projected_vec(local_camera_at * root_rot, camera_to_av));
02671                                 name_position += pixel_up_vec * 15.f;
02672                                 mNameText->setPositionAgent(name_position);
02673                         }
02674                         else if (mNameText)
02675                         {
02676                                 mNameText->markDead();
02677                                 mNameText = NULL;
02678                                 sNumVisibleChatBubbles--;
02679                         }
02680                 }
02681                 
02682                 LLNameValue *title = getNVPair("Title");
02683                 LLNameValue* firstname = getNVPair("FirstName");
02684                 LLNameValue* lastname = getNVPair("LastName");
02685                 
02686                 if (mNameText.notNull() && firstname && lastname)
02687                 {
02688                         BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY)  != mSignaledAnimations.end();
02689                         BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
02690                         BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
02691                         BOOL is_muted;
02692 
02693                         BOOL trustnet_title_enabled = gSavedSettings.getBOOL("TrustNetShowInBubble");
02694                         ETrustNetState tn_state = TRUSTNET_NO_ADAPTER;
02695                         ETrustNetDatumState tn_score_state = TNS_UNKNOWN;
02696 
02697                         if (mIsSelf)
02698                         {
02699                                 is_muted = FALSE;
02700                         }
02701                         else
02702                         {
02703                                 is_muted = gMuteListp->isMuted(getID());
02704                         }
02705 
02706                         if ( gTrustNet && trustnet_title_enabled )
02707                         {
02708                                 tn_state =  gTrustNet->getConnectionState();
02709                                 if ( tn_state == TRUSTNET_CONNECTED )
02710                                 {
02711                                         tn_score_state = gTrustNet->getScoreState(getID(), "behavior");
02712                                 }
02713                         }
02714 
02715                         if (mNameString.empty() ||
02716                                 new_name ||
02717                                 (!title && !mTitle.empty()) ||
02718                                 (title && mTitle != title->getString()) ||
02719                                 (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute)
02720                                 || is_appearance != mNameAppearance
02721                                 || (gTrustNet && (tn_state != mTrustNetState || tn_score_state != mTrustNetScoreState 
02722                                 || mTrustNetTitleEnabled != trustnet_title_enabled) ) )
02723                         {
02724                                 char line[MAX_STRING];          /* Flawfinder: ignore */
02725                                 line[0] = '\0';
02726 
02727                                 if ( gTrustNet && trustnet_title_enabled )
02728                                 {
02729                                         if ( tn_state != TRUSTNET_CONNECTED )
02730                                         {
02731                                                 // TrustNet not connected yet, display connection status
02732                                                 strncat(line, gTrustNet->getConnectionStateString().c_str(), MAX_STRING - strlen(line) - 1); /* why MAX_STRING and not sizeof(line)? */
02733                                                 line[MAX_STRING -1] = '\0';
02734                                         }
02735                                         else
02736                                         {
02737                                                 if ( tn_score_state == TNS_RETRIEVED )
02738                                                 {
02739                                                         std::ostringstream o;
02740                                                         o << gTrustNet->getScore(getID(), "behavior");
02741                                                         strncat(line, "Score: ", MAX_STRING - strlen(line) - 1);
02742                                                         strncat(line, o.str().c_str(), MAX_STRING - strlen(line) - 1);
02743                                                 
02744                                                         mNameText->setBackgroundColor( gTrustNet->getScoreColor(getID(), "behavior"));
02745                                                 }
02746                                                 else
02747                                                 {
02748                                                         strncat(line, "Requesting score...", MAX_STRING - strlen(line) - 1);
02749                                                 }
02750                                         }
02751 
02752                                         strcat(line, "\n");
02753                                 }
02754 
02755                                 if (!sRenderGroupTitles)
02756                                 {
02757                                         // If all group titles are turned off, stack first name
02758                                         // on a line above last name
02759                                         strncpy(line, firstname->getString(), MAX_STRING -1 );          /* Flawfinder: ignore */
02760                                         line[MAX_STRING -1] = '\0';
02761                                         strcat(line, "\n");
02762                                 }
02763                                 else if (title && title->getString() && title->getString()[0] != '\0')
02764                                 {
02765                                         strncpy(line, title->getString(), MAX_STRING -1 );              /* Flawfinder: ignore */
02766                                         line[MAX_STRING -1] = '\0';
02767                                         strcat(line, "\n");             /* Flawfinder: ignore */
02768                                         strncat(line, firstname->getString(), MAX_STRING - strlen(line) -1 );           /* Flawfinder: ignore */
02769                                 }
02770                                 else
02771                                 {
02772                                         strncat(line, firstname->getString(), MAX_STRING -1 );          /* Flawfinder: ignore */
02773                                         line[MAX_STRING -1] = '\0';
02774                                 }
02775 
02776                                 strcat(line, " ");              /* Flawfinder: ignore */
02777                                 strncat(line, lastname->getString(), MAX_STRING - strlen(line) -1);             /* Flawfinder: ignore */
02778                                 BOOL need_comma = FALSE;
02779 
02780                                 if (is_away || is_muted || is_busy)
02781                                 {
02782                                         strcat(line, " (");             /* Flawfinder: ignore */
02783                                         if (is_away)
02784                                         {
02785                                                 strcat(line, "Away");           /* Flawfinder: ignore */
02786                                                 need_comma = TRUE;
02787                                         }
02788                                         if (is_busy)
02789                                         {
02790                                                 if (need_comma)
02791                                                 {
02792                                                         strcat(line, ", ");             /* Flawfinder: ignore */
02793                                                 }
02794                                                 strcat(line, "Busy");           /* Flawfinder: ignore */
02795                                                 need_comma = TRUE;
02796                                         }
02797                                         if (is_muted)
02798                                         {
02799                                                 if (need_comma)
02800                                                 {
02801                                                         strcat(line, ", ");             /* Flawfinder: ignore */
02802                                                 }
02803                                                 strcat(line, "Muted");          /* Flawfinder: ignore */
02804                                                 need_comma = TRUE;
02805                                         }
02806                                         strcat(line,")");               /* Flawfinder: ignore */
02807                                 }
02808                                 if (is_appearance)
02809                                 {
02810                                         strcat(line, "\n(Editing Appearance)");         /* Flawfinder: ignore */
02811                                 }
02812                                 mNameAway = is_away;
02813                                 mNameBusy = is_busy;
02814                                 mNameMute = is_muted;
02815                                 mNameAppearance = is_appearance;
02816                                 mTitle = title ? title->getString() : "";
02817                                 mNameString = utf8str_to_wstring(line);
02818                                 mTrustNetTitleEnabled = trustnet_title_enabled;
02819                                 mTrustNetState = tn_state;
02820                                 mTrustNetScoreState = tn_score_state;
02821                                 new_name = TRUE;
02822                         }
02823 
02824                         if (visible_chat)
02825                         {
02826                                 mNameText->setDropShadow(TRUE);
02827                                 mNameText->setFont(LLFontGL::sSansSerif);
02828                                 mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_LEFT);
02829                                 mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
02830                                 if (new_name)
02831                                 {
02832                                         mNameText->setLabel(mNameString);
02833                                 }
02834                         
02835                                 char line[MAX_STRING];          /* Flawfinder: ignore */
02836                                 line[0] = '\0';
02837                                 std::deque<LLChat>::iterator chat_iter = mChats.begin();
02838                                 mNameText->clearString();
02839 
02840                                 LLColor4 new_chat = gColors.getColor( "AvatarNameColor" );
02841                                 LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
02842                                 LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
02843                                 if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
02844                                 {
02845                                         ++chat_iter;
02846                                 }
02847 
02848                                 for(; chat_iter != mChats.end(); ++chat_iter)
02849                                 {
02850                                         F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
02851                                         LLFontGL::StyleFlags style;
02852                                         switch(chat_iter->mChatType)
02853                                         {
02854                                         case CHAT_TYPE_WHISPER:
02855                                                 style = LLFontGL::ITALIC;
02856                                                 break;
02857                                         case CHAT_TYPE_SHOUT:
02858                                                 style = LLFontGL::BOLD;
02859                                                 break;
02860                                         default:
02861                                                 style = LLFontGL::NORMAL;
02862                                                 break;
02863                                         }
02864                                         if (chat_fade_amt < 1.f)
02865                                         {
02866                                                 F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
02867                                                 mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(new_chat, normal_chat, u), style);
02868                                         }
02869                                         else if (chat_fade_amt < 2.f)
02870                                         {
02871                                                 F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
02872                                                 mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(normal_chat, old_chat, u), style);
02873                                         }
02874                                         else if (chat_fade_amt < 3.f)
02875                                         {
02876                                                 // *NOTE: only remove lines down to minimum number
02877                                                 mNameText->addLine(utf8str_to_wstring(chat_iter->mText), old_chat, style);
02878                                         }
02879                                 }
02880                                 mNameText->setVisibleOffScreen(TRUE);
02881 
02882                                 if (mTyping)
02883                                 {
02884                                         S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
02885                                         switch(dot_count)
02886                                         {
02887                                         case 1:
02888                                                 mNameText->addLine(".", new_chat);
02889                                                 break;
02890                                         case 2:
02891                                                 mNameText->addLine("..", new_chat);
02892                                                 break;
02893                                         case 3:
02894                                                 mNameText->addLine("...", new_chat);
02895                                                 break;
02896                                         }
02897 
02898                                 }
02899                         }
02900                         else
02901                         {
02902                                 if (gSavedSettings.getBOOL("SmallAvatarNames"))
02903                                 {
02904                                         mNameText->setFont(LLFontGL::sSansSerif);
02905                                 }
02906                                 else
02907                                 {
02908                                         mNameText->setFont(LLFontGL::sSansSerifBig);
02909                                 }
02910                                 mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER);
02911                                 mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
02912                                 mNameText->setVisibleOffScreen(FALSE);
02913                                 if (new_name)
02914                                 {
02915                                         mNameText->setLabel("");
02916                                         mNameText->setString(mNameString);
02917                                 }
02918                         }
02919                 }
02920         }
02921         else if (mNameText)
02922         {
02923                 mNameText->markDead();
02924                 mNameText = NULL;
02925                 sNumVisibleChatBubbles--;
02926         }
02927 
02928         //--------------------------------------------------------------------
02929         // draw tractor beam when editing objects
02930         //--------------------------------------------------------------------
02931         if (!mIsSelf)
02932         {
02933                 return TRUE;
02934         }
02935 
02936         // This is only done for yourself (maybe it should be in the agent?)
02937         if (!needsRenderBeam() || !mIsBuilt)
02938         {
02939                 mBeam = NULL;
02940         }
02941         else if (!mBeam || mBeam->isDead())
02942         {
02943                 // VEFFECT: Tractor Beam
02944                 mBeam = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM);
02945                 mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
02946                 mBeam->setSourceObject(this);
02947                 mBeamTimer.reset();
02948         }
02949 
02950         if (!mBeam.isNull())
02951         {
02952                 LLObjectSelectionHandle selection = gSelectMgr->getSelection();
02953 
02954                 if (gAgent.mPointAt.notNull())
02955                 {
02956                         // get point from pointat effect
02957                         mBeam->setPositionGlobal(gAgent.mPointAt->getPointAtPosGlobal());
02958                         mBeam->triggerLocal();
02959                 }
02960                 else if (selection->getFirstRootObject() && 
02961                                 selection->getSelectType() != SELECT_TYPE_HUD)
02962                 {
02963                         LLViewerObject* objectp = selection->getFirstRootObject();
02964                         mBeam->setTargetObject(objectp);
02965                 }
02966                 else
02967                 {
02968                         mBeam->setTargetObject(NULL);
02969                         LLTool *tool = gToolMgr->getCurrentTool();
02970                         if (tool->isEditing())
02971                         {
02972                                 if (tool->getEditingObject())
02973                                 {
02974                                         mBeam->setTargetObject(tool->getEditingObject());
02975                                 }
02976                                 else
02977                                 {
02978                                         mBeam->setPositionGlobal(tool->getEditingPointGlobal());
02979                                 }
02980                         }
02981                         else
02982                         {
02983                                 mBeam->setPositionGlobal(gLastHitNonFloraPosGlobal + gLastHitNonFloraObjectOffset);
02984                         }
02985 
02986                 }
02987                 if (mBeamTimer.getElapsedTimeF32() > 0.25f)
02988                 {
02989                         mBeam->setColor(LLColor4U(gAgent.getEffectColor()));
02990                         mBeam->setNeedsSendToSim(TRUE);
02991                         mBeamTimer.reset();
02992                 }
02993         }
02994 
02995         F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]);
02996 
02997         F32 water_height;
02998         water_height = getRegion()->getWaterHeight();
02999 
03000         mBelowWater =  avatar_height < water_height;
03001         
03002         return TRUE;
03003 }
03004 
03005 void LLVOAvatar::slamPosition()
03006 {
03007         gAgent.setPositionAgent(getPositionAgent());
03008         mRoot.setWorldPosition(getPositionAgent()); // teleport
03009         setChanged(TRANSLATED);
03010         if (mDrawable.notNull())
03011         {
03012                 gPipeline.updateMoveNormalAsync(mDrawable);
03013         }
03014         mRoot.updateWorldMatrixChildren();
03015 }
03016 
03017 //------------------------------------------------------------------------
03018 // updateCharacter()
03019 // called on both your avatar and other avatars
03020 //------------------------------------------------------------------------
03021 void LLVOAvatar::updateCharacter(LLAgent &agent)
03022 {
03023         LLMemType mt(LLMemType::MTYPE_AVATAR);
03024 
03025         // update screen joint size
03026         if (mScreenp)
03027         {
03028                 F32 aspect = gCamera->getAspect();
03029                 LLVector3 scale(1.f, aspect, 1.f);
03030                 mScreenp->setScale(scale);
03031                 mScreenp->updateWorldMatrixChildren();
03032                 resetHUDAttachments();
03033         }
03034 
03035         // clear debug text
03036         mDebugText.clear();
03037         if (LLVOAvatar::sShowAnimationDebug)
03038         {
03039                 for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
03040                          iter != mMotionController.getActiveMotions().end(); ++iter)
03041                 {
03042                         LLMotion* motionp = *iter;
03043                         if (motionp->getMinPixelArea() < getPixelArea())
03044                         {
03045                                 std::string output;
03046                                 if (motionp->getName().empty())
03047                                 {
03048                                         output = llformat("%s - %d",
03049                                                                           motionp->getID().asString().c_str(),
03050                                                                           (U32)motionp->getPriority());
03051                                 }
03052                                 else
03053                                 {
03054                                         output = llformat("%s - %d",
03055                                                                           motionp->getName().c_str(),
03056                                                                           (U32)motionp->getPriority());
03057                                 }
03058                                 addDebugText(output);
03059                         }
03060                 }
03061         }
03062 
03063         if (gNoRender)
03064         {
03065                 // Hack if we're running drones...
03066                 if (mIsSelf)
03067                 {
03068                         gAgent.setPositionAgent(getPositionAgent());
03069                 }
03070                 return;
03071         }
03072 
03073 
03074         LLVector3d root_pos_global;
03075 
03076         if (!mIsBuilt)
03077         {
03078                 return;
03079         }
03080 
03081         // For fading out the names above heads, only let the timer
03082         // run if we're visible.
03083         if (mDrawable.notNull() && !mDrawable->isVisible())
03084         {
03085                 mTimeVisible.reset();
03086         }
03087 
03088         if (!mIsSelf && !isVisible())
03089         {
03090                 return;
03091         }
03092 
03093         // change animation time quanta based on avatar render load
03094         if (!mIsSelf)
03095         {
03096                 F32 time_quantum = clamp_rescale((F32)sInstances.size(), 10.f, 35.f, 0.f, 0.25f);
03097                 F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f);
03098                 F32 time_step = time_quantum * pixel_area_scale;
03099                 if (time_step != 0.f)
03100                 {
03101                         // disable walk motion servo controller as it doesn't work with motion timesteps
03102                         stopMotion(ANIM_AGENT_WALK_ADJUST);
03103                         removeAnimationData("Walk Speed");
03104                 }
03105                 mMotionController.setTimeStep(time_step);
03106 //              llinfos << "Setting timestep to " << time_quantum * pixel_area_scale << llendl;
03107         }
03108 
03109         if (getParent() && !mIsSitting)
03110         {
03111                 sitOnObject((LLViewerObject*)getParent());
03112         }
03113         else if (!getParent() && mIsSitting && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED))
03114         {
03115                 getOffObject();
03116         }
03117 
03118         //--------------------------------------------------------------------
03119         // create local variables in world coords for region position values
03120         //--------------------------------------------------------------------
03121         F32 speed;
03122         LLVector3 normal;
03123 
03124         LLVector3 xyVel = getVelocity();
03125         xyVel.mV[VZ] = 0.0f;
03126         speed = xyVel.magVec();
03127 
03128         BOOL throttle = TRUE;
03129 
03130         if (!(mIsSitting && getParent()))
03131         {
03132                 //--------------------------------------------------------------------
03133                 // get timing info
03134                 // handle initial condition case
03135                 //--------------------------------------------------------------------
03136                 F32 animation_time = mAnimTimer.getElapsedTimeF32();
03137                 if (mTimeLast == 0.0f)
03138                 {
03139                         mTimeLast = animation_time;
03140                         throttle = FALSE;
03141 
03142                         // put the pelvis at slaved position/mRotation
03143                         mRoot.setWorldPosition( getPositionAgent() ); // first frame
03144                         mRoot.setWorldRotation( getRotation() );
03145                 }
03146         
03147                 //--------------------------------------------------------------------
03148                 // dont' let dT get larger than 1/5th of a second
03149                 //--------------------------------------------------------------------
03150                 F32 deltaTime = animation_time - mTimeLast;
03151 
03152                 deltaTime = llclamp( deltaTime, DELTA_TIME_MIN, DELTA_TIME_MAX );
03153                 mTimeLast = animation_time;
03154 
03155                 mSpeedAccum = (mSpeedAccum * 0.95f) + (speed * 0.05f);
03156 
03157                 //--------------------------------------------------------------------
03158                 // compute the position of the avatar's root
03159                 //--------------------------------------------------------------------
03160                 LLVector3d root_pos;
03161                 LLVector3d ground_under_pelvis;
03162 
03163                 if (mIsSelf)
03164                 {
03165                         gAgent.setPositionAgent(getRenderPosition());
03166                 }
03167 
03168                 root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
03169 
03170                 resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
03171                 F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);
03172                 BOOL in_air = ( (!gWorldPointer->getRegionFromPosGlobal(ground_under_pelvis)) || 
03173                                 foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE);
03174 
03175                 if (in_air && !mInAir)
03176                 {
03177                         mTimeInAir.reset();
03178                 }
03179                 mInAir = in_air;
03180 
03181                 // correct for the fact that the pelvis is not necessarily the center 
03182                 // of the agent's physical representation
03183                 root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot;
03184                 
03185 
03186                 LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
03187 
03188                 if (newPosition != mRoot.getXform()->getWorldPosition())
03189                 {               
03190                         mRoot.touch();
03191                         mRoot.setWorldPosition(newPosition ); // regular update
03192                 }
03193 
03194 
03195                 //--------------------------------------------------------------------
03196                 // Propagate viewer object rotation to root of avatar
03197                 //--------------------------------------------------------------------
03198                 if (!isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS))
03199                 {
03200                         LLQuaternion iQ;
03201                         LLVector3 upDir( 0.0f, 0.0f, 1.0f );
03202                         
03203                         // Compute a forward direction vector derived from the primitive rotation
03204                         // and the velocity vector.  When walking or jumping, don't let body deviate
03205                         // more than 90 from the view, if necessary, flip the velocity vector.
03206 
03207                         LLVector3 primDir;
03208                         if (mIsSelf)
03209                         {
03210                                 primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector());
03211                                 primDir.normVec();
03212                         }
03213                         else
03214                         {
03215                                 primDir = getRotation().getMatrix3().getFwdRow();
03216                         }
03217                         LLVector3 velDir = getVelocity();
03218                         velDir.normVec();
03219                         if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end())
03220                         {
03221                                 F32 vpD = velDir * primDir;
03222                                 if (vpD < -0.5f)
03223                                 {
03224                                         velDir *= -1.0f;
03225                                 }
03226                         }
03227                         LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f));
03228                         if (mIsSelf && gAgent.cameraMouselook())
03229                         {
03230                                 // make sure fwdDir stays in same general direction as primdir
03231                                 if (gAgent.getFlying())
03232                                 {
03233                                         fwdDir = gCamera->getAtAxis();
03234                                 }
03235                                 else
03236                                 {
03237                                         LLVector3 at_axis = gCamera->getAtAxis();
03238                                         LLVector3 up_vector = gAgent.getReferenceUpVector();
03239                                         at_axis -= up_vector * (at_axis * up_vector);
03240                                         at_axis.normVec();
03241                                         
03242                                         F32 dot = fwdDir * at_axis;
03243                                         if (dot < 0.f)
03244                                         {
03245                                                 fwdDir -= 2.f * at_axis * dot;
03246                                                 fwdDir.normVec();
03247                                         }
03248                                 }
03249                                 
03250                         }
03251 
03252                         LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion();
03253                         F32 root_roll, root_pitch, root_yaw;
03254                         root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
03255 
03256                         if (gDebugAvatarRotation)
03257                         {
03258                                 llinfos << "root_roll " << RAD_TO_DEG * root_roll 
03259                                         << " root_pitch " << RAD_TO_DEG * root_pitch
03260                                         << " root_yaw " << RAD_TO_DEG * root_yaw
03261                                         << llendl;
03262                         }
03263 
03264                         // When moving very slow, the pelvis is allowed to deviate from the
03265                         // forward direction to allow it to hold it's position while the torso
03266                         // and head turn.  Once in motion, it must conform however.
03267                         BOOL self_in_mouselook = mIsSelf && gAgent.cameraMouselook();
03268 
03269                         LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
03270                         F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST);
03271                                                 
03272                         if (self_in_mouselook)
03273                         {
03274                                 pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR;
03275                         }
03276                         pelvis_rot_threshold *= DEG_TO_RAD;
03277 
03278                         F32 angle = angle_between( pelvisDir, fwdDir );
03279 
03280                         // The avatar's root is allowed to have a yaw that deviates widely
03281                         // from the forward direction, but if roll or pitch are off even
03282                         // a little bit we need to correct the rotation.
03283                         if(root_roll < 1.f * DEG_TO_RAD
03284                                 && root_pitch < 5.f * DEG_TO_RAD)
03285                         {
03286                                 // smaller correction vector means pelvis follows prim direction more closely
03287                                 if (!mTurning && angle > pelvis_rot_threshold*0.75f)
03288                                 {
03289                                         mTurning = TRUE;
03290                                 }
03291 
03292                                 // use tighter threshold when turning
03293                                 if (mTurning)
03294                                 {
03295                                         pelvis_rot_threshold *= 0.4f;
03296                                 }
03297 
03298                                 // am I done turning?
03299                                 if (angle < pelvis_rot_threshold)
03300                                 {
03301                                         mTurning = FALSE;
03302                                 }
03303 
03304                                 LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f);
03305                                 fwdDir += correction_vector;
03306                         }
03307                         else
03308                         {
03309                                 mTurning = FALSE;
03310                         }
03311 
03312                         // Now compute the full world space rotation for the whole body (wQv)
03313                         LLVector3 leftDir = upDir % fwdDir;
03314                         leftDir.normVec();
03315                         fwdDir = leftDir % upDir;
03316                         LLQuaternion wQv( fwdDir, leftDir, upDir );
03317 
03318                         if (mIsSelf && mTurning)
03319                         {
03320                                 if ((fwdDir % pelvisDir) * upDir > 0.f)
03321                                 {
03322                                         gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT);
03323                                 }
03324                                 else
03325                                 {
03326                                         gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT);
03327                                 }
03328                         }
03329 
03330                         // Set the root rotation, but do so incrementally so that it
03331                         // lags in time by some fixed amount.
03332                         //F32 u = LLCriticalDamp::getInterpolant(PELVIS_LAG);
03333                         F32 pelvis_lag_time = 0.f;
03334                         if (self_in_mouselook)
03335                         {
03336                                 pelvis_lag_time = PELVIS_LAG_MOUSELOOK;
03337                         }
03338                         else if (mInAir)
03339                         {
03340                                 pelvis_lag_time = PELVIS_LAG_FLYING;
03341                                 // increase pelvis lag time when moving slowly
03342                                 pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f);
03343                         }
03344                         else
03345                         {
03346                                 pelvis_lag_time = PELVIS_LAG_WALKING;
03347                         }
03348 
03349                         F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f);     
03350 
03351                         mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) );
03352                         
03353                 }
03354         }
03355         else if (mDrawable.notNull())
03356         {
03357                 mRoot.setPosition(mDrawable->getPosition());
03358                 mRoot.setRotation(mDrawable->getRotation());
03359         }
03360         
03361         //--------------------------------------------------------------------
03362         // the rest should only be done when close enough to see it
03363         //--------------------------------------------------------------------
03364         
03365 
03366         if (mPixelArea > 12.0f)
03367                 throttle = FALSE;
03368         if (mPixelArea < 400.0f)
03369         {
03370                 throttle = (LLDrawable::getCurrentFrame()+mID.mData[0])%2 != 0;
03371         }
03372 
03373         if ( !(mIsSitting && getParent()) && 
03374                 (throttle || 
03375                 (!isVisible() && (mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE))) )
03376         {
03377                 mRoot.setWorldRotation( getRotation() );
03378                 mRoot.updateWorldMatrixChildren();
03379                 return;
03380         }
03381 
03382         //-------------------------------------------------------------------------
03383         // Update character motions
03384         //-------------------------------------------------------------------------
03385         // store data relevant to motions
03386         mSpeed = speed;
03387 
03388         // update animations
03389         {
03390                 LLFastTimer t(LLFastTimer::FTM_UPDATE_ANIMATION);
03391                 updateMotion();
03392         }
03393 
03394         // update head position
03395         updateHeadOffset();
03396 
03397         //-------------------------------------------------------------------------
03398         // Find the ground under each foot, these are used for a variety
03399         // of things that follow
03400         //-------------------------------------------------------------------------
03401         LLVector3 ankle_left_pos_agent = mFootLeftp->getWorldPosition();
03402         LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
03403 
03404         LLVector3 ankle_left_ground_agent = ankle_left_pos_agent;
03405         LLVector3 ankle_right_ground_agent = ankle_right_pos_agent;
03406         resolveHeightAgent(ankle_left_pos_agent, ankle_left_ground_agent, normal);
03407         resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal);
03408 
03409         F32 leftElev = llmax(-0.2f, ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]);
03410         F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]);
03411 
03412         if (!mIsSitting)
03413         {
03414                 //-------------------------------------------------------------------------
03415                 // Figure out which foot is on ground
03416                 //-------------------------------------------------------------------------
03417                 if (!mInAir)
03418                 {
03419                         if ((leftElev < 0.0f) || (rightElev < 0.0f))
03420                         {
03421                                 ankle_left_pos_agent = mFootLeftp->getWorldPosition();
03422                                 ankle_right_pos_agent = mFootRightp->getWorldPosition();
03423                                 leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ];
03424                                 rightElev = ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ];
03425                         }
03426                 }
03427         }
03428         
03429         //-------------------------------------------------------------------------
03430         // Generate footstep sounds when feet hit the ground
03431         //-------------------------------------------------------------------------
03432         const LLUUID AGENT_FOOTSTEP_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_LAND};
03433         const S32 NUM_AGENT_FOOTSTEP_ANIMS = sizeof(AGENT_FOOTSTEP_ANIMS) / sizeof(LLUUID);
03434 
03435         if ( gAudiop && isAnyAnimationSignaled(AGENT_FOOTSTEP_ANIMS, NUM_AGENT_FOOTSTEP_ANIMS) )
03436         {
03437                 BOOL playSound = FALSE;
03438                 LLVector3 foot_pos_agent;
03439 
03440                 BOOL onGroundLeft = (leftElev <= 0.05f);
03441                 BOOL onGroundRight = (rightElev <= 0.05f);
03442 
03443                 // did left foot hit the ground?
03444                 if ( onGroundLeft && !mWasOnGroundLeft )
03445                 {
03446                         foot_pos_agent = ankle_left_pos_agent;
03447                         playSound = TRUE;
03448                 }
03449 
03450                 // did right foot hit the ground?
03451                 if ( onGroundRight && !mWasOnGroundRight )
03452                 {
03453                         foot_pos_agent = ankle_right_pos_agent;
03454                         playSound = TRUE;
03455                 }
03456 
03457                 mWasOnGroundLeft = onGroundLeft;
03458                 mWasOnGroundRight = onGroundRight;
03459 
03460                 if ( playSound )
03461                 {
03462 //                      F32 gain = clamp_rescale( mSpeedAccum,
03463 //                                                      AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
03464 //                                                      AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
03465 
03466                         F32 gain = .30f * gSavedSettings.getF32("AudioLevelAmbient");
03467                         LLUUID& step_sound_id = getStepSound();
03468 
03469                         LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
03470 
03471                         if (gParcelMgr && gParcelMgr->canHearSound(foot_pos_global)
03472                                 && gMuteListp && !gMuteListp->isMuted(getID(), LLMute::flagObjectSounds))
03473                         {
03474                                 gAudiop->triggerSound(step_sound_id, getID(), gain, foot_pos_global);
03475                         }
03476                 }
03477         }
03478 
03479         mRoot.updateWorldMatrixChildren();
03480 
03481         // Send the speaker position to the spatialized voice system.
03482         if(mIsSelf)
03483         {
03484                 LLMatrix3 rot;
03485                 LLVector3d pos;
03486 #if 1
03487                 // character rotation (stable, shouldn't move with animations)
03488                 rot = mRoot.getWorldRotation().getMatrix3();
03489 #else   
03490                 // actual head rotation (moves with animations, probably a bit too much)
03491                 rot.setRows(
03492                                 LLVector3::x_axis * mSkullp->getWorldRotation(), 
03493                                 LLVector3::y_axis * mSkullp->getWorldRotation(),  
03494                                 LLVector3::z_axis * mSkullp->getWorldRotation());               
03495 #endif
03496         
03497                 pos = getPositionGlobal();
03498                 pos += LLVector3d(mHeadOffset);
03499                 
03500                 // MBW -- XXX -- Setting velocity to 0 for now.  May figure it out later...
03501                 gVoiceClient->setAvatarPosition(
03502                                 pos,                            // position
03503                                 LLVector3::zero,        // velocity
03504                                 rot);                           // rotation matrix
03505         }
03506 
03507         if (!mDebugText.size() && mText.notNull())
03508         {
03509                 mText->markDead();
03510                 mText = NULL;
03511         }
03512         else if (mDebugText.size())
03513         {
03514                 setDebugText(mDebugText);
03515         }
03516 }
03517 
03518 //-----------------------------------------------------------------------------
03519 // updateHeadOffset()
03520 //-----------------------------------------------------------------------------
03521 void LLVOAvatar::updateHeadOffset()
03522 {
03523         // since we only care about Z, just grab one of the eyes
03524         LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
03525         midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition();
03526         midEyePt.mV[VZ] = llmax(-mPelvisToFoot + gCamera->getNear(), midEyePt.mV[VZ]);
03527 
03528         if (mDrawable.notNull())
03529         {
03530                 midEyePt = midEyePt * ~mDrawable->getWorldRotation();
03531         }
03532         if (mIsSitting)
03533         {
03534                 mHeadOffset = midEyePt; 
03535         }
03536         else
03537         {
03538                 F32 u = llmax(0.f, HEAD_MOVEMENT_AVG_TIME - (1.f / gFPSClamped));
03539                 mHeadOffset = lerp(midEyePt, mHeadOffset,  u);
03540         }
03541 }
03542 
03543 //------------------------------------------------------------------------
03544 // updateVisibility()
03545 //------------------------------------------------------------------------
03546 void LLVOAvatar::updateVisibility(BOOL force_invisible)
03547 {
03548         BOOL visible = FALSE;
03549 
03550         if (mIsDummy)
03551         {
03552                 visible = TRUE;
03553         }
03554         else if (mDrawable.isNull())
03555         {
03556                 visible = FALSE;
03557         }
03558         else if (!force_invisible)
03559         {
03560                 // calculate avatar distance wrt head
03561                 mDrawable->updateDistance(*gCamera);
03562                 
03563                 if (!mDrawable->getSpatialGroup() || mDrawable->getSpatialGroup()->isVisible())
03564                 {
03565                         visible = TRUE;
03566                 }
03567                 else
03568                 {
03569                         visible = FALSE;
03570                 }
03571 
03572                 if( mIsSelf )
03573                 {
03574                         if( !gAgent.areWearablesLoaded())
03575                         {
03576                                 visible = FALSE;
03577                         }
03578                 }
03579                 else
03580                 if( !mFirstAppearanceMessageReceived )
03581                 {
03582                         visible = FALSE;
03583                 }
03584 
03585                 if (sDebugInvisible)
03586                 {
03587                         LLNameValue* firstname = getNVPair("FirstName");
03588                         if (firstname)
03589                         {
03590                                 llinfos << "Avatar " << firstname->getString() << " updating visiblity" << llendl;
03591                         }
03592                         else
03593                         {
03594                                 llinfos << "Avatar " << this << " updating visiblity" << llendl;
03595                         }
03596 
03597                         if (visible)
03598                         {
03599                                 llinfos << "Visible" << llendl;
03600                         }
03601                         else
03602                         {
03603                                 llinfos << "Not visible" << llendl;
03604                         }
03605 
03606                         /*if (avatar_in_frustum)
03607                         {
03608                                 llinfos << "Avatar in frustum" << llendl;
03609                         }
03610                         else
03611                         {
03612                                 llinfos << "Avatar not in frustum" << llendl;
03613                         }*/
03614 
03615                         /*if (gCamera->sphereInFrustum(sel_pos_agent, 2.0f))
03616                         {
03617                                 llinfos << "Sel pos visible" << llendl;
03618                         }
03619                         if (gCamera->sphereInFrustum(wrist_right_pos_agent, 0.2f))
03620                         {
03621                                 llinfos << "Wrist pos visible" << llendl;
03622                         }
03623                         if (gCamera->sphereInFrustum(getPositionAgent(), getMaxScale()*2.f))
03624                         {
03625                                 llinfos << "Agent visible" << llendl;
03626                         }*/
03627                         llinfos << "PA: " << getPositionAgent() << llendl;
03628                         /*llinfos << "SPA: " << sel_pos_agent << llendl;
03629                         llinfos << "WPA: " << wrist_right_pos_agent << llendl;*/
03630                         for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); 
03631                                 attachment;
03632                                 attachment = mAttachmentPoints.getNextData())
03633                         {
03634                                 if (attachment->getObject())
03635                                 {
03636                                         if(attachment->getObject()->mDrawable->isVisible())
03637                                         {
03638                                                 llinfos << attachment->getName() << " visible" << llendl;
03639                                         }
03640                                         else
03641                                         {
03642                                                 llinfos << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << llendl;
03643                                         }
03644                                 }
03645                         }
03646                 }
03647         }
03648 
03649         if (!visible && mVisible)
03650         {
03651                 mMeshInvisibleTime.reset();
03652         }
03653 
03654         if (visible)
03655         {
03656                 if (!mMeshValid)
03657                 {
03658                         restoreMeshData();
03659                 }
03660         }
03661         else
03662         {
03663                 if (mMeshValid && mMeshInvisibleTime.getElapsedTimeF32() > TIME_BEFORE_MESH_CLEANUP)
03664                 {
03665                         releaseMeshData();
03666                 }
03667                 // this breaks off-screen chat bubbles
03668                 //if (mNameText)
03669                 //{
03670                 //      mNameText->markDead();
03671                 //      mNameText = NULL;
03672                 //      sNumVisibleChatBubbles--;
03673                 //}
03674         }
03675 
03676         mVisible = visible;
03677 }
03678 
03679 //------------------------------------------------------------------------
03680 // updateAllVisibility()
03681 //------------------------------------------------------------------------
03682 //static
03683 void LLVOAvatar::updateAllAvatarVisiblity()
03684 {
03685         LLVOAvatar::sNumVisibleAvatars = 0;
03686         
03687         F32 render_priority = (F32)LLVOAvatar::sMaxVisible;
03688         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
03689                 iter != LLCharacter::sInstances.end(); ++iter)
03690         {
03691                 LLVOAvatar* avatarp = (LLVOAvatar*) *iter;
03692                 if (avatarp->isDead())
03693                 {
03694                         continue;
03695                 }
03696                 if (avatarp->isSelf())
03697                 {
03698                         avatarp->mRenderPriority = 1000.f;
03699                 }
03700                 else
03701                 {
03702                         avatarp->mRenderPriority = render_priority * 10.f; // 500 -> 10
03703                         if (render_priority > 0.f)
03704                         {
03705                                 render_priority -= 1.f;
03706                         }
03707                 }
03708                 avatarp->updateVisibility(LLVOAvatar::sNumVisibleAvatars > LLVOAvatar::sMaxVisible);
03709 
03710                 if (avatarp->mDrawable.isNull())
03711                 {
03712                         llwarns << "Avatar with no drawable" << llendl;
03713                 }
03714                 else if (avatarp->mDrawable->isVisible())
03715                 {
03716                         LLVOAvatar::sNumVisibleAvatars++;
03717                 }
03718         }
03719 }
03720 
03721 //------------------------------------------------------------------------
03722 // needsRenderBeam()
03723 //------------------------------------------------------------------------
03724 BOOL LLVOAvatar::needsRenderBeam()
03725 {
03726         if (gNoRender)
03727         {
03728                 return FALSE;
03729         }
03730         LLTool *tool = gToolMgr->getCurrentTool();
03731 
03732         BOOL is_touching_or_grabbing = (tool == gToolGrab && gToolGrab->isEditing());
03733         if (gToolGrab->getEditingObject() && 
03734                 gToolGrab->getEditingObject()->isAttachment())
03735         {
03736                 // don't render selection beam on hud objects
03737                 is_touching_or_grabbing = FALSE;
03738         }
03739         return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && gSelectMgr->shouldShowSelection());
03740 }
03741 
03742 //-----------------------------------------------------------------------------
03743 // renderSkinned()
03744 //-----------------------------------------------------------------------------
03745 U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
03746 {
03747         U32 num_indices = 0;
03748 
03749         if (!mIsBuilt)
03750         {
03751                 return num_indices;
03752         }
03753 
03754         if (sDebugInvisible)
03755         {
03756                 LLNameValue* firstname = getNVPair("FirstName");
03757                 if (firstname)
03758                 {
03759                         llinfos << "Avatar " << firstname->getString() << " in render" << llendl;
03760                 }
03761                 else
03762                 {
03763                         llinfos << "Avatar " << this << " in render" << llendl;
03764                 }
03765                 if (!mIsBuilt)
03766                 {
03767                         llinfos << "Not built!" << llendl;
03768                 }
03769                 else if (!gAgent.needsRenderAvatar())
03770                 {
03771                         llinfos << "Doesn't need avatar render!" << llendl;
03772                 }
03773                 else
03774                 {
03775                         llinfos << "Rendering!" << llendl;
03776                 }
03777         }
03778 
03779         if (!mIsBuilt)
03780         {
03781                 return num_indices;
03782         }
03783 
03784         if (mIsSelf && !gAgent.needsRenderAvatar())
03785         {
03786                 return num_indices;
03787         }
03788 
03789         // render collision normal
03790         if (sShowFootPlane && mDrawable.notNull())
03791         {
03792                 LLVector3 slaved_pos = mDrawable->getPositionAgent();
03793                 LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]);
03794                 F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW];
03795                 LLVector3 collide_point = slaved_pos;
03796                 collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE);
03797 
03798                 glBegin(GL_LINES);
03799                 {
03800                         F32 SQUARE_SIZE = 0.2f;
03801                         glColor4f(1.f, 0.f, 0.f, 1.f);
03802                         
03803                         glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
03804                         glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
03805 
03806                         glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
03807                         glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
03808                         
03809                         glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
03810                         glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
03811                         
03812                         glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]);
03813                         glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]);
03814                         
03815                         glVertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]);
03816                         glVertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]);
03817 
03818                 }glEnd();
03819         }
03820         //--------------------------------------------------------------------
03821         // render all geomety attached to the skeleton
03822         //--------------------------------------------------------------------
03823         static LLStat render_stat;
03824 
03825         LLViewerJointMesh::sRenderPass = pass;
03826 
03827         if (pass == AVATAR_RENDER_PASS_SINGLE)
03828         {
03829                 BOOL first_pass = TRUE;
03830                 if (!mIsSelf || gAgent.needsRenderHead())
03831                 {
03832                         num_indices += mHeadLOD.render(mAdjustedPixelArea);
03833                         first_pass = FALSE;
03834                 }
03835                 num_indices += mUpperBodyLOD.render(mAdjustedPixelArea, first_pass);
03836                 num_indices += mLowerBodyLOD.render(mAdjustedPixelArea, FALSE);
03837 
03838                 {
03839                         LLGLEnable blend(GL_BLEND);
03840                         LLGLEnable test(GL_ALPHA_TEST);
03841                         num_indices += renderTransparent();
03842                 }
03843         }
03844         /*else if (pass == AVATAR_RENDER_PASS_CLOTHING_INNER)
03845         {
03846                 if (!mIsSelf || gAgent.needsRenderHead())
03847                 {
03848                         num_indices += mHeadLOD.render(mAdjustedPixelArea);
03849                 }
03850                 LLViewerJointMesh::sClothingInnerColor = mTexSkinColor->getColor() * 0.5f;
03851                 LLViewerJointMesh::sClothingMaskImageName = mUpperMaskTexName;
03852                 num_indices += mUpperBodyLOD.render(mAdjustedPixelArea);
03853                 LLViewerJointMesh::sClothingMaskImageName = mLowerMaskTexName;
03854                 num_indices += mLowerBodyLOD.render(mAdjustedPixelArea);
03855                 LLViewerJointMesh::sClothingMaskImageName = 0;
03856                 if( isWearingWearableType( WT_SKIRT ) )
03857                 {
03858                         glAlphaFunc(GL_GREATER,0.25f);
03859                         num_indices += mSkirtLOD.render(mAdjustedPixelArea);
03860                         glAlphaFunc(GL_GREATER,0.01f);
03861                 }
03862 
03863                 if (!mIsSelf || gAgent.needsRenderHead())
03864                 {
03865                         num_indices += mEyeLashLOD.render(mAdjustedPixelArea);
03866                         num_indices += mHairLOD.render(mAdjustedPixelArea);
03867                 }
03868         }
03869         else if (pass == AVATAR_RENDER_PASS_CLOTHING_OUTER)
03870         {
03871                 LLViewerJointMesh::sClothingInnerColor = mTexSkinColor->getColor() * 0.5f;
03872                 LLViewerJointMesh::sClothingMaskImageName = mUpperMaskTexName;
03873                 num_indices += mUpperBodyLOD.render(mAdjustedPixelArea);
03874                 LLViewerJointMesh::sClothingMaskImageName = mLowerMaskTexName;
03875                 num_indices += mLowerBodyLOD.render(mAdjustedPixelArea);
03876                 LLViewerJointMesh::sClothingMaskImageName = 0;
03877         }*/
03878 
03879         LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
03880         
03881         //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl;
03882 
03883         //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f);
03884 
03885         return num_indices;
03886 }
03887 
03888 U32 LLVOAvatar::renderTransparent()
03889 {
03890         U32 num_indices = 0;
03891         BOOL first_pass = FALSE;
03892         if( isWearingWearableType( WT_SKIRT ) )
03893         {
03894                 glAlphaFunc(GL_GREATER,0.25f);
03895                 num_indices += mSkirtLOD.render(mAdjustedPixelArea, FALSE);
03896                 first_pass = FALSE;
03897                 glAlphaFunc(GL_GREATER,0.01f);
03898         }
03899 
03900         if (!mIsSelf || gAgent.needsRenderHead())
03901         {
03902                 num_indices += mEyeLashLOD.render(mAdjustedPixelArea, first_pass);
03903                 num_indices += mHairLOD.render(mAdjustedPixelArea, FALSE);
03904         }
03905 
03906         return num_indices;
03907 }
03908 
03909 //-----------------------------------------------------------------------------
03910 // renderRigid()
03911 //-----------------------------------------------------------------------------
03912 U32 LLVOAvatar::renderRigid()
03913 {
03914         U32 num_indices = 0;
03915 
03916         if (!mIsBuilt)
03917         {
03918                 return 0;
03919         }
03920 
03921         if (mIsSelf && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
03922         {
03923                 return 0;
03924         }
03925         
03926         if (!mIsBuilt)
03927         {
03928                 return 0;
03929         }
03930 
03931         num_indices += mEyeBallLeftLOD.render(mAdjustedPixelArea);
03932         num_indices += mEyeBallRightLOD.render(mAdjustedPixelArea);
03933         
03934         return num_indices;
03935 }
03936 
03937 U32 LLVOAvatar::renderFootShadows()
03938 {
03939         U32 num_indices = 0;
03940 
03941         if (!mIsBuilt)
03942         {
03943                 return 0;
03944         }
03945 
03946         if (mIsSelf && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
03947         {
03948                 return 0;
03949         }
03950         
03951         if (!mIsBuilt)
03952         {
03953                 return 0;
03954         }
03955 
03956         U32 foot_mask = LLVertexBuffer::MAP_VERTEX |
03957                                         LLVertexBuffer::MAP_TEXCOORD;
03958 
03959         //render foot shadows
03960         LLGLEnable blend(GL_BLEND);
03961         mShadowImagep->bind();
03962         glColor4fv(mShadow0Facep->getRenderColor().mV);
03963         mShadow0Facep->renderIndexed(foot_mask);
03964         glColor4fv(mShadow1Facep->getRenderColor().mV);
03965         mShadow1Facep->renderIndexed(foot_mask);
03966         
03967         return num_indices;
03968 }
03969 
03970 //-----------------------------------------------------------------------------
03971 // renderCollisionVolumes()
03972 //-----------------------------------------------------------------------------
03973 void LLVOAvatar::renderCollisionVolumes()
03974 {
03975         for (S32 i = 0; i < mNumCollisionVolumes; i++)
03976         {
03977                 mCollisionVolumes[i].render();
03978         }
03979 }
03980 
03981 //------------------------------------------------------------------------
03982 // LLVOAvatar::updateTextures()
03983 //------------------------------------------------------------------------
03984 void LLVOAvatar::updateTextures(LLAgent &agent)
03985 {
03986 //      LLFastTimer ftm(LLFastTimer::FTM_TEMP5);
03987         BOOL render_avatar = TRUE;
03988 
03989         if (mIsDummy || gNoRender)
03990         {
03991                 return;
03992         }
03993         
03994         BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR );
03995         BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
03996         BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
03997         BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR );
03998         BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );
03999 
04000         if( mIsSelf )
04001         {
04002                 render_avatar = TRUE;
04003         }
04004         else
04005         {
04006                 render_avatar = isVisible() && !mCulled;
04007         }
04008 
04009         // bind the texture so that they'll be decoded
04010         // slightly inefficient, we can short-circuit this
04011         // if we have to
04012         if( render_avatar && !gGLManager.mIsDisabled )
04013         {
04014                 if( head_baked && ! mHeadBakedLoaded )
04015                 {
04016                         getTEImage( TEX_HEAD_BAKED )->bind();
04017                 }
04018                 if( upper_baked && ! mUpperBakedLoaded )
04019                 {
04020                         getTEImage( TEX_UPPER_BAKED )->bind();
04021                 }
04022                 if( lower_baked && ! mLowerBakedLoaded )
04023                 {
04024                         getTEImage( TEX_LOWER_BAKED )->bind();
04025                 }
04026                 if( eyes_baked && ! mEyesBakedLoaded )
04027                 {
04028                         getTEImage( TEX_EYES_BAKED )->bind();
04029                 }
04030                 if( skirt_baked && ! mSkirtBakedLoaded )
04031                 {
04032                         getTEImage( TEX_SKIRT_BAKED )->bind();
04033                 }
04034         }
04035 
04036         /*
04037         // JAMESDEBUG
04038         if (mIsSelf)
04039         {
04040                 S32 null_count = 0;
04041                 S32 default_count = 0;
04042                 for (U32 i = 0; i < getNumTEs(); i++)
04043                 {
04044                         const LLTextureEntry* te = getTE(i);
04045                         if (te)
04046                         {
04047                                 if (te->getID() == LLUUID::null)
04048                                 {
04049                                         null_count++;
04050                                 }
04051                                 else if (te->getID() == IMG_DEFAULT_AVATAR)
04052                                 {
04053                                         default_count++;
04054                                 }
04055                         }
04056                 }
04057                 llinfos << "JAMESDEBUG my avatar TE null " << null_count << " default " << default_count << llendl;
04058         }
04059         */
04060 
04061         mMaxPixelArea = 0.f;
04062         mMinPixelArea = 99999999.f;
04063         for (U32 i = 0; i < getNumTEs(); i++)
04064         {
04065                 LLViewerImage *imagep = getTEImage(i);
04066                 if (imagep)
04067                 {
04068                         // Debugging code - maybe non-self avatars are downloading textures?
04069                         //llinfos << "avatar self " << mIsSelf << " tex " << i 
04070                         //      << " decode " << imagep->getDecodePriority()
04071                         //      << " boost " << boost_avatar 
04072                         //      << " size " << imagep->getWidth() << "x" << imagep->getHeight()
04073                         //      << " discard " << imagep->getDiscardLevel()
04074                         //      << " desired " << imagep->getDesiredDiscardLevel()
04075                         //      << llendl;
04076                         
04077                         const LLTextureEntry *te = getTE(i);
04078                         F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT);
04079 //                      BOOL boost_aux = (imagep->needsAux() && (!imagep->mFullWidth || !imagep->mFullHeight));
04080                         S32 boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_BAKED_SELF : LLViewerImage::BOOST_AVATAR_BAKED;
04081                         
04082                         // Spam if this is a baked texture, not set to default image, without valid host info
04083                         if (isTextureIndexBaked(i)
04084                                 && imagep->getID() != IMG_DEFAULT_AVATAR
04085                                 && !imagep->getTargetHost().isOk())
04086                         {
04087                                 llwarns << "LLVOAvatar::updateTextures No host for texture "
04088                                         << imagep->getID() << " for avatar "
04089                                         << (mIsSelf ? "<myself>" : getID().asString().c_str()) 
04090                                         << " on host " << getRegion()->getHost() << llendl;
04091                         }
04092                         
04093                         switch( i )
04094                         {
04095                         // Head
04096                         case TEX_HEAD_BODYPAINT:
04097                                 addLocalTextureStats( LOCTEX_HEAD_BODYPAINT, imagep, texel_area_ratio, render_avatar, head_baked );
04098                                 break;
04099 
04100                         // Upper
04101                         case TEX_UPPER_JACKET:
04102                                 addLocalTextureStats( LOCTEX_UPPER_JACKET, imagep, texel_area_ratio, render_avatar, upper_baked );
04103                                 break;
04104 
04105                         case TEX_UPPER_SHIRT:
04106                                 addLocalTextureStats( LOCTEX_UPPER_SHIRT, imagep, texel_area_ratio, render_avatar, upper_baked );
04107                                 break;
04108 
04109                         case TEX_UPPER_GLOVES:
04110                                 addLocalTextureStats( LOCTEX_UPPER_GLOVES, imagep, texel_area_ratio, render_avatar, upper_baked );
04111                                 break;
04112                         
04113                         case TEX_UPPER_UNDERSHIRT:
04114                                 addLocalTextureStats( LOCTEX_UPPER_UNDERSHIRT, imagep, texel_area_ratio, render_avatar, upper_baked );
04115                                 break;
04116 
04117                         case TEX_UPPER_BODYPAINT:
04118                                 addLocalTextureStats( LOCTEX_UPPER_BODYPAINT, imagep, texel_area_ratio, render_avatar, upper_baked );
04119                                 break;
04120 
04121                         // Lower
04122                         case TEX_LOWER_JACKET:
04123                                 addLocalTextureStats( LOCTEX_LOWER_JACKET, imagep, texel_area_ratio, render_avatar, lower_baked );
04124                                 break;
04125 
04126                         case TEX_LOWER_PANTS:
04127                                 addLocalTextureStats( LOCTEX_LOWER_PANTS, imagep, texel_area_ratio, render_avatar, lower_baked );
04128                                 break;
04129 
04130                         case TEX_LOWER_SHOES:
04131                                 addLocalTextureStats( LOCTEX_LOWER_SHOES, imagep, texel_area_ratio, render_avatar, lower_baked );
04132                                 break;
04133 
04134                         case TEX_LOWER_SOCKS:
04135                                 addLocalTextureStats( LOCTEX_LOWER_SOCKS, imagep, texel_area_ratio, render_avatar, lower_baked );
04136                                 break;
04137 
04138                         case TEX_LOWER_UNDERPANTS:
04139                                 addLocalTextureStats( LOCTEX_LOWER_UNDERPANTS, imagep, texel_area_ratio, render_avatar, lower_baked );
04140                                 break;
04141 
04142                         case TEX_LOWER_BODYPAINT:
04143                                 addLocalTextureStats( LOCTEX_LOWER_BODYPAINT, imagep, texel_area_ratio, render_avatar, lower_baked );
04144                                 break;
04145 
04146                         // Eyes
04147                         case TEX_EYES_IRIS:
04148                                 addLocalTextureStats( LOCTEX_EYES_IRIS, imagep, texel_area_ratio, render_avatar, eyes_baked );
04149                                 break;
04150 
04151                         // Skirt
04152                         case TEX_SKIRT:
04153                                 addLocalTextureStats( LOCTEX_SKIRT, imagep, texel_area_ratio, render_avatar, skirt_baked );
04154                                 break;
04155 
04156                         // Baked
04157                         case TEX_HEAD_BAKED:
04158                                 if (head_baked)
04159                                 {
04160                                         addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
04161                                 }
04162                                 break;
04163 
04164                         case TEX_UPPER_BAKED:
04165                                 if (upper_baked)
04166                                 {
04167                                         addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
04168                                 }
04169                                 break;
04170                         
04171                         case TEX_LOWER_BAKED:
04172                                 if (lower_baked)
04173                                 {
04174                                         addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
04175                                 }
04176                                 break;
04177                         
04178                         case TEX_EYES_BAKED:
04179                                 if (eyes_baked)
04180                                 {
04181                                         addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
04182                                 }
04183                                 break;
04184 
04185                         case TEX_SKIRT_BAKED:
04186                                 if (skirt_baked)
04187                                 {
04188                                         addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
04189                                 }
04190                                 break;
04191 
04192                         case TEX_HAIR:
04193                                 // Hair is neither a local texture used for baking, nor the output
04194                                 // of the baking process.  It's just a texture that happens to be
04195                                 // used to draw avatars.  Hence BOOST_AVATAR.  JC
04196                                 boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_SELF : LLViewerImage::BOOST_AVATAR;
04197                                 addBakedTextureStats( imagep, mPixelArea, texel_area_ratio, boost_level );
04198                                 break;
04199                         
04200                         default:
04201                                 llassert(0);
04202                                 break;
04203                         }
04204                 }
04205         }
04206 
04207         if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
04208         {
04209                 setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));
04210         }       
04211         
04212         if( render_avatar )
04213         {
04214                 mShadowImagep->addTextureStats(mPixelArea);
04215         }
04216 }
04217 
04218 
04219 void LLVOAvatar::addLocalTextureStats( LLVOAvatar::ELocTexIndex idx, LLViewerImage* imagep,
04220                                                                            F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked )
04221 {
04222         if (!covered_by_baked &&
04223                 render_avatar && // always true if mIsSelf
04224                 mLocalTexture[ idx ].notNull() && mLocalTexture[idx]->getID() != IMG_DEFAULT_AVATAR)
04225         {       
04226                 F32 desired_pixels;
04227                 if( mIsSelf )
04228                 {
04229                         desired_pixels = llmin(mPixelArea, (F32)LOCTEX_IMAGE_AREA_SELF );
04230                         imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR_SELF);
04231                 }
04232                 else
04233                 {
04234                         desired_pixels = llmin(mPixelArea, (F32)LOCTEX_IMAGE_AREA_OTHER );
04235                         imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR);
04236                 }
04237                 imagep->addTextureStats( desired_pixels, texel_area_ratio );
04238         }
04239 }
04240 
04241                             
04242 void LLVOAvatar::addBakedTextureStats( LLViewerImage* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
04243 {
04244         mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);
04245         mMinPixelArea = llmin(pixel_area, mMinPixelArea);
04246         imagep->addTextureStats(pixel_area, texel_area_ratio);
04247         imagep->setBoostLevel(boost_level);
04248 }
04249 
04250 //-----------------------------------------------------------------------------
04251 // resolveHeight()
04252 //-----------------------------------------------------------------------------
04253 
04254 void LLVOAvatar::resolveHeightAgent(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &out_norm)
04255 {
04256         LLVector3d in_pos_global, out_pos_global;
04257 
04258         in_pos_global = gAgent.getPosGlobalFromAgent(in_pos_agent);
04259         resolveHeightGlobal(in_pos_global, out_pos_global, out_norm);
04260         out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global);
04261 }
04262 
04263 
04264 void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm)
04265 {
04266         LLViewerObject *obj;
04267         gWorldPointer->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj);
04268 }
04269 
04270 
04271 void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm)
04272 {
04273         LLVector3d zVec(0.0f, 0.0f, 0.5f);
04274         LLVector3d p0 = inPos + zVec;
04275         LLVector3d p1 = inPos - zVec;
04276         LLViewerObject *obj;
04277         gWorldPointer->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj);
04278         if (!obj)
04279         {
04280                 mStepOnLand = TRUE;
04281                 mStepMaterial = 0;
04282                 mStepObjectVelocity.setVec(0.0f, 0.0f, 0.0f);
04283         }
04284         else
04285         {
04286                 mStepOnLand = FALSE;
04287                 mStepMaterial = obj->getMaterial();
04288 
04289                 // We want the primitive velocity, not our velocity... (which actually subtracts the
04290                 // step object velocity)
04291                 LLVector3 angularVelocity = obj->getAngularVelocity();
04292                 LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent();
04293 
04294                 LLVector3 linearComponent = angularVelocity % relativePos;
04295 //              llinfos << "Linear Component of Rotation Velocity " << linearComponent << llendl;
04296                 mStepObjectVelocity = obj->getVelocity() + linearComponent;
04297         }
04298 }
04299 
04300 
04301 //-----------------------------------------------------------------------------
04302 // getStepSound()
04303 //-----------------------------------------------------------------------------
04304 LLUUID& LLVOAvatar::getStepSound()
04305 {
04306         if ( mStepOnLand )
04307         {
04308                 return sStepSoundOnLand;
04309         }
04310 
04311         return sStepSounds[mStepMaterial];
04312 }
04313 
04314 
04315 //-----------------------------------------------------------------------------
04316 // processAnimationStateChanges()
04317 //-----------------------------------------------------------------------------
04318 void LLVOAvatar::processAnimationStateChanges()
04319 {
04320         LLMemType mt(LLMemType::MTYPE_AVATAR);
04321         
04322         if (gNoRender)
04323         {
04324                 return;
04325         }
04326 
04327         if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) )
04328         {
04329                 startMotion(ANIM_AGENT_WALK_ADJUST);
04330                 stopMotion(ANIM_AGENT_FLY_ADJUST);
04331         }
04332         else if (mInAir && !mIsSitting)
04333         {
04334                 stopMotion(ANIM_AGENT_WALK_ADJUST);
04335                 startMotion(ANIM_AGENT_FLY_ADJUST);
04336         }
04337         else
04338         {
04339                 stopMotion(ANIM_AGENT_WALK_ADJUST);
04340                 stopMotion(ANIM_AGENT_FLY_ADJUST);
04341         }
04342 
04343         if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
04344         {
04345                 startMotion(ANIM_AGENT_TARGET);
04346                 stopMotion(ANIM_AGENT_BODY_NOISE);
04347         }
04348         else
04349         {
04350                 stopMotion(ANIM_AGENT_TARGET);
04351                 startMotion(ANIM_AGENT_BODY_NOISE);
04352         }
04353         
04354         // clear all current animations
04355         AnimIterator anim_it;
04356         for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();)
04357         {
04358                 AnimIterator found_anim = mSignaledAnimations.find(anim_it->first);
04359 
04360                 // playing, but not signaled, so stop
04361                 if (found_anim == mSignaledAnimations.end())
04362                 {
04363                         processSingleAnimationStateChange(anim_it->first, FALSE);
04364                         mPlayingAnimations.erase(anim_it++);
04365                         continue;
04366                 }
04367 
04368                 ++anim_it;
04369         }
04370 
04371         // start up all new anims
04372         for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
04373         {
04374                 AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
04375 
04376                 // signaled but not playing, or different sequence id, start motion
04377                 if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
04378                 {
04379                         if (processSingleAnimationStateChange(anim_it->first, TRUE))
04380                         {
04381                                 mPlayingAnimations[anim_it->first] = anim_it->second;
04382                                 ++anim_it;
04383                                 continue;
04384                         }
04385                 }
04386 
04387                 ++anim_it;
04388         }
04389 
04390         // clear source information for animations which have been stopped
04391         if (mIsSelf)
04392         {
04393                 AnimSourceIterator source_it = mAnimationSources.begin();
04394 
04395                 for (source_it = mAnimationSources.begin(); source_it != mAnimationSources.end();)
04396                 {
04397                         if (mSignaledAnimations.find(source_it->second) == mSignaledAnimations.end())
04398                         {
04399                                 mAnimationSources.erase(source_it++);
04400                         }
04401                         else
04402                         {
04403                                 ++source_it;
04404                         }
04405                 }
04406         }
04407 
04408         stop_glerror();
04409 }
04410 
04411 
04412 //-----------------------------------------------------------------------------
04413 // processSingleAnimationStateChange();
04414 //-----------------------------------------------------------------------------
04415 BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start )
04416 {
04417         LLMemType mt(LLMemType::MTYPE_AVATAR);
04418         
04419         BOOL result = FALSE;
04420 
04421         if ( start ) // start animation
04422         {
04423                 if (anim_id == ANIM_AGENT_TYPE)
04424                 {
04425                         if (gAudiop)
04426                         {
04427                                 LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition());
04428                                 if (gParcelMgr && gParcelMgr->canHearSound(char_pos_global)
04429                                         && gMuteListp && !gMuteListp->isMuted(getID(), LLMute::flagObjectSounds))
04430                                 {
04431                                         // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed
04432                                         // to support both spatialized and non-spatialized instances of the same sound
04433                                         //if (mIsSelf)
04434                                         //{
04435                                         //  F32 volume = gain * gSavedSettings.getF32("AudioLevelUI")
04436                                         //      gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), volume);
04437                                         //}
04438                                         //else
04439                                         {
04440                                                 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
04441                                                 F32 volume = gSavedSettings.getF32("AudioLevelSFX");
04442                                                 gAudiop->triggerSound(sound_id, getID(), volume, char_pos_global);
04443                                         }
04444                                 }
04445                         }
04446                 }
04447                 else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
04448                 {
04449                         mIsSitting = TRUE;
04450                 }
04451 
04452 
04453                 if (startMotion(anim_id))
04454                 {
04455                         result = TRUE;
04456                 }
04457                 else
04458                 {
04459                         llwarns << "Failed to start motion!" << llendl;
04460                 }
04461         }
04462         else //stop animation
04463         {
04464                 if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED)
04465                 {
04466                         mIsSitting = FALSE;
04467                 }
04468                 stopMotion(anim_id);
04469                 result = TRUE;
04470         }
04471 
04472         return result;
04473 }
04474 
04475 //-----------------------------------------------------------------------------
04476 // isAnyAnimationSignaled()
04477 //-----------------------------------------------------------------------------
04478 BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims)
04479 {
04480         for (S32 i = 0; i < num_anims; i++)
04481         {
04482                 if(mSignaledAnimations.find(anim_array[i]) != mSignaledAnimations.end())
04483                 {
04484                         return TRUE;
04485                 }
04486         }
04487         return FALSE;
04488 }
04489 
04490 //-----------------------------------------------------------------------------
04491 // resetAnimations()
04492 //-----------------------------------------------------------------------------
04493 void LLVOAvatar::resetAnimations()
04494 {
04495         LLKeyframeMotion::flushKeyframeCache();
04496         flushAllMotions();
04497 }
04498 
04499 //-----------------------------------------------------------------------------
04500 // startMotion()
04501 // id is the asset if of the animation to start
04502 // time_offset is the offset into the animation at which to start playing
04503 //-----------------------------------------------------------------------------
04504 BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset)
04505 {
04506         LLMemType mt(LLMemType::MTYPE_AVATAR);
04507         
04508         // start special case female walk for female avatars
04509         if (getSex() == SEX_FEMALE)
04510         {
04511                 if (id == ANIM_AGENT_WALK)
04512                 {
04513                         return LLCharacter::startMotion(ANIM_AGENT_FEMALE_WALK, time_offset);
04514                 }
04515                 else if (id == ANIM_AGENT_SIT)
04516                 {
04517                         return LLCharacter::startMotion(ANIM_AGENT_SIT_FEMALE, time_offset);
04518                 }
04519         }
04520 
04521         if (mIsSelf && id == ANIM_AGENT_AWAY)
04522         {
04523                 gAgent.setAFK();
04524         }
04525 
04526         return LLCharacter::startMotion(id, time_offset);
04527 }
04528 
04529 //-----------------------------------------------------------------------------
04530 // stopMotion()
04531 //-----------------------------------------------------------------------------
04532 BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate)
04533 {
04534         if (mIsSelf)
04535         {
04536                 gAgent.onAnimStop(id);
04537         }
04538 
04539         if (id == ANIM_AGENT_WALK)
04540         {
04541                 LLCharacter::stopMotion(ANIM_AGENT_FEMALE_WALK, stop_immediate);
04542         }
04543         else if (id == ANIM_AGENT_SIT)
04544         {
04545                 LLCharacter::stopMotion(ANIM_AGENT_SIT_FEMALE, stop_immediate);
04546         }
04547 
04548         return LLCharacter::stopMotion(id, stop_immediate);
04549 }
04550 
04551 //-----------------------------------------------------------------------------
04552 // stopMotionFromSource()
04553 //-----------------------------------------------------------------------------
04554 void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)
04555 {
04556         if (!mIsSelf)
04557         {
04558                 return;
04559         }
04560         AnimSourceIterator motion_it;
04561 
04562         for(motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end();)
04563         {
04564                 gAgent.sendAnimationRequest( motion_it->second, ANIM_REQUEST_STOP );
04565                 mAnimationSources.erase(motion_it++);
04566         }
04567 
04568         LLViewerObject* object = gObjectList.findObject(source_id);
04569         if (object)
04570         {
04571                 object->mFlags &= ~FLAGS_ANIM_SOURCE;
04572         }
04573 }
04574 
04575 //-----------------------------------------------------------------------------
04576 // getVolumePos()
04577 //-----------------------------------------------------------------------------
04578 LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset)
04579 {
04580         if (joint_index > mNumCollisionVolumes)
04581         {
04582                 return LLVector3::zero;
04583         }
04584 
04585         return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
04586 }
04587 
04588 //-----------------------------------------------------------------------------
04589 // findCollisionVolume()
04590 //-----------------------------------------------------------------------------
04591 LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id)
04592 {
04593         if ((S32)volume_id > mNumCollisionVolumes)
04594         {
04595                 return NULL;
04596         }
04597         
04598         return &mCollisionVolumes[volume_id];
04599 }
04600 
04601 //-----------------------------------------------------------------------------
04602 // findCollisionVolume()
04603 //-----------------------------------------------------------------------------
04604 S32 LLVOAvatar::getCollisionVolumeID(std::string &name)
04605 {
04606         for (S32 i = 0; i < mNumCollisionVolumes; i++)
04607         {
04608                 if (mCollisionVolumes[i].getName() == name)
04609                 {
04610                         return i;
04611                 }
04612         }
04613 
04614         return -1;
04615 }
04616 
04617 //-----------------------------------------------------------------------------
04618 // addDebugText()
04619 //-----------------------------------------------------------------------------
04620  void LLVOAvatar::addDebugText(const std::string& text)
04621 {
04622         mDebugText.append(1, '\n');
04623         mDebugText.append(text);
04624 }
04625 
04626 //-----------------------------------------------------------------------------
04627 // getID()
04628 //-----------------------------------------------------------------------------
04629 const LLUUID& LLVOAvatar::getID()
04630 {
04631         return mID;
04632 }
04633 
04634 //-----------------------------------------------------------------------------
04635 // getJoint()
04636 //-----------------------------------------------------------------------------
04637 // RN: avatar joints are multi-rooted to include screen-based attachments
04638 LLJoint *LLVOAvatar::getJoint( const std::string &name )
04639 {
04640         LLJoint* jointp = NULL;
04641         if (mScreenp)
04642         {
04643                 jointp = mScreenp->findJoint(name);
04644         }
04645         if (!jointp)
04646         {
04647                 jointp = mRoot.findJoint(name);
04648         }
04649         return jointp;
04650 }
04651 
04652 //-----------------------------------------------------------------------------
04653 // getCharacterPosition()
04654 //-----------------------------------------------------------------------------
04655 LLVector3 LLVOAvatar::getCharacterPosition()
04656 {
04657         if (mDrawable.notNull())
04658         {
04659                 return mDrawable->getPositionAgent();
04660         }
04661         else
04662         {
04663                 return getPositionAgent();
04664         }
04665 }
04666 
04667 
04668 //-----------------------------------------------------------------------------
04669 // LLVOAvatar::getCharacterRotation()
04670 //-----------------------------------------------------------------------------
04671 LLQuaternion LLVOAvatar::getCharacterRotation()
04672 {
04673         return getRotation();
04674 }
04675 
04676 
04677 //-----------------------------------------------------------------------------
04678 // LLVOAvatar::getCharacterVelocity()
04679 //-----------------------------------------------------------------------------
04680 LLVector3 LLVOAvatar::getCharacterVelocity()
04681 {
04682         return getVelocity() - mStepObjectVelocity;
04683 }
04684 
04685 
04686 //-----------------------------------------------------------------------------
04687 // LLVOAvatar::getCharacterAngularVelocity()
04688 //-----------------------------------------------------------------------------
04689 LLVector3 LLVOAvatar::getCharacterAngularVelocity()
04690 {
04691         return getAngularVelocity();
04692 }
04693 
04694 //-----------------------------------------------------------------------------
04695 // LLVOAvatar::getGround()
04696 //-----------------------------------------------------------------------------
04697 void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &outNorm)
04698 {
04699         LLVector3d z_vec(0.0f, 0.0f, 1.0f);
04700         LLVector3d p0_global, p1_global;
04701 
04702         if (gNoRender || mIsDummy)
04703         {
04704                 outNorm.setVec(z_vec);
04705                 out_pos_agent = in_pos_agent;
04706                 return;
04707         }
04708         
04709         p0_global = gAgent.getPosGlobalFromAgent(in_pos_agent) + z_vec;
04710         p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec;
04711         LLViewerObject *obj;
04712         LLVector3d out_pos_global;
04713         gWorldPointer->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj);
04714         out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global);
04715 }
04716 
04717 //-----------------------------------------------------------------------------
04718 // LLVOAvatar::getTimeDilation()
04719 //-----------------------------------------------------------------------------
04720 F32 LLVOAvatar::getTimeDilation()
04721 {
04722         return mTimeDilation;
04723 }
04724 
04725 
04726 //-----------------------------------------------------------------------------
04727 // LLVOAvatar::getPixelArea()
04728 //-----------------------------------------------------------------------------
04729 F32 LLVOAvatar::getPixelArea() const
04730 {
04731         if (mIsDummy)
04732         {
04733                 return 100000.f;
04734         }
04735         return mPixelArea;
04736 }
04737 
04738 
04739 //-----------------------------------------------------------------------------
04740 // LLVOAvatar::getHeadMesh()
04741 //-----------------------------------------------------------------------------
04742 LLPolyMesh*     LLVOAvatar::getHeadMesh()
04743 {
04744         return mHeadMesh0.getMesh();
04745 }
04746 
04747 
04748 //-----------------------------------------------------------------------------
04749 // LLVOAvatar::getUpperBodyMesh()
04750 //-----------------------------------------------------------------------------
04751 LLPolyMesh*     LLVOAvatar::getUpperBodyMesh()
04752 {
04753         return mUpperBodyMesh0.getMesh();
04754 }
04755 
04756 
04757 //-----------------------------------------------------------------------------
04758 // LLVOAvatar::getPosGlobalFromAgent()
04759 //-----------------------------------------------------------------------------
04760 LLVector3d      LLVOAvatar::getPosGlobalFromAgent(const LLVector3 &position)
04761 {
04762         return gAgent.getPosGlobalFromAgent(position);
04763 }
04764 
04765 //-----------------------------------------------------------------------------
04766 // getPosAgentFromGlobal()
04767 //-----------------------------------------------------------------------------
04768 LLVector3       LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
04769 {
04770         return gAgent.getPosAgentFromGlobal(position);
04771 }
04772 
04773 //-----------------------------------------------------------------------------
04774 // allocateCharacterJoints()
04775 //-----------------------------------------------------------------------------
04776 BOOL LLVOAvatar::allocateCharacterJoints( U32 num )
04777 {
04778         delete [] mSkeleton;
04779         mSkeleton = NULL;
04780         mNumJoints = 0;
04781 
04782         mSkeleton = new LLViewerJoint[num];
04783         
04784         for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
04785         {
04786                 mSkeleton[joint_num].setJointNum(joint_num);
04787         }
04788 
04789         if (!mSkeleton)
04790         {
04791                 return FALSE;
04792         }
04793 
04794         mNumJoints = num;
04795         return TRUE;
04796 }
04797 
04798 //-----------------------------------------------------------------------------
04799 // allocateCollisionVolumes()
04800 //-----------------------------------------------------------------------------
04801 BOOL LLVOAvatar::allocateCollisionVolumes( U32 num )
04802 {
04803         delete [] mCollisionVolumes;
04804         mCollisionVolumes = NULL;
04805         mNumCollisionVolumes = 0;
04806 
04807         mCollisionVolumes = new LLViewerJointCollisionVolume[num];
04808         if (!mCollisionVolumes)
04809         {
04810                 return FALSE;
04811         }
04812 
04813         mNumCollisionVolumes = num;
04814         return TRUE;
04815 }
04816 
04817 
04818 //-----------------------------------------------------------------------------
04819 // getCharacterJoint()
04820 //-----------------------------------------------------------------------------
04821 LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
04822 {
04823         if ((S32)num >= mNumJoints 
04824             || (S32)num < 0)
04825         {
04826                 return NULL;
04827         }
04828         return (LLJoint*)&mSkeleton[num];
04829 }
04830 
04831 //-----------------------------------------------------------------------------
04832 // requestStopMotion()
04833 //-----------------------------------------------------------------------------
04834 void LLVOAvatar::requestStopMotion( LLMotion* motion )
04835 {
04836         // Only agent avatars should handle the stop motion notifications.
04837         if ( mIsSelf )
04838         {
04839                 // Notify agent that motion has stopped
04840                 gAgent.requestStopMotion( motion );
04841         }
04842 }
04843 
04844 //-----------------------------------------------------------------------------
04845 // loadAvatar()
04846 //-----------------------------------------------------------------------------
04847 BOOL LLVOAvatar::loadAvatar()
04848 {
04849 //      LLFastTimer t(LLFastTimer::FTM_LOAD_AVATAR);
04850         
04851         // avatar_skeleton.xml
04852         if( !buildSkeleton(sSkeletonInfo) )
04853         {
04854                 llwarns << "avatar file: buildSkeleton() failed" << llendl;
04855                 return FALSE;
04856         }
04857 
04858         // avatar_lad.xml : <skeleton>
04859         if( !loadSkeletonNode() )
04860         {
04861                 llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
04862                 return FALSE;
04863         }
04864         
04865         // avatar_lad.xml : <mesh>
04866         if( !loadMeshNodes() )
04867         {
04868                 llwarns << "avatar file: loadNodeMesh() failed" << llendl;
04869                 return FALSE;
04870         }
04871         
04872         // avatar_lad.xml : <global_color>
04873         if( sAvatarInfo->mTexSkinColorInfo )
04874         {
04875                 mTexSkinColor = new LLTexGlobalColor( this );
04876                 if( !mTexSkinColor->setInfo( sAvatarInfo->mTexSkinColorInfo ) )
04877                 {
04878                         llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
04879                         return FALSE;
04880                 }
04881         }
04882         else
04883         {
04884                 llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
04885                 return FALSE;
04886         }
04887         if( sAvatarInfo->mTexHairColorInfo )
04888         {
04889                 mTexHairColor = new LLTexGlobalColor( this );
04890                 if( !mTexHairColor->setInfo( sAvatarInfo->mTexHairColorInfo ) )
04891                 {
04892                         llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
04893                         return FALSE;
04894                 }
04895         }
04896         else
04897         {
04898                 llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
04899                 return FALSE;
04900         }
04901         if( sAvatarInfo->mTexEyeColorInfo )
04902         {
04903                 mTexEyeColor = new LLTexGlobalColor( this );
04904                 if( !mTexEyeColor->setInfo( sAvatarInfo->mTexEyeColorInfo ) )
04905                 {
04906                         llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
04907                         return FALSE;
04908                 }
04909         }
04910         else
04911         {
04912                 llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
04913                 return FALSE;
04914         }
04915         
04916         // avatar_lad.xml : <layer_set>
04917         if (sAvatarInfo->mLayerInfoList.empty())
04918         {
04919                 llwarns << "avatar file: missing <layer_set> node" << llendl;
04920         }
04921         else
04922         {
04923                 LLVOAvatarInfo::layer_info_list_t::iterator iter;
04924                 for (iter = sAvatarInfo->mLayerInfoList.begin();
04925                          iter != sAvatarInfo->mLayerInfoList.end(); iter++)
04926                 {
04927                         LLTexLayerSetInfo *info = *iter;
04928                         LLTexLayerSet* layer_set = new LLTexLayerSet( this );
04929                         if (!layer_set->setInfo(info))
04930                         {
04931                                 stop_glerror();
04932                                 delete layer_set;
04933                                 llwarns << "avatar file: layer_set->parseData() failed" << llendl;
04934                                 return FALSE;
04935                         }
04936                         if( layer_set->isBodyRegion( "head" ) )
04937                         {
04938                                 mHeadLayerSet = layer_set;
04939                         }
04940                         else if( layer_set->isBodyRegion( "upper_body" ) )
04941                         {
04942                                 mUpperBodyLayerSet = layer_set;
04943                         }
04944                         else if( layer_set->isBodyRegion( "lower_body" ) )
04945                         {
04946                                 mLowerBodyLayerSet = layer_set;
04947                         }
04948                         else if( layer_set->isBodyRegion( "eyes" ) )
04949                         {
04950                                 mEyesLayerSet = layer_set;
04951                         }
04952                         else if( layer_set->isBodyRegion( "skirt" ) )
04953                         {
04954                                 mSkirtLayerSet = layer_set;
04955                         }
04956                         else
04957                         {
04958                                 llwarns << "<layer_set> has invalid body_region attribute" << llendl;
04959                                 delete layer_set;
04960                                 return FALSE;
04961                         }
04962                 }
04963         }
04964         
04965         // avatar_lad.xml : <driver_parameters>
04966         {
04967                 LLVOAvatarInfo::driver_info_list_t::iterator iter;
04968                 for (iter = sAvatarInfo->mDriverInfoList.begin();
04969                          iter != sAvatarInfo->mDriverInfoList.end(); iter++)
04970                 {
04971                         LLDriverParamInfo *info = *iter;
04972                         LLDriverParam* driver_param = new LLDriverParam( this );
04973                         if (driver_param->setInfo(info))
04974                         {
04975                                 addVisualParam( driver_param );
04976                         }
04977                         else
04978                         {
04979                                 delete driver_param;
04980                                 llwarns << "avatar file: driver_param->parseData() failed" << llendl;
04981                                 return FALSE;
04982                         }
04983                 }
04984         }
04985         
04986         return TRUE;
04987 }
04988 
04989 //-----------------------------------------------------------------------------
04990 // loadSkeletonNode(): loads <skeleton> node from XML tree
04991 //-----------------------------------------------------------------------------
04992 BOOL LLVOAvatar::loadSkeletonNode ()
04993 {
04994         mRoot.addChild( &mSkeleton[0] );
04995 
04996         mRoot.addChild( &mHeadLOD );
04997                 mHeadLOD.mUpdateXform = FALSE;
04998                 mHeadLOD.addChild( &mHeadMesh0 );
04999                 mHeadLOD.addChild( &mHeadMesh1 );
05000                 mHeadLOD.addChild( &mHeadMesh2 );
05001                 mHeadLOD.addChild( &mHeadMesh3 );
05002                 mHeadLOD.addChild( &mHeadMesh4 );
05003         
05004         mRoot.addChild( &mEyeLashLOD );
05005                 mEyeLashLOD.mUpdateXform = FALSE;
05006                 mEyeLashLOD.addChild( &mEyeLashMesh0 );
05007 
05008         mRoot.addChild( &mUpperBodyLOD );
05009                 mUpperBodyLOD.mUpdateXform = FALSE;
05010                 mUpperBodyLOD.addChild( &mUpperBodyMesh0 );
05011                 mUpperBodyLOD.addChild( &mUpperBodyMesh1 );
05012                 mUpperBodyLOD.addChild( &mUpperBodyMesh2 );
05013                 mUpperBodyLOD.addChild( &mUpperBodyMesh3 );
05014                 mUpperBodyLOD.addChild( &mUpperBodyMesh4 );
05015 
05016         mRoot.addChild( &mLowerBodyLOD );
05017                 mLowerBodyLOD.mUpdateXform = FALSE;
05018                 mLowerBodyLOD.addChild( &mLowerBodyMesh0 );
05019                 mLowerBodyLOD.addChild( &mLowerBodyMesh1 );
05020                 mLowerBodyLOD.addChild( &mLowerBodyMesh2 );
05021                 mLowerBodyLOD.addChild( &mLowerBodyMesh3 );
05022                 mLowerBodyLOD.addChild( &mLowerBodyMesh4 );
05023 
05024         mRoot.addChild( &mSkirtLOD );
05025                 mSkirtLOD.mUpdateXform = FALSE;
05026                 mSkirtLOD.addChild( &mSkirtMesh0 );
05027                 mSkirtLOD.addChild( &mSkirtMesh1 );
05028                 mSkirtLOD.addChild( &mSkirtMesh2 );
05029                 mSkirtLOD.addChild( &mSkirtMesh3 );
05030                 mSkirtLOD.addChild( &mSkirtMesh4 );
05031 
05032         LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull");
05033         if (skull)
05034         {
05035                 skull->addChild( &mHairLOD );
05036                         mHairLOD.mUpdateXform = FALSE;
05037                         mHairLOD.addChild( &mHairMesh0 );
05038                         mHairLOD.addChild( &mHairMesh1 );
05039                         mHairLOD.addChild( &mHairMesh2 );
05040                         mHairLOD.addChild( &mHairMesh3 );
05041                         mHairLOD.addChild( &mHairMesh4 );
05042                         mHairLOD.addChild( &mHairMesh5 );
05043         }
05044 
05045         LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
05046         if (eyeL)
05047         {
05048                 eyeL->addChild( &mEyeBallLeftLOD );
05049                         mEyeBallLeftLOD.mUpdateXform = FALSE;
05050                         mEyeBallLeftLOD.addChild( &mEyeBallLeftMesh0 );
05051                         mEyeBallLeftLOD.addChild( &mEyeBallLeftMesh1 );
05052         }
05053 
05054         LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight");
05055         if (eyeR)
05056         {
05057                 eyeR->addChild( &mEyeBallRightLOD );
05058                         mEyeBallRightLOD.mUpdateXform = FALSE;
05059                         mEyeBallRightLOD.addChild( &mEyeBallRightMesh0 );
05060                         mEyeBallRightLOD.addChild( &mEyeBallRightMesh1 );
05061         }
05062 
05063         // SKELETAL DISTORTIONS
05064         {
05065                 LLVOAvatarInfo::skeletal_distortion_info_list_t::iterator iter;
05066                 for (iter = sAvatarInfo->mSkeletalDistortionInfoList.begin();
05067                          iter != sAvatarInfo->mSkeletalDistortionInfoList.end(); iter++)
05068                 {
05069                         LLPolySkeletalDistortionInfo *info = *iter;
05070                         LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
05071                         if (!param->setInfo(info))
05072                         {
05073                                 delete param;
05074                                 return FALSE;
05075                         }
05076                         else
05077                         {
05078                                 addVisualParam(param);
05079                         }                               
05080                 }
05081         }
05082         
05083         // ATTACHMENTS
05084         {
05085                 LLVOAvatarInfo::attachment_info_list_t::iterator iter;
05086                 for (iter = sAvatarInfo->mAttachmentInfoList.begin();
05087                          iter != sAvatarInfo->mAttachmentInfoList.end(); iter++)
05088                 {
05089                         LLVOAvatarInfo::LLVOAvatarAttachmentInfo *info = *iter;
05090                         if (!isSelf() && info->mJointName == "mScreen")
05091                         { //don't process screen joint for other avatars
05092                                 continue;
05093                         }
05094 
05095                         LLViewerJointAttachment* attachment = new LLViewerJointAttachment();
05096 
05097                         attachment->setName(info->mName);
05098                         LLJoint *parentJoint = getJoint(info->mJointName);
05099                         if (!parentJoint)
05100                         {
05101                                 llwarns << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << llendl;
05102                                 delete attachment;
05103                                 continue;
05104                         }
05105 
05106                         if (info->mHasPosition)
05107                         {
05108                                 attachment->setOriginalPosition(info->mPosition);
05109                         }
05110 
05111                         if (info->mHasRotation)
05112                         {
05113                                 LLQuaternion rotation;
05114                                 rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD,
05115                                                                  info->mRotationEuler.mV[VY] * DEG_TO_RAD,
05116                                                                  info->mRotationEuler.mV[VZ] * DEG_TO_RAD);
05117                                 attachment->setRotation(rotation);
05118                         }
05119 
05120                         int group = info->mGroup;
05121                         if (group >= 0)
05122                         {
05123                                 if (group < 0 || group >= 9)
05124                                 {
05125                                         llwarns << "Invalid group number (" << group << ") for attachment point " << info->mName << llendl;
05126                                 }
05127                                 else
05128                                 {
05129                                         attachment->setGroup(group);
05130                                 }
05131                         }
05132 
05133                         S32 attachmentID = info->mAttachmentID;
05134                         if (attachmentID < 1 || attachmentID > 255)
05135                         {
05136                                 llwarns << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << llendl;
05137                                 delete attachment;
05138                                 continue;
05139                         }
05140                         if (mAttachmentPoints.checkData(attachmentID))
05141                         {
05142                                 llwarns << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << llendl;
05143                                 delete attachment;
05144                                 continue;
05145                         }
05146 
05147                         attachment->setPieSlice(info->mPieMenuSlice);
05148                         attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson);
05149                         attachment->setIsHUDAttachment(info->mIsHUDAttachment);
05150 
05151                         mAttachmentPoints[attachmentID] = attachment;
05152 
05153                         // now add attachment joint
05154                         parentJoint->addChild(attachment);
05155                 }
05156         }
05157 
05158         return TRUE;
05159 }
05160 
05161 //-----------------------------------------------------------------------------
05162 // loadMeshNodes(): loads <mesh> nodes from XML tree
05163 //-----------------------------------------------------------------------------
05164 BOOL LLVOAvatar::loadMeshNodes()
05165 {
05166         LLVOAvatarInfo::mesh_info_list_t::iterator iter;
05167         for (iter = sAvatarInfo->mMeshInfoList.begin();
05168                  iter != sAvatarInfo->mMeshInfoList.end(); iter++)
05169         {
05170                 LLVOAvatarInfo::LLVOAvatarMeshInfo *info = *iter;
05171                 LLString &type = info->mType;
05172                 S32 lod = info->mLOD;
05173 
05174                 LLViewerJointMesh* mesh = NULL;
05175                 if (type == "hairMesh")
05176                 {
05177                         switch (lod)
05178                         {
05179                           case 0:
05180                                 mesh = &mHairMesh0;
05181                                 break;
05182                           case 1:
05183                                 mesh = &mHairMesh1;
05184                                 break;
05185                           case 2:
05186                                 mesh = &mHairMesh2;
05187                                 break;
05188                           case 3:
05189                                 mesh = &mHairMesh3;
05190                                 break;
05191                           case 4:
05192                                 mesh = &mHairMesh4;
05193                                 break;
05194                           case 5:
05195                                 mesh = &mHairMesh5;
05196                                 break;
05197                           default:
05198                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05199                                 return FALSE;
05200                         }
05201                 }
05202                 else if (type == "headMesh")
05203                 {
05204                         switch (lod)
05205                         {
05206                           case 0:
05207                                 mesh = &mHeadMesh0;
05208                                 break;
05209                           case 1:
05210                                 mesh = &mHeadMesh1;
05211                                 break;
05212                           case 2:
05213                                 mesh = &mHeadMesh2;
05214                                 break;
05215                           case 3:
05216                                 mesh = &mHeadMesh3;
05217                                 break;
05218                           case 4:
05219                                 mesh = &mHeadMesh4;
05220                                 break;
05221                           default:
05222                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05223                                 return FALSE;
05224                         }
05225                 }
05226                 else if (type == "upperBodyMesh")
05227                 {
05228                         switch (lod)
05229                         {
05230                           case 0:
05231                                 mesh = &mUpperBodyMesh0;
05232                                 break;
05233                           case 1:
05234                                 mesh = &mUpperBodyMesh1;
05235                                 break;
05236                           case 2:
05237                                 mesh = &mUpperBodyMesh2;
05238                                 break;
05239                           case 3:
05240                                 mesh = &mUpperBodyMesh3;
05241                                 break;
05242                           case 4:
05243                                 mesh = &mUpperBodyMesh4;
05244                                 break;
05245                           default:
05246                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05247                                 return FALSE;
05248                         }
05249                 }
05250                 else if (type == "lowerBodyMesh")
05251                 {
05252                         switch (lod)
05253                         {
05254                           case 0:
05255                                 mesh = &mLowerBodyMesh0;
05256                                 break;
05257                           case 1:
05258                                 mesh = &mLowerBodyMesh1;
05259                                 break;
05260                           case 2:
05261                                 mesh = &mLowerBodyMesh2;
05262                                 break;
05263                           case 3:
05264                                 mesh = &mLowerBodyMesh3;
05265                                 break;
05266                           case 4:
05267                                 mesh = &mLowerBodyMesh4;
05268                                 break;
05269                           default:
05270                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05271                                 return FALSE;
05272                         }
05273                 }       
05274                 else if (type == "skirtMesh")
05275                 {
05276                         switch (lod)
05277                         {
05278                           case 0:
05279                                 mesh = &mSkirtMesh0;
05280                                 break;
05281                           case 1:
05282                                 mesh = &mSkirtMesh1;
05283                                 break;
05284                           case 2:
05285                                 mesh = &mSkirtMesh2;
05286                                 break;
05287                           case 3:
05288                                 mesh = &mSkirtMesh3;
05289                                 break;
05290                           case 4:
05291                                 mesh = &mSkirtMesh4;
05292                                 break;
05293                           default:
05294                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05295                                 return FALSE;
05296                         }
05297                 }
05298                 else if (type == "eyelashMesh")
05299                 {
05300                         mesh = &mEyeLashMesh0;
05301                 }
05302                 else if (type == "eyeBallLeftMesh")
05303                 {
05304                         switch (lod)
05305                         {
05306                           case 0:
05307                                 mesh = &mEyeBallLeftMesh0;
05308                                 break;
05309                           case 1:
05310                                 mesh = &mEyeBallLeftMesh1;
05311                                 break;
05312                           default:
05313                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05314                                 return FALSE;
05315                         }
05316                 }
05317                 else if (type == "eyeBallRightMesh")
05318                 {
05319                         switch (lod)
05320                         {
05321                           case 0:
05322                                 mesh = &mEyeBallRightMesh0;
05323                                 break;
05324                           case 1:
05325                                 mesh = &mEyeBallRightMesh1;
05326                                 break;
05327                           default:
05328                                 llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
05329                                 return FALSE;
05330                         }
05331                 }
05332 
05333                 if( !mesh )
05334                 {
05335                         llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
05336                         return FALSE;
05337                 }
05338 
05339                 //      llinfos << "Parsing mesh data for " << type << "..." << llendl;
05340 
05341                 mesh->setColor( 0.8f, 0.8f, 0.8f, 1.0f );
05342 
05343                 LLPolyMesh *poly_mesh = NULL;
05344 
05345                 if (!info->mReferenceMeshName.empty())
05346                 {
05347                         mesh_map_t::iterator iter = mMeshes.find(info->mReferenceMeshName);
05348                         if (iter != mMeshes.end())
05349                         {
05350                                 poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, iter->second);
05351                                 poly_mesh->setAvatar(this);
05352                         }
05353                         else
05354                         {
05355                                 // This should never happen
05356                         }
05357                 }
05358                 else
05359                 {
05360                         poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
05361                         poly_mesh->setAvatar(this);
05362                 }
05363 
05364                 if( !poly_mesh )
05365                 {
05366                         llwarns << "Failed to load mesh of type " << type << llendl;
05367                         return FALSE;
05368                 }
05369 
05370                 // Multimap insert
05371                 mMeshes.insert(std::pair<LLString, LLPolyMesh*>(info->mMeshFileName, poly_mesh));
05372         
05373                 mesh->setMesh( poly_mesh );
05374 
05375                 mesh->setLOD( info->mMinPixelArea );
05376 
05377                 LLVOAvatarInfo::LLVOAvatarMeshInfo::morph_info_list_t::iterator iter;
05378                 for (iter = info->mPolyMorphTargetInfoList.begin();
05379                          iter != info->mPolyMorphTargetInfoList.end(); iter++)
05380                 {
05381                         LLVOAvatarInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*iter);
05382                         LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
05383                         if (!param->setInfo(info_pair->first))
05384                         {
05385                                 delete param;
05386                                 return FALSE;
05387                         }
05388                         else
05389                         {
05390                                 if (info_pair->second)
05391                                 {
05392                                         addSharedVisualParam(param);
05393                                 }
05394                                 else
05395                                 {
05396                                         addVisualParam(param);
05397                                 }
05398                         }                               
05399                 }
05400         }
05401 
05402         return TRUE;
05403 }
05404 
05405 //-----------------------------------------------------------------------------
05406 // updateVisualParams()
05407 //-----------------------------------------------------------------------------
05408 void LLVOAvatar::updateVisualParams()
05409 {
05410         if (gNoRender)
05411         {
05412                 return;
05413         }
05414 
05415         setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
05416 
05417         LLCharacter::updateVisualParams();
05418 
05419         if (mLastSkeletonSerialNum != mSkeletonSerialNum)
05420         {
05421                 computeBodySize();
05422                 mLastSkeletonSerialNum = mSkeletonSerialNum;
05423                 mRoot.updateWorldMatrixChildren();
05424         }
05425 
05426         dirtyMesh();
05427         updateHeadOffset();
05428 }
05429 
05430 //-----------------------------------------------------------------------------
05431 // isActive()
05432 //-----------------------------------------------------------------------------
05433 BOOL LLVOAvatar::isActive() const
05434 {
05435         return TRUE;
05436 }
05437 
05438 //-----------------------------------------------------------------------------
05439 // setPixelAreaAndAngle()
05440 //-----------------------------------------------------------------------------
05441 void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
05442 {
05443         LLMemType mt(LLMemType::MTYPE_AVATAR);
05444                 
05445         F32 max_scale = getMaxScale();
05446         F32 mid_scale = getMidScale();
05447         F32 min_scale = llmin( getScale().mV[VX], llmin( getScale().mV[VY], getScale().mV[VZ] ) );
05448 
05449         // IW: esitmate - when close to large objects, computing range based on distance from center is no good
05450         // to try to get a min distance from face, subtract min_scale/2 from the range.
05451         // This means we'll load too much detail sometimes, but that's better than not enough
05452         // I don't think there's a better way to do this without calculating distance per-poly
05453         F32 range = (getRenderPosition()-gCamera->getOrigin()).magVec() - min_scale/2;
05454 
05455         if (range < 0.001f)             // range == zero
05456         {
05457                 mAppAngle = 180.f;
05458                 mPixelArea =    gCamera->getViewHeightInPixels() * 
05459                                                 gCamera->getViewHeightInPixels() *  
05460                                                 gCamera->getAspect();
05461         }
05462         else
05463         {
05464                 mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG;
05465 
05466                 F32 pixels_per_meter = gCamera->getPixelMeterRatio() / range;
05467 
05468                 mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale);
05469 //              if( !mIsSelf )
05470 //              {
05471 //                      llinfos << "range " << range << llendl;
05472 //                      llinfos << "pixels_per_meter " << pixels_per_meter << llendl;
05473 //                      llinfos << "scale " << max_scale << "x" << mid_scale << llendl;
05474 //                      llinfos << "pixel area " << mPixelArea << llendl;
05475 //              }
05476         }
05477 
05478         // We always want to look good to ourselves
05479         if( mIsSelf )
05480         {
05481                 mPixelArea = llmax( mPixelArea, F32(LOCTEX_IMAGE_SIZE_SELF / 16) );
05482         }
05483 }
05484 
05485 //-----------------------------------------------------------------------------
05486 // updateJointLODs()
05487 //-----------------------------------------------------------------------------
05488 BOOL LLVOAvatar::updateJointLODs()
05489 {
05490         F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE));
05491         F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f);
05492         F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
05493         {
05494                 if (mIsSelf)
05495                 {
05496                         if(gAgent.cameraCustomizeAvatar() || gAgent.cameraMouselook())
05497                         {
05498                                 mAdjustedPixelArea = 1000000;
05499                         }
05500                         else
05501                         {
05502                                 mAdjustedPixelArea = mPixelArea;
05503                         }
05504                 }
05505                 else if (mIsDummy)
05506                 {
05507                         mAdjustedPixelArea = 1000000;
05508                 }
05509                 else
05510                 {
05511                         // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
05512                         mAdjustedPixelArea = (F32)mPixelArea * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
05513                 }
05514 
05515                 // now select meshes to render based on adjusted pixel area
05516                 BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
05517                 if (res)
05518                 {
05519                         sNumLODChangesThisFrame++;
05520                         dirtyMesh();
05521                         return TRUE;
05522                 }
05523         }
05524 
05525         return FALSE;
05526 }
05527 
05528 //-----------------------------------------------------------------------------
05529 // createDrawable()
05530 //-----------------------------------------------------------------------------
05531 LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
05532 {
05533         pipeline->allocDrawable(this);
05534         mDrawable->setLit(FALSE);
05535 
05536         LLDrawPoolAvatar *poolp = (LLDrawPoolAvatar*) gPipeline.getPool(LLDrawPool::POOL_AVATAR);
05537 
05538         // Only a single face (one per avatar)
05539         mDrawable->setState(LLDrawable::ACTIVE);
05540         mDrawable->addFace(poolp, NULL);
05541         mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
05542         
05543         LLFace *facep;
05544 
05545         // Add faces for the foot shadows
05546         facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
05547         mShadow0Facep = facep;
05548 
05549         facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
05550         mShadow1Facep = facep;
05551 
05552         dirtyMesh();
05553         return mDrawable;
05554 }
05555 
05556 
05557 //-----------------------------------------------------------------------------
05558 // updateGeometry()
05559 //-----------------------------------------------------------------------------
05560 BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
05561 {
05562         LLFastTimer ftm(LLFastTimer::FTM_UPDATE_AVATAR);
05563         if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
05564         {
05565                 return TRUE;
05566         }
05567         
05568         if (!mMeshValid)
05569         {
05570                 return TRUE;
05571         }
05572 
05573         if (!drawable)
05574         {
05575                 llerrs << "LLVOAvatar::updateGeometry() called with NULL drawable" << llendl;
05576         }
05577 
05578         return TRUE;
05579 }
05580 
05581 //-----------------------------------------------------------------------------
05582 // updateShadowFaces()
05583 //-----------------------------------------------------------------------------
05584 void LLVOAvatar::updateShadowFaces()
05585 {
05586         LLFace *face0p = mShadow0Facep;
05587         LLFace *face1p = mShadow1Facep;
05588         //
05589         // render avatar shadows
05590         //
05591         if (mInAir)
05592         {
05593                 face0p->setSize(0, 0);
05594                 face1p->setSize(0, 0);
05595                 return;
05596         }
05597 
05598         LLSprite sprite(mShadowImageID);
05599         sprite.setFollow(FALSE);
05600         const F32 cos_angle = gSky.getSunDirection().mV[2];
05601         F32 cos_elev = sqrt(1 - cos_angle * cos_angle);
05602         if (cos_angle < 0) cos_elev = -cos_elev;
05603         sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f);
05604         LLVector3 sun_vec = gSky.mVOSkyp->getToSun();
05605 
05606         if (mShadowImagep->getHasGLTexture())
05607         {
05608                 LLVector3 normal;
05609                 LLVector3d shadow_pos;
05610                 LLVector3 shadow_pos_agent;
05611                 F32 foot_height;
05612 
05613                 if (mFootLeftp)
05614                 {
05615                         LLVector3 joint_world_pos = mFootLeftp->getWorldPosition();
05616                         // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
05617                         // but we make an explicit ray trace call in expectation of future improvements
05618                         resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), 
05619                                 gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
05620                         shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
05621                         foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
05622 
05623                         // Pull sprite in direction of surface normal
05624                         shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
05625 
05626                         // Render sprite
05627                         sprite.setNormal(normal);
05628                         if (mIsSelf && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
05629                         {
05630                                 sprite.setColor(0.f, 0.f, 0.f, 0.f);
05631                         }
05632                         else
05633                         {
05634                                 sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
05635                         }
05636                         sprite.setPosition(shadow_pos_agent);
05637 
05638                         LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos;
05639                         //foot_to_knee.normVec();
05640                         foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
05641                         sprite.setYaw(azimuth(sun_vec - foot_to_knee));
05642                 
05643                         sprite.updateFace(*face0p);
05644                 }
05645 
05646                 if (mFootRightp)
05647                 {
05648                         LLVector3 joint_world_pos = mFootRightp->getWorldPosition();
05649                         // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
05650                         // but we make an explicit ray trace call in expectation of future improvements
05651                         resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), 
05652                                 gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
05653                         shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
05654                         foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
05655 
05656                         // Pull sprite in direction of surface normal
05657                         shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
05658 
05659                         // Render sprite
05660                         sprite.setNormal(normal);
05661                         if (mIsSelf && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK)
05662                         {
05663                                 sprite.setColor(0.f, 0.f, 0.f, 0.f);
05664                         }
05665                         else
05666                         {
05667                                 sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
05668                         }
05669                         sprite.setPosition(shadow_pos_agent);
05670 
05671                         LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos;
05672                         //foot_to_knee.normVec();
05673                         foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
05674                         sprite.setYaw(azimuth(sun_vec - foot_to_knee));
05675         
05676                         sprite.updateFace(*face1p);
05677                 }
05678         }
05679 }
05680 
05681 //-----------------------------------------------------------------------------
05682 // updateSexDependentLayerSets()
05683 //-----------------------------------------------------------------------------
05684 void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user )
05685 {
05686         invalidateComposite( mHeadLayerSet,                     set_by_user );
05687         invalidateComposite( mLowerBodyLayerSet,        set_by_user );
05688         invalidateComposite( mUpperBodyLayerSet,        set_by_user );
05689         updateMeshTextures();
05690 }
05691 
05692 //-----------------------------------------------------------------------------
05693 // dirtyMesh()
05694 //-----------------------------------------------------------------------------
05695 void LLVOAvatar::dirtyMesh()
05696 {
05697         mDirtyMesh = TRUE;
05698 }
05699 
05700 //-----------------------------------------------------------------------------
05701 // requestLayerSetUpdate()
05702 //-----------------------------------------------------------------------------
05703 void LLVOAvatar::requestLayerSetUpdate( LLVOAvatar::ELocTexIndex i )
05704 {
05705         switch( i )
05706         {
05707         case LOCTEX_HEAD_BODYPAINT:
05708                 if( mHeadLayerSet )
05709                 {
05710                         mHeadLayerSet->requestUpdate();
05711                 }
05712                 break;
05713 
05714         case LOCTEX_UPPER_BODYPAINT:  
05715         case LOCTEX_UPPER_SHIRT:
05716         case LOCTEX_UPPER_GLOVES:
05717         case LOCTEX_UPPER_UNDERSHIRT:
05718                 if( mUpperBodyLayerSet )
05719                 {
05720                         mUpperBodyLayerSet->requestUpdate();
05721                 }
05722                 break;
05723 
05724         case LOCTEX_LOWER_BODYPAINT:  
05725         case LOCTEX_LOWER_PANTS:
05726         case LOCTEX_LOWER_SHOES:
05727         case LOCTEX_LOWER_SOCKS:
05728         case LOCTEX_LOWER_UNDERPANTS:
05729                 if( mLowerBodyLayerSet )
05730                 {
05731                         mLowerBodyLayerSet->requestUpdate();
05732                 }
05733                 break;
05734 
05735         case LOCTEX_EYES_IRIS:
05736                 if( mEyesLayerSet )
05737                 {
05738                         mEyesLayerSet->requestUpdate();
05739                 }
05740                 break;
05741 
05742 
05743         case LOCTEX_SKIRT:
05744                 if( mSkirtLayerSet )
05745                 {
05746                         mSkirtLayerSet->requestUpdate();
05747                 }
05748                 break;
05749 
05750 
05751         case LOCTEX_UPPER_JACKET:
05752         case LOCTEX_LOWER_JACKET:
05753                 if( mUpperBodyLayerSet )
05754                 {
05755                         mUpperBodyLayerSet->requestUpdate();
05756                 }
05757 
05758                 if( mLowerBodyLayerSet )
05759                 {
05760                         mLowerBodyLayerSet->requestUpdate();
05761                 }
05762                 break;
05763 
05764         case LOCTEX_NUM_ENTRIES:
05765                 llerrs << "Bogus texture value " << i << llendl;
05766                 break;
05767         }
05768 
05769 }
05770 
05771 void LLVOAvatar::setParent(LLViewerObject* parent)
05772 {
05773         if (parent == NULL)
05774         {
05775                 getOffObject();
05776                 LLViewerObject::setParent(parent);
05777                 if (isSelf())
05778                 {
05779                         gAgent.resetCamera();
05780                 }
05781         }
05782         else
05783         {
05784                 LLViewerObject::setParent(parent);
05785                 sitOnObject(parent);
05786         }
05787 }
05788 
05789 void LLVOAvatar::addChild(LLViewerObject *childp)
05790 {
05791         LLViewerObject::addChild(childp);
05792         attachObject(childp);
05793 }
05794 
05795 void LLVOAvatar::removeChild(LLViewerObject *childp)
05796 {
05797         LLViewerObject::removeChild(childp);
05798         detachObject(childp);
05799 }
05800 
05801 LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* viewer_object)
05802 {
05803         S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState());
05804 
05805         LLViewerJointAttachment* attachment = mAttachmentPoints.getIfThere(attachmentID);
05806 
05807         if (!attachment)
05808         {
05809                 llwarns << "Object attachment point invalid: " << attachmentID << llendl;
05810         }
05811 
05812         return attachment;
05813 }
05814 
05815 //-----------------------------------------------------------------------------
05816 // attachObject()
05817 //-----------------------------------------------------------------------------
05818 BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object)
05819 {
05820         LLViewerJointAttachment* attachment = getTargetAttachmentPoint(viewer_object);
05821 
05822         if (!attachment || !attachment->addObject(viewer_object))
05823         {
05824                 return FALSE;
05825         }
05826 
05827         if (viewer_object->isSelected())
05828         {
05829                 gSelectMgr->updateSelectionCenter();
05830                 gSelectMgr->updatePointAt();
05831         }
05832 
05833         if (mIsSelf)
05834         {
05835                 updateAttachmentVisibility(gAgent.getCameraMode());
05836                 
05837                 // Then make sure the inventory is in sync with the avatar.
05838                 gInventory.addChangedMask( LLInventoryObserver::LABEL, attachment->getItemID() );
05839                 gInventory.notifyObservers();
05840         }
05841 
05842         return TRUE;
05843 }
05844 
05845 //-----------------------------------------------------------------------------
05846 // lazyAttach()
05847 //-----------------------------------------------------------------------------
05848 void LLVOAvatar::lazyAttach()
05849 {
05850         for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData();
05851                 attachment;
05852                 attachment = mAttachmentPoints.getNextData())
05853                 {
05854                         if (attachment->getAttachmentDirty())
05855                         {
05856                                 attachment->lazyAttach();
05857                                 if (mIsSelf)
05858                                 {
05859                                         updateAttachmentVisibility(gAgent.getCameraMode());
05860                                 }
05861                         }
05862                 }
05863 }
05864 
05865 void LLVOAvatar::resetHUDAttachments()
05866 {
05867         for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData();
05868                 attachment;
05869                 attachment = mAttachmentPoints.getNextData())
05870         {
05871                 if (attachment->getIsHUDAttachment())
05872                 {
05873                         LLViewerObject* obj = attachment->getObject();
05874                         if (obj && obj->mDrawable.notNull())
05875                         {
05876                                 gPipeline.markMoved(obj->mDrawable);
05877                         }
05878                 }
05879         }
05880 }
05881 
05882 //-----------------------------------------------------------------------------
05883 // detachObject()
05884 //-----------------------------------------------------------------------------
05885 BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object)
05886 {
05887         for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData();
05888                 attachment;
05889                 attachment = mAttachmentPoints.getNextData())
05890         {
05891                 // only one object per attachment point for now
05892                 if (attachment->getObject() == viewer_object)
05893                 {
05894                         LLUUID item_id = attachment->getItemID();
05895                         attachment->removeObject(viewer_object);
05896                         if (mIsSelf)
05897                         {
05898                                 // the simulator should automatically handle
05899                                 // permissiosn revokation
05900 
05901                                 stopMotionFromSource(viewer_object->getID());
05902                                 LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE);
05903 
05904                                 for (S32 i = 0; i < (S32)viewer_object->mChildList.size(); i++)
05905                                 {
05906                                         LLViewerObject* child_objectp = viewer_object->mChildList[i];
05907                                         // the simulator should automatically handle
05908                                         // permissions revokation
05909 
05910                                         stopMotionFromSource(child_objectp->getID());
05911                                         LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE);
05912                                 }
05913 
05914                         }
05915                         lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl;
05916                         if (mIsSelf)
05917                         {
05918                                 // Then make sure the inventory is in sync with the avatar.
05919                                 gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
05920                                 gInventory.notifyObservers();
05921                         }
05922                         return TRUE;
05923                 }
05924         }
05925 
05926         
05927         return FALSE;
05928 }
05929 
05930 //-----------------------------------------------------------------------------
05931 // sitOnObject()
05932 //-----------------------------------------------------------------------------
05933 void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
05934 {
05935         if (mDrawable.isNull())
05936         {
05937                 return;
05938         }
05939         LLQuaternion inv_obj_rot = ~sit_object->getRenderRotation();
05940         LLVector3 obj_pos = sit_object->getRenderPosition();
05941 
05942         LLVector3 rel_pos = getRenderPosition() - obj_pos;
05943         rel_pos.rotVec(inv_obj_rot);
05944 
05945         mDrawable->mXform.setPosition(rel_pos);
05946         mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot);
05947 
05948         gPipeline.markMoved(mDrawable, TRUE);
05949         mIsSitting = TRUE;
05950         mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
05951         mRoot.setPosition(getPosition());
05952         mRoot.updateWorldMatrixChildren();
05953 
05954         stopMotion(ANIM_AGENT_BODY_NOISE);
05955 
05956         if (mIsSelf)
05957         {
05958                 // Might be first sit
05959                 LLFirstUse::useSit();
05960 
05961                 gAgent.setFlying(FALSE);
05962                 gAgent.setThirdPersonHeadOffset(LLVector3::zero);
05963                 //interpolate to new camera position
05964                 gAgent.startCameraAnimation();
05965                 // make sure we are not trying to autopilot
05966                 gAgent.stopAutoPilot();
05967                 gAgent.setupSitCamera();
05968                 if (gAgent.mForceMouselook) gAgent.changeCameraToMouselook();
05969         }
05970 }
05971 
05972 //-----------------------------------------------------------------------------
05973 // getOffObject()
05974 //-----------------------------------------------------------------------------
05975 void LLVOAvatar::getOffObject()
05976 {
05977         if (mDrawable.isNull())
05978         {
05979                 return;
05980         }
05981         
05982         LLViewerObject* sit_object = (LLViewerObject*)getParent();
05983 
05984         if (sit_object) 
05985         {
05986                 stopMotionFromSource(sit_object->getID());
05987                 LLFollowCamMgr::setCameraActive(sit_object->getID(), FALSE);
05988 
05989                 for (S32 i = 0; i < (S32)sit_object->mChildList.size(); i++)
05990                 {
05991                         LLViewerObject* child_objectp = sit_object->mChildList[i];
05992 
05993                         stopMotionFromSource(child_objectp->getID());
05994                         LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE);
05995                 }
05996         }
05997 
05998         // assumes that transform will not be updated with drawable still having a parent
05999         LLVector3 cur_position_world = mDrawable->getWorldPosition();
06000         LLQuaternion cur_rotation_world = mDrawable->getWorldRotation();
06001 
06002         // set *local* position based on last *world* position, since we're unparenting the avatar
06003         mDrawable->mXform.setPosition(cur_position_world);
06004         mDrawable->mXform.setRotation(cur_rotation_world);
06005 
06006         gPipeline.markMoved(mDrawable, TRUE);
06007 
06008         mIsSitting = FALSE;
06009         mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject
06010         mRoot.setPosition(cur_position_world);
06011         mRoot.setRotation(cur_rotation_world);
06012         mRoot.getXform()->update();
06013 
06014         startMotion(ANIM_AGENT_BODY_NOISE);
06015 
06016         if (mIsSelf)
06017         {
06018                 LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion();
06019                 LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT;
06020                 av_rot = av_rot * obj_rot;
06021                 LLVector3 at_axis = LLVector3::x_axis;
06022                 at_axis = at_axis * av_rot;
06023                 at_axis.mV[VZ] = 0.f;
06024                 at_axis.normVec();
06025                 gAgent.resetAxes(at_axis);
06026 
06027                 //reset orientation
06028 //              mRoot.setRotation(avWorldRot);
06029                 gAgent.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
06030 
06031                 gAgent.setSitCamera(LLUUID::null);
06032         }
06033 }
06034 
06035 //-----------------------------------------------------------------------------
06036 // findAvatarFromAttachment()
06037 //-----------------------------------------------------------------------------
06038 // static 
06039 LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj )
06040 {
06041         if( obj->isAttachment() )
06042         {
06043                 do
06044                 {
06045                         obj = (LLViewerObject*) obj->getParent();
06046                 }
06047                 while( obj && !obj->isAvatar() );
06048 
06049                 if( obj && !obj->isDead() )
06050                 {
06051                         return (LLVOAvatar*)obj;
06052                 }
06053         }
06054         return NULL;
06055 }
06056 
06057 //-----------------------------------------------------------------------------
06058 // isWearingAttachment()
06059 //-----------------------------------------------------------------------------
06060 BOOL LLVOAvatar::isWearingAttachment( const LLUUID& inv_item_id )
06061 {
06062         for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData();
06063                 attachment_point;
06064                 attachment_point = mAttachmentPoints.getNextData())
06065         {
06066                 if( attachment_point->getItemID() == inv_item_id )
06067                 {
06068                         return TRUE;
06069                 }
06070         }
06071         return FALSE;
06072 }
06073 
06074 //-----------------------------------------------------------------------------
06075 // getWornAttachment()
06076 //-----------------------------------------------------------------------------
06077 LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id )
06078 {
06079         for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData();
06080                 attachment_point;
06081                 attachment_point = mAttachmentPoints.getNextData())
06082         {
06083                 if( attachment_point->getItemID() == inv_item_id )
06084                 {
06085                         return attachment_point->getObject();
06086                 }
06087         }
06088         return NULL;
06089 }
06090 
06091 const LLString LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id)
06092 {
06093         for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData();
06094                 attachment_point;
06095                 attachment_point = mAttachmentPoints.getNextData())
06096         {
06097                 if( attachment_point->getItemID() == inv_item_id )
06098                 {
06099                         return (LLString)attachment_point->getName();
06100                 }
06101         }
06102 
06103         return LLString::null;
06104 }
06105 
06106 
06107 //-----------------------------------------------------------------------------
06108 // static 
06109 // onLocalTextureLoaded()
06110 //-----------------------------------------------------------------------------
06111 void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
06112 {
06113         //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl;
06114 
06115         const LLUUID& src_id = src_vi->getID();
06116         LLAvatarTexData *data = (LLAvatarTexData *)userdata;
06117         if (success)
06118         {
06119                 LLVOAvatar *self = (LLVOAvatar *)gObjectList.findObject(data->mAvatarID);
06120                 LLVOAvatar::ELocTexIndex idx = data->mIndex;
06121                 if( self &&
06122                         (!self->mLocalTextureBaked[ idx ]) &&
06123                         (self->mLocalTexture[ idx ].notNull()) &&
06124                         (self->mLocalTexture[ idx ]->getID() == src_id) &&
06125                         (discard_level < self->mLocalTextureDiscard[idx]))
06126                 {
06127                         self->mLocalTextureDiscard[idx] = discard_level;
06128                         self->requestLayerSetUpdate( idx );
06129                         if( self->mIsSelf && gAgent.cameraCustomizeAvatar() )
06130                         {
06131                                 LLVisualParamHint::requestHintUpdates();
06132                         }
06133                         self->updateMeshTextures();
06134                 }
06135         }
06136 
06137         if( final || !success )
06138         {
06139                 delete data;
06140         }
06141 }
06142 
06143 void LLVOAvatar::updateComposites()
06144 {
06145         if( mHeadLayerSet )
06146         {
06147                 mHeadLayerSet->updateComposite();
06148         }
06149 
06150         if( mUpperBodyLayerSet )
06151         {
06152                 mUpperBodyLayerSet->updateComposite();
06153         }
06154 
06155         if( mLowerBodyLayerSet )
06156         {
06157                 mLowerBodyLayerSet->updateComposite();
06158         }
06159 
06160         if( mEyesLayerSet )
06161         {
06162                 mEyesLayerSet->updateComposite();
06163         }
06164 
06165         if( mSkirtLayerSet && isWearingWearableType( WT_SKIRT ))
06166         {
06167                 mSkirtLayerSet->updateComposite();
06168         }
06169 }
06170 
06171 LLColor4 LLVOAvatar::getGlobalColor( const LLString& color_name )
06172 {
06173         if( color_name=="skin_color" && mTexSkinColor )
06174         {
06175                 return mTexSkinColor->getColor();
06176         }
06177         else
06178         if( color_name=="hair_color" && mTexHairColor )
06179         {
06180                 return mTexHairColor->getColor();
06181         }
06182         if( color_name=="eye_color" && mTexEyeColor )
06183         {
06184                 return mTexEyeColor->getColor();
06185         }
06186         else
06187         {
06188 //              return LLColor4( .5f, .5f, .5f, .5f );
06189                 return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
06190         }
06191 }
06192 
06193 
06194 void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user )
06195 {
06196         if( !layerset || !layerset->getUpdatesEnabled() )
06197         {
06198                 return;
06199         }
06200 
06201         /* Debug spam. JC
06202         const char* layer_name = "";
06203         if (layerset == mHeadLayerSet)
06204         {
06205                 layer_name = "head";
06206         }
06207         else if (layerset == mUpperBodyLayerSet)
06208         {
06209                 layer_name = "upperbody";
06210         }
06211         else if (layerset == mLowerBodyLayerSet)
06212         {
06213                 layer_name = "lowerbody";
06214         }
06215         else if (layerset == mEyesLayerSet)
06216         {
06217                 layer_name = "eyes";
06218         }
06219         else if (layerset == mSkirtLayerSet)
06220         {
06221                 layer_name = "skirt";
06222         }
06223         else
06224         {
06225                 layer_name = "unknown";
06226         }
06227         llinfos << "LLVOAvatar::invalidComposite() " << layer_name << llendl;
06228         */
06229 
06230         layerset->requestUpdate();
06231 
06232         if( set_by_user )
06233         {
06234                 llassert( mIsSelf );
06235 
06236                 ETextureIndex baked_te = getBakedTE( layerset );
06237                 if( gAgent.cameraCustomizeAvatar() )
06238                 {
06239                         mSavedTE[ baked_te ].setNull();  
06240                 }
06241                 else
06242                 {
06243                         setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) );
06244                         layerset->requestUpload();
06245                 }
06246         }
06247 }
06248 
06249 
06250 void LLVOAvatar::onGlobalColorChanged( LLTexGlobalColor* global_color, BOOL set_by_user )
06251 {
06252         if( global_color == mTexSkinColor )
06253         {
06254 //              llinfos << "invalidateComposite cause: onGlobalColorChanged( skin color )" << llendl; 
06255                 invalidateComposite( mHeadLayerSet,                     set_by_user );
06256                 invalidateComposite( mUpperBodyLayerSet,        set_by_user );
06257                 invalidateComposite( mLowerBodyLayerSet,        set_by_user );
06258         }
06259         else
06260         if( global_color == mTexHairColor )
06261         {
06262 //              llinfos << "invalidateComposite cause: onGlobalColorChanged( hair color )" << llendl; 
06263                 invalidateComposite( mHeadLayerSet, set_by_user );
06264 
06265                 LLColor4 color = mTexHairColor->getColor();
06266                 mHairMesh0.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
06267                 mHairMesh1.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
06268                 mHairMesh2.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
06269                 mHairMesh3.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
06270                 mHairMesh4.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
06271                 mHairMesh5.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
06272         }
06273         else
06274         if( global_color == mTexEyeColor )
06275         {
06276 //              llinfos << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << llendl; 
06277                 invalidateComposite( mEyesLayerSet, set_by_user );
06278         }
06279         updateMeshTextures();
06280 }
06281 
06282 void LLVOAvatar::forceBakeAllTextures(bool slam_for_debug)
06283 {
06284         llinfos << "TAT: forced full rebake. " << llendl;
06285 
06286         for (S32 i = 0; i < BAKED_TEXTURE_COUNT; i++)
06287         {
06288                 ETextureIndex baked_index = sBakedTextureIndices[i];
06289                 LLTexLayerSet* layer_set = getLayerSet(baked_index);
06290                 if (layer_set)
06291                 {
06292                         if (slam_for_debug)
06293                         {
06294                                 layer_set->setUpdatesEnabled(TRUE);
06295                                 layer_set->cancelUpload();
06296                         }
06297 
06298                         BOOL set_by_user = TRUE;
06299                         invalidateComposite(layer_set, set_by_user);
06300                         gViewerStats->incStat(LLViewerStats::ST_TEX_REBAKES);
06301                 }
06302                 else
06303                 {
06304                         llwarns << "TAT: NO LAYER SET FOR " << (S32)baked_index << llendl;
06305                 }
06306         }
06307 
06308         // Don't know if this is needed
06309         updateMeshTextures();
06310 }
06311 
06312 
06313 // static
06314 void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
06315 {
06316         LLUUID texture_id;
06317         msg->getUUID("TextureData", "TextureID", texture_id);
06318 
06319         LLVOAvatar* self = gAgent.getAvatarObject();
06320         if (!self) return;
06321 
06322         // If this is a texture corresponding to one of our baked entries, 
06323         // just rebake that layer set.
06324         BOOL found = FALSE;
06325         for (S32 i = 0; i < BAKED_TEXTURE_COUNT; i++)
06326         {
06327                 ETextureIndex baked_index = sBakedTextureIndices[i];
06328                 if (texture_id == self->getTEImage(baked_index)->getID())
06329                 {
06330                         LLTexLayerSet* layer_set = self->getLayerSet(baked_index);
06331                         if (layer_set)
06332                         {
06333                                 llinfos << "TAT: rebake - matched entry " << (S32)baked_index << llendl;
06334                                 // Apparently set_by_user == force upload
06335                                 BOOL set_by_user = TRUE;
06336                                 self->invalidateComposite(layer_set, set_by_user);
06337                                 found = TRUE;
06338                                 gViewerStats->incStat(LLViewerStats::ST_TEX_REBAKES);
06339                         }
06340                 }
06341         }
06342 
06343         // If texture not found, rebake all entries.
06344         if (!found)
06345         {
06346                 self->forceBakeAllTextures();
06347         }
06348         else
06349         {
06350                 // Not sure if this is necessary, but forceBakeAllTextures() does it.
06351                 self->updateMeshTextures();
06352         }
06353 }
06354 
06355 
06356 BOOL LLVOAvatar::getLocalTextureRaw(S32 index, LLImageRaw* image_raw)
06357 {
06358     BOOL success = FALSE;
06359 
06360         if( (0 <= index) && (index < LOCTEX_NUM_ENTRIES) )
06361         {
06362                 if (mLocalTexture[ index ].isNull() || mLocalTexture[ index ]->getID() == IMG_DEFAULT_AVATAR )
06363                 {
06364                         success = TRUE;
06365                 }
06366                 else
06367                 {
06368                         if( mLocalTexture[ index ]->readBackRaw(-1, image_raw, false) )
06369                         {
06370                                 success = TRUE;
06371                         }
06372                         else
06373                         {
06374                                 // No data loaded yet
06375                                 setLocalTexture( (ELocTexIndex)index, getTEImage( index ), FALSE );
06376                         }
06377                 }
06378         }
06379         return success;
06380 }
06381 
06382 BOOL LLVOAvatar::getLocalTextureGL(S32 index, LLImageGL** image_gl_pp)
06383 {
06384         BOOL success = FALSE;
06385         *image_gl_pp = NULL;
06386 
06387         if( (0 <= index) && (index < LOCTEX_NUM_ENTRIES) )
06388         {
06389                 if( mLocalTexture[ index ].isNull() || mLocalTexture[ index ]->getID() == IMG_DEFAULT_AVATAR)
06390                 {
06391                         success = TRUE;
06392                 }
06393                 else
06394                 {
06395                         *image_gl_pp = mLocalTexture[ index ];
06396                         success = TRUE;
06397                 }
06398         }
06399 
06400         if( !success )
06401         {
06402 //              llinfos << "getLocalTextureGL(" << index << ") had no data" << llendl;
06403         }
06404         return success;
06405 }
06406 
06407 const LLUUID& LLVOAvatar::getLocalTextureID( S32 index )
06408 {
06409         if (index >= 0 && mLocalTexture[index].notNull())
06410         {
06411                 return mLocalTexture[index]->getID();
06412         }
06413         else
06414         {
06415                 return IMG_DEFAULT_AVATAR;
06416         }
06417 }
06418 
06419 // static
06420 void LLVOAvatar::dumpTotalLocalTextureByteCount()
06421 {
06422         S32 total_gl_bytes = 0;
06423         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
06424                 iter != LLCharacter::sInstances.end(); ++iter)
06425         {
06426                 LLVOAvatar* cur = (LLVOAvatar*) *iter;
06427                 S32 gl_bytes = 0;
06428                 cur->getLocalTextureByteCount(&gl_bytes );
06429                 total_gl_bytes += gl_bytes;
06430         }
06431         llinfos << "Total Avatar LocTex GL:" << (total_gl_bytes/1024) << "KB" << llendl;
06432 }
06433 
06434 BOOL LLVOAvatar::isVisible()
06435 {
06436         return mDrawable.notNull() && mDrawable->isVisible(); 
06437 }
06438 
06439 
06440 //-----------------------------------------------------------------------------
06441 // findMotion()
06442 //-----------------------------------------------------------------------------
06443 LLMotion*               LLVOAvatar::findMotion(const LLUUID& id)
06444 {
06445         return mMotionController.findMotion(id);
06446 }
06447 
06448 // Counts the memory footprint of local textures.
06449 void LLVOAvatar::getLocalTextureByteCount( S32* gl_bytes )
06450 {
06451         *gl_bytes = 0;
06452         for( S32 i = 0; i < LOCTEX_NUM_ENTRIES; i++ )
06453         {
06454                 LLViewerImage* image_gl = mLocalTexture[i];
06455                 if( image_gl )
06456                 {
06457                         S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
06458 
06459                         if( image_gl->getHasGLTexture() )
06460                         {
06461                                 *gl_bytes += bytes;
06462                         }
06463                 }
06464         }
06465 }
06466 
06467 
06468 BOOL LLVOAvatar::bindScratchTexture( LLGLenum format )
06469 {
06470         U32 texture_bytes = 0;
06471         GLuint gl_name = getScratchTexName( format, &texture_bytes );
06472         if( gl_name )
06473         {
06474                 LLImageGL::bindExternalTexture( gl_name, 0, GL_TEXTURE_2D );
06475                 stop_glerror();
06476 
06477                 F32* last_bind_time = LLVOAvatar::sScratchTexLastBindTime.getIfThere( format );
06478                 if( last_bind_time )
06479                 {
06480                         if( *last_bind_time != LLImageGL::sLastFrameTime )
06481                         {
06482                                 *last_bind_time = LLImageGL::sLastFrameTime;
06483                                 LLImageGL::updateBoundTexMem(texture_bytes);
06484                         }
06485                 }
06486                 else
06487                 {
06488                         LLImageGL::updateBoundTexMem(texture_bytes);
06489                         LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) );
06490                 }
06491 
06492                 
06493                 return TRUE;
06494         }
06495         else
06496         {
06497                 return FALSE;
06498         }
06499 }
06500 
06501 
06502 LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes )
06503 {
06504         S32 components;
06505         GLenum internal_format;
06506         switch( format )
06507         {
06508         case GL_LUMINANCE:                      components = 1; internal_format = GL_LUMINANCE8;                break;
06509         case GL_ALPHA:                          components = 1; internal_format = GL_ALPHA8;                    break;
06510         case GL_COLOR_INDEX:            components = 1; internal_format = GL_COLOR_INDEX8_EXT;  break;
06511         case GL_LUMINANCE_ALPHA:        components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break;
06512         case GL_RGB:                            components = 3; internal_format = GL_RGB8;                              break;
06513         case GL_RGBA:                           components = 4; internal_format = GL_RGBA8;                             break;
06514         default:        llassert(0);    components = 4; internal_format = GL_RGBA8;                             break;
06515         }
06516 
06517         *texture_bytes = components * VOAVATAR_SCRATCH_TEX_WIDTH * VOAVATAR_SCRATCH_TEX_HEIGHT;
06518         
06519         if( LLVOAvatar::sScratchTexNames.checkData( format ) )
06520         {
06521                 return *( LLVOAvatar::sScratchTexNames.getData( format ) );
06522         }
06523         else
06524         {
06525 
06526                 LLGLSUIDefault gls_ui;
06527 
06528                 GLuint name = 0;
06529                 glGenTextures(1, &name );
06530                 stop_glerror();
06531 
06532                 LLImageGL::bindExternalTexture( name, 0, GL_TEXTURE_2D ); 
06533                 stop_glerror();
06534 
06535                 glTexImage2D(
06536                         GL_TEXTURE_2D, 0, internal_format, 
06537                         VOAVATAR_SCRATCH_TEX_WIDTH, VOAVATAR_SCRATCH_TEX_HEIGHT,
06538                         0, format, GL_UNSIGNED_BYTE, NULL );
06539                 stop_glerror();
06540 
06541                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
06542                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
06543                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
06544                 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
06545                 stop_glerror();
06546 
06547                 LLImageGL::unbindTexture(0, GL_TEXTURE_2D); 
06548                 stop_glerror();
06549 
06550                 LLVOAvatar::sScratchTexNames.addData( format, new LLGLuint( name ) );
06551 
06552                 LLVOAvatar::sScratchTexBytes += *texture_bytes;
06553                 LLImageGL::sGlobalTextureMemory += *texture_bytes;
06554                 return name;
06555         }
06556 }
06557 
06558 
06559 
06560 //-----------------------------------------------------------------------------
06561 // setLocalTextureTE()
06562 //-----------------------------------------------------------------------------
06563 void LLVOAvatar::setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user )
06564 {
06565         if( !mIsSelf )
06566         {
06567                 llassert( 0 );
06568                 return;
06569         }
06570 
06571         if( te >= TEX_NUM_ENTRIES )
06572         {
06573                 llassert(0);
06574                 return;
06575         }
06576 
06577         if( getTEImage( te )->getID() == image->getID() )
06578         {
06579                 return;
06580         }
06581 
06582         if (isTextureIndexBaked(te))
06583         {
06584                 llassert(0);
06585                 return;
06586         }
06587 
06588         LLTexLayerSet* layer_set = getLayerSet((ETextureIndex)te);
06589         if (layer_set)
06590         {
06591                 invalidateComposite(layer_set, set_by_user);
06592         }
06593 
06594         setTEImage( te, image );
06595         updateMeshTextures();
06596 
06597         if( gAgent.cameraCustomizeAvatar() )
06598         {
06599                 LLVisualParamHint::requestHintUpdates();
06600         }
06601 }
06602 
06603 void LLVOAvatar::setupComposites()
06604 {
06605         // Don't invalidate the baked textures we had on start-up.
06606         BOOL head_baked =  ( getTEImage( TEX_HEAD_BAKED  )->getID() != IMG_DEFAULT_AVATAR );
06607         BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06608         BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06609         BOOL eyes_baked =  ( getTEImage( TEX_EYES_BAKED  )->getID() != IMG_DEFAULT_AVATAR );
06610         BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06611         
06612         if (mHeadLayerSet)
06613         {
06614                 mHeadLayerSet->setUpdatesEnabled(               !head_baked  );
06615         }
06616         if (mUpperBodyLayerSet)
06617         {
06618                 mUpperBodyLayerSet->setUpdatesEnabled(  !upper_baked );
06619         }
06620         if (mLowerBodyLayerSet)
06621         {
06622                 mLowerBodyLayerSet->setUpdatesEnabled(  !lower_baked );
06623         }
06624         if (mEyesLayerSet)
06625         {
06626                 mEyesLayerSet->setUpdatesEnabled(               !eyes_baked  );
06627         }
06628         if (mSkirtLayerSet)
06629         {
06630                 mSkirtLayerSet->setUpdatesEnabled(              !skirt_baked  );
06631         }
06632 }
06633 
06634 //-----------------------------------------------------------------------------
06635 // updateMeshTextures()
06636 // Uses the current TE values to set the meshes' and layersets' textures.
06637 //-----------------------------------------------------------------------------
06638 void LLVOAvatar::updateMeshTextures()
06639 {
06640 //      llinfos << "updateMeshTextures" << llendl;
06641         if (gNoRender)
06642         {
06643                 return;
06644         }
06645         // if user has never specified a texture, assign the default
06646         LLViewerImage* default_tex = gImageList.getImage(IMG_DEFAULT);
06647         U8 num_TEs = getNumTEs();
06648         for (U32 i=0; i<num_TEs; i++)
06649         {
06650                 LLViewerImage* te_image = getTEImage(i);
06651                 if( (NULL == te_image) || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT) )
06652                 {
06653                         if( TEX_HAIR == i )
06654                         {
06655                                 setTEImage(i, default_tex );
06656                         }
06657                         else
06658                         {
06659                                 setTEImage(i, gImageList.getImage(IMG_DEFAULT_AVATAR)); // a special texture that's never rendered.
06660                         }
06661                 }
06662         }
06663 
06664         // During face edit mode, we don't use baked textures
06665         BOOL self_customize = mIsSelf && gAgent.cameraCustomizeAvatar();
06666 
06667         BOOL head_baked = (getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06668         BOOL upper_baked = (getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06669         BOOL lower_baked = (getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06670         BOOL eyes_baked = (getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06671         BOOL skirt_baked = (getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );
06672 
06673         // Nothing should be baked if we're in customize avatar mode.
06674         llassert( !( self_customize && 
06675                 ( head_baked || upper_baked || lower_baked || eyes_baked ) ) );
06676 
06677         BOOL use_lkg_head_baked =  FALSE;
06678         BOOL use_lkg_upper_baked = FALSE;
06679         BOOL use_lkg_lower_baked = FALSE;
06680         BOOL use_lkg_eyes_baked =  FALSE;
06681         BOOL use_lkg_skirt_baked =  FALSE;
06682 
06683         BOOL other_culled = !mIsSelf && mCulled;
06684         if( other_culled )
06685         {
06686                 use_lkg_head_baked =  !head_baked  && (mLastHeadBakedID != IMG_DEFAULT_AVATAR);
06687                 use_lkg_upper_baked = !upper_baked && (mLastUpperBodyBakedID != IMG_DEFAULT_AVATAR);
06688                 use_lkg_lower_baked = !lower_baked && (mLastLowerBodyBakedID != IMG_DEFAULT_AVATAR);
06689                 use_lkg_eyes_baked =  !eyes_baked  && (mLastEyesBakedID != IMG_DEFAULT_AVATAR);
06690                 use_lkg_skirt_baked = !skirt_baked && (mLastSkirtBakedID != IMG_DEFAULT_AVATAR);
06691 
06692                 if( mHeadLayerSet )
06693                 {
06694                         mHeadLayerSet->destroyComposite();
06695                 }
06696 
06697                 if( mUpperBodyLayerSet )
06698                 {
06699                         mUpperBodyLayerSet->destroyComposite();
06700                 }
06701 
06702                 if( mLowerBodyLayerSet )
06703                 {
06704                         mLowerBodyLayerSet->destroyComposite();
06705                 }
06706 
06707                 if( mEyesLayerSet )
06708                 {
06709                         mEyesLayerSet->destroyComposite();
06710                 }
06711 
06712                 if( mSkirtLayerSet )
06713                 {
06714                         mSkirtLayerSet->destroyComposite();
06715                 }
06716 
06717         }
06718         else
06719         if( !self_customize )
06720         {
06721                 // When you're changing clothes and you're not in Appearance mode,
06722                 // use the last-known good baked texture until you finish the first
06723                 // render of the new layerset.
06724                 use_lkg_head_baked =  !head_baked  && (mLastHeadBakedID      != IMG_DEFAULT_AVATAR) && mHeadLayerSet      && !mHeadLayerSet->getComposite()->isInitialized();
06725                 use_lkg_upper_baked = !upper_baked && (mLastUpperBodyBakedID != IMG_DEFAULT_AVATAR) && mUpperBodyLayerSet && !mUpperBodyLayerSet->getComposite()->isInitialized();
06726                 use_lkg_lower_baked = !lower_baked && (mLastLowerBodyBakedID != IMG_DEFAULT_AVATAR) && mLowerBodyLayerSet && !mLowerBodyLayerSet->getComposite()->isInitialized();
06727                 use_lkg_eyes_baked =  !eyes_baked  && (mLastEyesBakedID      != IMG_DEFAULT_AVATAR) && mEyesLayerSet      && !mEyesLayerSet->getComposite()->isInitialized();
06728                 use_lkg_skirt_baked = !skirt_baked && (mLastSkirtBakedID     != IMG_DEFAULT_AVATAR) && mSkirtLayerSet     && !mSkirtLayerSet->getComposite()->isInitialized();
06729 
06730                 if( use_lkg_head_baked ) 
06731                 {
06732                         mHeadLayerSet->setUpdatesEnabled( TRUE );
06733                 }
06734 
06735                 if( use_lkg_upper_baked ) 
06736                 {
06737                         mUpperBodyLayerSet->setUpdatesEnabled( TRUE );
06738                 }
06739 
06740                 if( use_lkg_lower_baked )
06741                 {
06742                         mLowerBodyLayerSet->setUpdatesEnabled( TRUE );
06743                 }
06744 
06745                 if( use_lkg_eyes_baked )  
06746                 {
06747                         mEyesLayerSet->setUpdatesEnabled( TRUE );
06748                 }
06749 
06750                 if( use_lkg_skirt_baked )  
06751                 {
06752                         mSkirtLayerSet->setUpdatesEnabled( TRUE );
06753                 }
06754         }
06755 
06756         // Baked textures should be requested from the sim this avatar is on. JC
06757         LLHost target_host = getObjectHost();
06758         if (!target_host.isOk())
06759         {
06760                 llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl;
06761         }
06762                 
06763         // Head
06764         if( use_lkg_head_baked )
06765         {
06766                 LLViewerImage* baked = gImageList.getImageFromHost( mLastHeadBakedID, target_host );
06767                 mHeadMesh0.setTexture( baked );
06768                 mHeadMesh1.setTexture( baked );
06769                 mHeadMesh2.setTexture( baked );
06770                 mHeadMesh3.setTexture( baked );
06771                 mHeadMesh4.setTexture( baked );
06772                 mEyeLashMesh0.setTexture( baked );
06773         }
06774         else
06775         if( !self_customize && head_baked )
06776         {
06777                 LLViewerImage* baked = getTEImage( TEX_HEAD_BAKED );
06778                 if( baked->getID() == mLastHeadBakedID )
06779                 {
06780                         // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
06781                         useBakedTexture( baked->getID() );
06782                 }
06783                 else
06784                 {
06785                         mHeadBakedLoaded = FALSE;
06786                         mHeadMaskDiscard = -1;
06787                         baked->setNeedsAux(TRUE);
06788                         baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));  
06789                         baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
06790                 }
06791         }
06792         else
06793         if( mHeadLayerSet && !other_culled )
06794         {
06795                 mHeadLayerSet->createComposite();
06796                 mHeadLayerSet->setUpdatesEnabled( TRUE );
06797                 mHeadMesh0.setLayerSet( mHeadLayerSet );
06798                 mHeadMesh1.setLayerSet( mHeadLayerSet );
06799                 mHeadMesh2.setLayerSet( mHeadLayerSet );
06800                 mHeadMesh3.setLayerSet( mHeadLayerSet );
06801                 mHeadMesh4.setLayerSet( mHeadLayerSet );
06802                 mEyeLashMesh0.setLayerSet( mHeadLayerSet );
06803         }
06804         else
06805         {
06806                 mHeadMesh0.setTexture( default_tex );
06807                 mHeadMesh1.setTexture( default_tex );
06808                 mHeadMesh2.setTexture( default_tex );
06809                 mHeadMesh3.setTexture( default_tex );
06810                 mHeadMesh4.setTexture( default_tex );
06811                 mEyeLashMesh0.setTexture( default_tex );
06812         }
06813 
06814         // Upper body
06815         if( use_lkg_upper_baked )
06816         {
06817                 LLViewerImage* baked = gImageList.getImageFromHost( mLastUpperBodyBakedID, target_host );
06818                 mUpperBodyMesh0.setTexture( baked );
06819                 mUpperBodyMesh1.setTexture( baked );
06820                 mUpperBodyMesh2.setTexture( baked );
06821                 mUpperBodyMesh3.setTexture( baked );
06822                 mUpperBodyMesh4.setTexture( baked );
06823         }
06824         else
06825         if( !self_customize && upper_baked )
06826         {
06827                 LLViewerImage* baked = getTEImage( TEX_UPPER_BAKED );
06828 
06829                 if( baked->getID() == mLastUpperBodyBakedID )
06830                 {
06831                         // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
06832                         useBakedTexture( baked->getID() );
06833                 }
06834                 else
06835                 {
06836                         mUpperBakedLoaded = FALSE;
06837                         mUpperMaskDiscard = -1;
06838                         baked->setNeedsAux(TRUE);
06839                         baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));
06840                         baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
06841                 }
06842         }
06843         else
06844         if( mUpperBodyLayerSet && !other_culled )
06845         {
06846                 mUpperBodyLayerSet->createComposite();
06847                 mUpperBodyLayerSet->setUpdatesEnabled( TRUE );
06848                 mUpperBodyMesh0.setLayerSet( mUpperBodyLayerSet );
06849                 mUpperBodyMesh1.setLayerSet( mUpperBodyLayerSet );
06850                 mUpperBodyMesh2.setLayerSet( mUpperBodyLayerSet );
06851                 mUpperBodyMesh3.setLayerSet( mUpperBodyLayerSet );
06852                 mUpperBodyMesh4.setLayerSet( mUpperBodyLayerSet );
06853         }
06854         else
06855         {
06856                 mUpperBodyMesh0.setTexture( default_tex );
06857                 mUpperBodyMesh1.setTexture(     default_tex );
06858                 mUpperBodyMesh2.setTexture(     default_tex );
06859                 mUpperBodyMesh3.setTexture(     default_tex );
06860                 mUpperBodyMesh4.setTexture(     default_tex );
06861         }
06862 
06863         // Lower body
06864         if( use_lkg_lower_baked )
06865         {
06866                 LLViewerImage* baked = gImageList.getImageFromHost( mLastLowerBodyBakedID, target_host );
06867                 mLowerBodyMesh0.setTexture( baked );
06868                 mLowerBodyMesh1.setTexture( baked );
06869                 mLowerBodyMesh2.setTexture( baked );
06870                 mLowerBodyMesh3.setTexture( baked );
06871                 mLowerBodyMesh4.setTexture( baked );
06872         }
06873         else
06874         if( !self_customize && lower_baked )
06875         {
06876                 LLViewerImage* baked = getTEImage( TEX_LOWER_BAKED );
06877                 if( baked->getID() == mLastLowerBodyBakedID )
06878                 {
06879                         // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
06880                         useBakedTexture( baked->getID() );
06881                 }
06882                 else
06883                 {
06884                         mLowerBakedLoaded = FALSE;
06885                         mLowerMaskDiscard = -1;
06886                         baked->setNeedsAux(TRUE);
06887                         baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID ));
06888                         baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
06889                 }
06890         }
06891         else
06892         if( mLowerBodyLayerSet && !other_culled )
06893         {
06894                 mLowerBodyLayerSet->createComposite();
06895                 mLowerBodyLayerSet->setUpdatesEnabled( TRUE );
06896                 mLowerBodyMesh0.setLayerSet( mLowerBodyLayerSet );
06897                 mLowerBodyMesh1.setLayerSet( mLowerBodyLayerSet );
06898                 mLowerBodyMesh2.setLayerSet( mLowerBodyLayerSet );
06899                 mLowerBodyMesh3.setLayerSet( mLowerBodyLayerSet );
06900                 mLowerBodyMesh4.setLayerSet( mLowerBodyLayerSet );
06901         }
06902         else
06903         {
06904                 mLowerBodyMesh0.setTexture(     default_tex );
06905                 mLowerBodyMesh1.setTexture(     default_tex );
06906                 mLowerBodyMesh2.setTexture(     default_tex );
06907                 mLowerBodyMesh3.setTexture(     default_tex );
06908                 mLowerBodyMesh4.setTexture(     default_tex );
06909         }
06910 
06911         // Eyes
06912         if( use_lkg_eyes_baked )
06913         {
06914                 LLViewerImage* baked = gImageList.getImageFromHost( mLastEyesBakedID, target_host );
06915                 mEyeBallLeftMesh0.setTexture(  baked );
06916                 mEyeBallLeftMesh1.setTexture(  baked );
06917                 mEyeBallRightMesh0.setTexture( baked );
06918                 mEyeBallRightMesh1.setTexture( baked );
06919         }
06920         else
06921         if( !self_customize && eyes_baked )
06922         {
06923                 LLViewerImage* baked = getTEImage( TEX_EYES_BAKED );
06924                 if( baked->getID() == mLastEyesBakedID )
06925                 {
06926                         // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
06927                         useBakedTexture( baked->getID() );
06928                 }
06929                 else
06930                 {
06931                         mEyesBakedLoaded = FALSE;
06932                         baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
06933                 }
06934         }
06935         else
06936         if( mEyesLayerSet && !other_culled )
06937         {
06938                 mEyesLayerSet->createComposite();
06939                 mEyesLayerSet->setUpdatesEnabled( TRUE );
06940                 mEyeBallLeftMesh0.setLayerSet( mEyesLayerSet );
06941                 mEyeBallLeftMesh1.setLayerSet( mEyesLayerSet );
06942                 mEyeBallRightMesh0.setLayerSet( mEyesLayerSet );
06943                 mEyeBallRightMesh1.setLayerSet( mEyesLayerSet );
06944         }
06945         else
06946         {
06947                 mEyeBallLeftMesh0.setTexture( default_tex );
06948                 mEyeBallLeftMesh1.setTexture( default_tex );
06949                 mEyeBallRightMesh0.setTexture( default_tex );
06950                 mEyeBallRightMesh1.setTexture( default_tex );
06951         }
06952 
06953         // Skirt
06954         if( use_lkg_skirt_baked )
06955         {
06956                 LLViewerImage* baked = gImageList.getImageFromHost( mLastSkirtBakedID, target_host );
06957                 mSkirtMesh0.setTexture(  baked );
06958                 mSkirtMesh1.setTexture(  baked );
06959                 mSkirtMesh2.setTexture(  baked );
06960                 mSkirtMesh3.setTexture(  baked );
06961                 mSkirtMesh4.setTexture(  baked );
06962         }
06963         else
06964         if( !self_customize && skirt_baked )
06965         {
06966                 LLViewerImage* baked = getTEImage( TEX_SKIRT_BAKED );
06967                 if( baked->getID() == mLastSkirtBakedID )
06968                 {
06969                         // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
06970                         useBakedTexture( baked->getID() );
06971                 }
06972                 else
06973                 {
06974                         mSkirtBakedLoaded = FALSE;
06975                         baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) );
06976                 }
06977         }
06978         else
06979         if( mSkirtLayerSet && !other_culled)
06980         {
06981                 mSkirtLayerSet->createComposite();
06982                 mSkirtLayerSet->setUpdatesEnabled( TRUE );
06983                 mSkirtMesh0.setLayerSet( mSkirtLayerSet );
06984                 mSkirtMesh1.setLayerSet( mSkirtLayerSet );
06985                 mSkirtMesh2.setLayerSet( mSkirtLayerSet );
06986                 mSkirtMesh3.setLayerSet( mSkirtLayerSet );
06987                 mSkirtMesh4.setLayerSet( mSkirtLayerSet );
06988         }
06989         else
06990         {
06991                 mSkirtMesh0.setTexture( default_tex );
06992                 mSkirtMesh1.setTexture( default_tex );
06993                 mSkirtMesh2.setTexture( default_tex );
06994                 mSkirtMesh3.setTexture( default_tex );
06995                 mSkirtMesh4.setTexture( default_tex );
06996         }
06997 
06998         mHairMesh0.setTexture(                                          getTEImage( TEX_HAIR ) );
06999         mHairMesh1.setTexture(                                          getTEImage( TEX_HAIR ) );
07000         mHairMesh2.setTexture(                                          getTEImage( TEX_HAIR ) );
07001         mHairMesh3.setTexture(                                          getTEImage( TEX_HAIR ) );
07002         mHairMesh4.setTexture(                                          getTEImage( TEX_HAIR ) );
07003         mHairMesh5.setTexture(                                          getTEImage( TEX_HAIR ) );
07004 
07005         if( mTexHairColor )
07006         {
07007                 LLColor4 color = mTexHairColor->getColor();
07008                 mHairMesh0.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
07009                 mHairMesh1.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
07010                 mHairMesh2.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
07011                 mHairMesh3.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
07012                 mHairMesh4.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
07013                 mHairMesh5.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
07014         }
07015 
07016         // Head
07017         BOOL head_baked_ready = (head_baked && mHeadBakedLoaded) || other_culled;
07018         setLocalTexture( LOCTEX_HEAD_BODYPAINT,         getTEImage( TEX_HEAD_BODYPAINT ),       head_baked_ready );
07019 
07020         // Upper body
07021         BOOL upper_baked_ready = (upper_baked && mUpperBakedLoaded) || other_culled;
07022         setLocalTexture( LOCTEX_UPPER_SHIRT,            getTEImage( TEX_UPPER_SHIRT ),          upper_baked_ready );
07023         setLocalTexture( LOCTEX_UPPER_BODYPAINT,        getTEImage( TEX_UPPER_BODYPAINT ),      upper_baked_ready );
07024         setLocalTexture( LOCTEX_UPPER_JACKET,           getTEImage( TEX_UPPER_JACKET ),         upper_baked_ready );
07025         setLocalTexture( LOCTEX_UPPER_GLOVES,           getTEImage( TEX_UPPER_GLOVES ),         upper_baked_ready );
07026         setLocalTexture( LOCTEX_UPPER_UNDERSHIRT,       getTEImage( TEX_UPPER_UNDERSHIRT ),     upper_baked_ready );
07027 
07028         // Lower body
07029         BOOL lower_baked_ready = (lower_baked && mLowerBakedLoaded) || other_culled;
07030         setLocalTexture( LOCTEX_LOWER_PANTS,            getTEImage( TEX_LOWER_PANTS ),          lower_baked_ready );
07031         setLocalTexture( LOCTEX_LOWER_BODYPAINT,        getTEImage( TEX_LOWER_BODYPAINT ),      lower_baked_ready );
07032         setLocalTexture( LOCTEX_LOWER_SHOES,            getTEImage( TEX_LOWER_SHOES ),          lower_baked_ready );
07033         setLocalTexture( LOCTEX_LOWER_SOCKS,            getTEImage( TEX_LOWER_SOCKS ),          lower_baked_ready );
07034         setLocalTexture( LOCTEX_LOWER_JACKET,           getTEImage( TEX_LOWER_JACKET ),         lower_baked_ready );
07035         setLocalTexture( LOCTEX_LOWER_UNDERPANTS,       getTEImage( TEX_LOWER_UNDERPANTS ),     lower_baked_ready );
07036 
07037         // Eyes
07038         BOOL eyes_baked_ready = (eyes_baked && mEyesBakedLoaded) || other_culled;
07039         setLocalTexture( LOCTEX_EYES_IRIS,                      getTEImage( TEX_EYES_IRIS ),            eyes_baked_ready );
07040 
07041         // Skirt
07042         BOOL skirt_baked_ready = (skirt_baked && mSkirtBakedLoaded) || other_culled;
07043         setLocalTexture( LOCTEX_SKIRT,                          getTEImage( TEX_SKIRT ),                        skirt_baked_ready );
07044 
07045         removeMissingBakedTextures();
07046 }
07047 
07048 //-----------------------------------------------------------------------------
07049 // setLocalTexture()
07050 //-----------------------------------------------------------------------------
07051 void LLVOAvatar::setLocalTexture( ELocTexIndex idx, LLViewerImage* tex, BOOL baked_version_ready )
07052 {
07053         S32 desired_discard = mIsSelf ? 0 : 2;
07054         if (!baked_version_ready)
07055         {
07056                 if (tex != mLocalTexture[idx] || mLocalTextureBaked[idx])
07057                 {
07058                         mLocalTextureDiscard[idx] = MAX_DISCARD_LEVEL+1;
07059                 }
07060                 if (tex->getID() != IMG_DEFAULT_AVATAR)
07061                 {
07062                         if (mLocalTextureDiscard[idx] > desired_discard)
07063                         {
07064                                 S32 tex_discard = tex->getDiscardLevel();
07065                                 if (tex_discard >= 0 && tex_discard <= desired_discard)
07066                                 {
07067                                         mLocalTextureDiscard[idx] = tex_discard;
07068                                         requestLayerSetUpdate( idx );
07069                                         if( mIsSelf && gAgent.cameraCustomizeAvatar() )
07070                                         {
07071                                                 LLVisualParamHint::requestHintUpdates();
07072                                         }
07073                                 }
07074                                 else
07075                                 {
07076                                         tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, new LLAvatarTexData(getID(), idx) );
07077                                 }
07078                         }
07079                         tex->setMinDiscardLevel(desired_discard);
07080                 }
07081         }
07082         mLocalTextureBaked[idx] = baked_version_ready;
07083         mLocalTexture[idx] = tex;
07084 }
07085 
07086 //-----------------------------------------------------------------------------
07087 // requestLayerSetUploads()
07088 //-----------------------------------------------------------------------------
07089 void LLVOAvatar::requestLayerSetUploads()
07090 {
07091         BOOL upper_baked = (getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07092         BOOL lower_baked = (getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07093         BOOL head_baked = (getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07094         BOOL eyes_baked = (getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07095         BOOL skirt_baked = (getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07096 
07097         if( !head_baked && mHeadLayerSet )
07098         {
07099                 mHeadLayerSet->requestUpload();
07100         }
07101 
07102         if( !upper_baked && mUpperBodyLayerSet )
07103         {
07104                 mUpperBodyLayerSet->requestUpload();
07105         }
07106 
07107         if( !lower_baked && mLowerBodyLayerSet )
07108         {
07109                 mLowerBodyLayerSet->requestUpload();
07110         }
07111 
07112         if( !eyes_baked && mEyesLayerSet )
07113         {
07114                 mEyesLayerSet->requestUpload();
07115         }
07116 
07117         if( !skirt_baked && mSkirtLayerSet )
07118         {
07119                 mSkirtLayerSet->requestUpload();
07120         }
07121 }
07122 
07123 
07124 //-----------------------------------------------------------------------------
07125 // setCompositeUpdatesEnabled()
07126 //-----------------------------------------------------------------------------
07127 void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b )
07128 {
07129         if( mHeadLayerSet )
07130         {
07131                 mHeadLayerSet->setUpdatesEnabled( b );
07132         }
07133         
07134         if( mUpperBodyLayerSet )
07135         {
07136                 mUpperBodyLayerSet->setUpdatesEnabled( b );
07137         }
07138 
07139         if( mLowerBodyLayerSet )
07140         {
07141                 mLowerBodyLayerSet->setUpdatesEnabled( b );
07142         }
07143 
07144         if( mEyesLayerSet )
07145         {
07146                 mEyesLayerSet->setUpdatesEnabled( b );
07147         }
07148 
07149         if( mSkirtLayerSet )
07150         {
07151                 mSkirtLayerSet->setUpdatesEnabled( b );
07152         }
07153 
07154 }
07155 
07156 void LLVOAvatar::addChat(const LLChat& chat)
07157 {
07158         std::deque<LLChat>::iterator chat_iter;
07159 
07160         mChats.push_back(chat);
07161 
07162         S32 chat_length = 0;
07163         for( chat_iter = mChats.begin(); chat_iter != mChats.end(); ++chat_iter)
07164         {
07165                 chat_length += chat_iter->mText.size();
07166         }
07167 
07168         // remove any excess chat
07169         chat_iter = mChats.begin();
07170         while ((chat_length > MAX_BUBBLE_CHAT_LENGTH || mChats.size() > MAX_BUBBLE_CHAT_UTTERANCES) && chat_iter != mChats.end())
07171         {
07172                 chat_length -= chat_iter->mText.size();
07173                 mChats.pop_front();
07174                 chat_iter = mChats.begin();
07175         }
07176 
07177         mChatTimer.reset();
07178 }
07179 
07180 void LLVOAvatar::clearChat()
07181 {
07182         mChats.clear();
07183 }
07184 
07185 S32 LLVOAvatar::getLocalDiscardLevel( S32 index )
07186 {
07187         if (index >= 0 && mLocalTexture[index].notNull() && mLocalTexture[index]->getID() != IMG_DEFAULT_AVATAR)
07188         {
07189                 return mLocalTexture[index]->getDiscardLevel();
07190         }
07191         else
07192         {
07193                 // We don't care about this (no image associated with the layer) treat as fully loaded.
07194                 return 0;
07195         }
07196 }
07197 
07198 //-----------------------------------------------------------------------------
07199 // isLocalTextureDataFinal()
07200 // Returns true is the highest quality discard level exists for every texture
07201 // in the layerset.
07202 //-----------------------------------------------------------------------------
07203 BOOL LLVOAvatar::isLocalTextureDataFinal( LLTexLayerSet* layerset )
07204 {
07205         if( layerset == mHeadLayerSet )
07206         {
07207                 return getLocalDiscardLevel( LOCTEX_HEAD_BODYPAINT ) == 0;
07208         }
07209         else if( layerset == mUpperBodyLayerSet )
07210         {
07211                 return getLocalDiscardLevel( LOCTEX_UPPER_SHIRT ) == 0 &&
07212                         getLocalDiscardLevel( LOCTEX_UPPER_BODYPAINT ) == 0 &&
07213                         getLocalDiscardLevel( LOCTEX_UPPER_JACKET ) == 0 && 
07214                         getLocalDiscardLevel( LOCTEX_UPPER_GLOVES ) == 0 && 
07215                         getLocalDiscardLevel( LOCTEX_UPPER_UNDERSHIRT ) == 0;
07216         }
07217         else if( layerset == mLowerBodyLayerSet )
07218         {
07219                 return getLocalDiscardLevel( LOCTEX_LOWER_PANTS ) == 0 &&
07220                         getLocalDiscardLevel( LOCTEX_LOWER_BODYPAINT ) == 0 && 
07221                         getLocalDiscardLevel( LOCTEX_LOWER_SHOES ) == 0 && 
07222                         getLocalDiscardLevel( LOCTEX_LOWER_SOCKS ) == 0 && 
07223                         getLocalDiscardLevel( LOCTEX_LOWER_JACKET ) == 0 && 
07224                         getLocalDiscardLevel( LOCTEX_LOWER_UNDERPANTS ) == 0;
07225         }
07226         else if( layerset == mEyesLayerSet )
07227         {
07228                 return getLocalDiscardLevel( LOCTEX_EYES_IRIS ) == 0;
07229         }
07230         else if( layerset == mSkirtLayerSet )
07231         {
07232                 return getLocalDiscardLevel( LOCTEX_SKIRT ) == 0;
07233         }
07234 
07235         llassert(0);
07236         return FALSE;
07237 }
07238 
07239 //-----------------------------------------------------------------------------
07240 // isLocalTextureDataAvailable()
07241 // Returns true is at least the lowest quality discard level exists for every texture
07242 // in the layerset.
07243 //-----------------------------------------------------------------------------
07244 BOOL LLVOAvatar::isLocalTextureDataAvailable( LLTexLayerSet* layerset )
07245 {
07246         if( layerset == mHeadLayerSet )
07247         {
07248                 return getLocalDiscardLevel( LOCTEX_HEAD_BODYPAINT ) >= 0;
07249         }
07250         else if( layerset == mUpperBodyLayerSet )
07251         {
07252                 return getLocalDiscardLevel( LOCTEX_UPPER_SHIRT ) >= 0 &&
07253                         getLocalDiscardLevel( LOCTEX_UPPER_BODYPAINT ) >= 0 &&
07254                         getLocalDiscardLevel( LOCTEX_UPPER_JACKET ) >= 0 && 
07255                         getLocalDiscardLevel( LOCTEX_UPPER_GLOVES ) >= 0 && 
07256                         getLocalDiscardLevel( LOCTEX_UPPER_UNDERSHIRT ) >= 0;
07257         }
07258         else if( layerset == mLowerBodyLayerSet )
07259         {
07260                 return getLocalDiscardLevel( LOCTEX_LOWER_PANTS ) >= 0 &&
07261                         getLocalDiscardLevel( LOCTEX_LOWER_BODYPAINT ) >= 0 && 
07262                         getLocalDiscardLevel( LOCTEX_LOWER_SHOES ) >= 0 && 
07263                         getLocalDiscardLevel( LOCTEX_LOWER_SOCKS ) >= 0 && 
07264                         getLocalDiscardLevel( LOCTEX_LOWER_JACKET ) >= 0 && 
07265                         getLocalDiscardLevel( LOCTEX_LOWER_UNDERPANTS ) >= 0;
07266         }
07267         else if( layerset == mEyesLayerSet )
07268         {
07269                 return getLocalDiscardLevel( LOCTEX_EYES_IRIS ) >= 0;
07270         }
07271         else if( layerset == mSkirtLayerSet )
07272         {
07273                 return getLocalDiscardLevel( LOCTEX_SKIRT ) >= 0;
07274         }
07275 
07276         llassert(0);
07277         return FALSE;
07278 }
07279 
07280 
07281 //-----------------------------------------------------------------------------
07282 // getBakedTE()
07283 // Used by the LayerSet.  (Layer sets don't in general know what textures depend on them.)
07284 //-----------------------------------------------------------------------------
07285 LLVOAvatar::ETextureIndex LLVOAvatar::getBakedTE( LLTexLayerSet* layerset )
07286 {
07287         if( layerset == mHeadLayerSet )
07288         {
07289                 return TEX_HEAD_BAKED;
07290         }
07291         else
07292         if( layerset == mUpperBodyLayerSet )
07293         {
07294                 return TEX_UPPER_BAKED;
07295         }
07296         else
07297         if( layerset == mLowerBodyLayerSet )
07298         {
07299                 return TEX_LOWER_BAKED;
07300         }
07301         else
07302         if( layerset == mEyesLayerSet )
07303         {
07304                 return TEX_EYES_BAKED;
07305         }
07306         else
07307         if( layerset == mSkirtLayerSet )
07308         {
07309                 return TEX_SKIRT_BAKED;
07310         }
07311 
07312         llassert(0);
07313         return TEX_HEAD_BAKED;
07314 }
07315 
07316 //-----------------------------------------------------------------------------
07317 // setNewBakedTexture()
07318 // A new baked texture has been successfully uploaded and we can start using it now.
07319 //-----------------------------------------------------------------------------
07320 void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
07321 {
07322         // Baked textures live on other sims.
07323         LLHost target_host = getObjectHost();   
07324         setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) );
07325         updateMeshTextures();
07326         dirtyMesh();
07327 
07328         LLVOAvatar::cullAvatarsByPixelArea();
07329 
07330         switch( te )
07331         {
07332         case TEX_HEAD_BAKED:
07333                 llinfos << "New baked texture: HEAD" << llendl;
07334                 break;
07335         case TEX_UPPER_BAKED:
07336                 llinfos << "New baked texture: UPPER" << llendl;
07337                 break;
07338         case TEX_LOWER_BAKED:
07339                 llinfos << "New baked texture: LOWER" << llendl;
07340                 break;
07341         case TEX_EYES_BAKED:
07342                 llinfos << "New baked texture: EYES" << llendl;
07343                 break;
07344         case TEX_SKIRT_BAKED:
07345                 llinfos << "New baked texture: SKIRT" << llendl;
07346                 break;
07347         default:
07348                 llwarns << "New baked texture: unknown te " << te << llendl;
07349                 break;
07350         }
07351         
07352         //      dumpAvatarTEs( "setNewBakedTexture() send" );
07353         // RN: throttle uploads
07354         if (!hasPendingBakedUploads())
07355         {
07356                 gAgent.sendAgentSetAppearance();
07357         }
07358 }
07359 
07360 bool LLVOAvatar::hasPendingBakedUploads()
07361 {
07362         bool head_pending = (mHeadLayerSet && mHeadLayerSet->getComposite()->uploadPending());
07363         bool upper_pending = (mUpperBodyLayerSet && mUpperBodyLayerSet->getComposite()->uploadPending());
07364         bool lower_pending = (mLowerBodyLayerSet && mLowerBodyLayerSet->getComposite()->uploadPending());
07365         bool eyes_pending = (mEyesLayerSet && mEyesLayerSet->getComposite()->uploadPending());
07366         bool skirt_pending = (mSkirtLayerSet && mSkirtLayerSet->getComposite()->uploadPending());
07367 
07368         //llinfos << "TAT: LLVOAvatar::hasPendingBakedUploads()"
07369         //      << " head_pending " << head_pending
07370         //      << " upper_pending " << upper_pending
07371         //      << " lower_pending " << lower_pending
07372         //      << " eyes_pending " << eyes_pending
07373         //      << " skirt_pending " << skirt_pending
07374         //      << llendl;
07375 
07376         if (head_pending || upper_pending || lower_pending || eyes_pending || skirt_pending)
07377         {
07378                 return true;
07379         }
07380         else
07381         {
07382                 return false;
07383         }
07384 }
07385 
07386 //-----------------------------------------------------------------------------
07387 // setCachedBakedTexture()
07388 // A baked texture id was received from a cache query, make it active
07389 //-----------------------------------------------------------------------------
07390 void LLVOAvatar::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid )
07391 {
07392         setTETexture( te, uuid );
07393 
07394         switch(te)
07395         {
07396         case TEX_HEAD_BAKED:
07397                 if( mHeadLayerSet )
07398                 {
07399                         mHeadLayerSet->cancelUpload();
07400                 }               
07401                 break;
07402         case TEX_UPPER_BAKED:
07403                 if( mUpperBodyLayerSet )
07404                 {
07405                         mUpperBodyLayerSet->cancelUpload();
07406                 }
07407                 break;
07408         case TEX_LOWER_BAKED:
07409                 if( mLowerBodyLayerSet )
07410                 {
07411                         mLowerBodyLayerSet->cancelUpload();
07412                 }
07413                 break;
07414         case TEX_EYES_BAKED:
07415                 if( mEyesLayerSet )
07416                 {
07417                         mEyesLayerSet->cancelUpload();
07418                 }
07419                 break;
07420         case TEX_SKIRT_BAKED:
07421                 if( mSkirtLayerSet )
07422                 {
07423                         mSkirtLayerSet->cancelUpload();
07424                 }
07425                 break;
07426 
07427                 case TEX_HEAD_BODYPAINT:
07428                 case TEX_UPPER_SHIRT:
07429                 case TEX_LOWER_PANTS:
07430                 case TEX_EYES_IRIS:
07431                 case TEX_HAIR:
07432                 case TEX_UPPER_BODYPAINT:
07433                 case TEX_LOWER_BODYPAINT:
07434                 case TEX_LOWER_SHOES:
07435                 case TEX_LOWER_SOCKS:
07436                 case TEX_UPPER_JACKET:
07437                 case TEX_LOWER_JACKET:
07438                 case TEX_UPPER_GLOVES:
07439                 case TEX_UPPER_UNDERSHIRT:
07440                 case TEX_LOWER_UNDERPANTS:
07441                 case TEX_SKIRT:
07442                 case TEX_NUM_ENTRIES:
07443                         break;
07444         }
07445 }
07446 
07447 //-----------------------------------------------------------------------------
07448 // static
07449 // onCustomizeStart()
07450 //-----------------------------------------------------------------------------
07451 void LLVOAvatar::onCustomizeStart()
07452 {
07453         LLVOAvatar* avatar = gAgent.getAvatarObject();
07454         if( avatar )
07455         {
07456                 for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ )
07457                 {
07458                         S32 tex_index = sBakedTextureIndices[i];
07459                         avatar->mSavedTE[ tex_index ] = avatar->getTEImage(tex_index)->getID();
07460                         avatar->setTEImage( tex_index, gImageList.getImage(IMG_DEFAULT_AVATAR) );
07461                 }
07462 
07463                 avatar->updateMeshTextures();
07464 
07465 //              avatar->dumpAvatarTEs( "onCustomizeStart() send" );
07466                 gAgent.sendAgentSetAppearance();
07467         }
07468 }
07469 
07470 //-----------------------------------------------------------------------------
07471 // static
07472 // onCustomizeEnd()
07473 //-----------------------------------------------------------------------------
07474 void LLVOAvatar::onCustomizeEnd()
07475 {
07476         LLVOAvatar* avatar = gAgent.getAvatarObject();
07477         if( !avatar ) return;
07478 
07479         LLHost target_host = avatar->getObjectHost();
07480                 for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ )
07481                 {
07482                         S32 tex_index = sBakedTextureIndices[i];
07483                         const LLUUID& saved = avatar->mSavedTE[ tex_index ];
07484                         if( !saved.isNull() )
07485                         {
07486                         avatar->setTEImage( tex_index, gImageList.getImageFromHost( saved, target_host ) );
07487                         }
07488                 }
07489 
07490                 avatar->updateMeshTextures();
07491 
07492                 if( !gQuit )
07493                 {
07494                         avatar->requestLayerSetUploads();
07495                 }
07496 
07497                 gAgent.sendAgentSetAppearance();
07498         }
07499 
07500 BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] )
07501 {
07502         switch( te )
07503         {
07504         case TEX_UPPER_SHIRT:
07505                 param_name[0] = "shirt_red";
07506                 param_name[1] = "shirt_green";
07507                 param_name[2] = "shirt_blue";
07508                 break;
07509 
07510         case TEX_LOWER_PANTS:
07511                 param_name[0] = "pants_red";
07512                 param_name[1] = "pants_green";
07513                 param_name[2] = "pants_blue";
07514                 break;
07515 
07516         case TEX_LOWER_SHOES:
07517                 param_name[0] = "shoes_red";
07518                 param_name[1] = "shoes_green";
07519                 param_name[2] = "shoes_blue";
07520                 break;
07521 
07522         case TEX_LOWER_SOCKS:
07523                 param_name[0] = "socks_red";
07524                 param_name[1] = "socks_green";
07525                 param_name[2] = "socks_blue";
07526                 break;
07527 
07528         case TEX_UPPER_JACKET:
07529         case TEX_LOWER_JACKET:
07530                 param_name[0] = "jacket_red";
07531                 param_name[1] = "jacket_green";
07532                 param_name[2] = "jacket_blue";
07533                 break;
07534 
07535         case TEX_UPPER_GLOVES:
07536                 param_name[0] = "gloves_red";
07537                 param_name[1] = "gloves_green";
07538                 param_name[2] = "gloves_blue";
07539                 break;
07540 
07541         case TEX_UPPER_UNDERSHIRT:
07542                 param_name[0] = "undershirt_red";
07543                 param_name[1] = "undershirt_green";
07544                 param_name[2] = "undershirt_blue";
07545                 break;
07546         
07547         case TEX_LOWER_UNDERPANTS:
07548                 param_name[0] = "underpants_red";
07549                 param_name[1] = "underpants_green";
07550                 param_name[2] = "underpants_blue";
07551                 break;
07552 
07553         case TEX_SKIRT:
07554                 param_name[0] = "skirt_red";
07555                 param_name[1] = "skirt_green";
07556                 param_name[2] = "skirt_blue";
07557                 break;
07558 
07559         default:
07560                 llassert(0);
07561                 return FALSE;
07562         }
07563 
07564         return TRUE;
07565 }
07566 
07567 void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL set_by_user )
07568 {
07569         const char* param_name[3];
07570         if( teToColorParams( te, param_name ) )
07571         {
07572                 setVisualParamWeight( param_name[0], new_color.mV[VX], set_by_user );
07573                 setVisualParamWeight( param_name[1], new_color.mV[VY], set_by_user );
07574                 setVisualParamWeight( param_name[2], new_color.mV[VZ], set_by_user );
07575         }
07576 }
07577 
07578 LLColor4  LLVOAvatar::getClothesColor( ETextureIndex te )
07579 {
07580         LLColor4 color;
07581         const char* param_name[3];
07582         if( teToColorParams( te, param_name ) )
07583         {
07584                 color.mV[VX] = getVisualParamWeight( param_name[0] );
07585                 color.mV[VY] = getVisualParamWeight( param_name[1] );
07586                 color.mV[VZ] = getVisualParamWeight( param_name[2] );
07587         }
07588         return color;
07589 }
07590 
07591 
07592 
07593 
07594 void LLVOAvatar::dumpAvatarTEs( const char* context )
07595 {
07596         llinfos << (mIsSelf ? "Self: " : "Other: ") << context << llendl;
07597         for( S32 i=0; i<TEX_NUM_ENTRIES; i++ )
07598         {
07599                 const char* te_name[] = {
07600                         "TEX_HEAD_BODYPAINT   ",
07601                         "TEX_UPPER_SHIRT      ",
07602                         "TEX_LOWER_PANTS      ",
07603                         "TEX_EYES_IRIS        ",
07604                         "TEX_HAIR             ",
07605                         "TEX_UPPER_BODYPAINT  ",
07606                         "TEX_LOWER_BODYPAINT  ",
07607                         "TEX_LOWER_SHOES      ",
07608                         "TEX_HEAD_BAKED       ",
07609                         "TEX_UPPER_BAKED      ",
07610                         "TEX_LOWER_BAKED      ",
07611                         "TEX_EYES_BAKED       ",
07612                         "TEX_LOWER_SOCKS      ",
07613                         "TEX_UPPER_JACKET     ",
07614                         "TEX_LOWER_JACKET     ",
07615                         "TEX_UPPER_GLOVES     ",
07616                         "TEX_UPPER_UNDERSHIRT ",
07617                         "TEX_LOWER_UNDERPANTS ",
07618                         "TEX_SKIRT            ",
07619                         "TEX_SKIRT_BAKED      "
07620                 };
07621 
07622                 LLViewerImage* te_image = getTEImage(i);
07623                 if( !te_image )
07624                 {
07625                         llinfos << "       " << te_name[i] << ": null ptr" << llendl;
07626                 }
07627                 else
07628                 if( te_image->getID().isNull() )
07629                 {
07630                         llinfos << "       " << te_name[i] << ": null UUID" << llendl;
07631                 }
07632                 else
07633                 if( te_image->getID() == IMG_DEFAULT )
07634                 {
07635                         llinfos << "       " << te_name[i] << ": IMG_DEFAULT" << llendl;
07636                 }
07637                 else
07638                 if( te_image->getID() == IMG_DEFAULT_AVATAR )
07639                 {
07640                         llinfos << "       " << te_name[i] << ": IMG_DEFAULT_AVATAR" << llendl;
07641                 }
07642                 else
07643                 {
07644                         llinfos << "       " << te_name[i] << ": " << te_image->getID() << llendl;
07645                 }
07646         }
07647 }
07648 
07649 //-----------------------------------------------------------------------------
07650 // updateAttachmentVisibility()
07651 //-----------------------------------------------------------------------------
07652 void LLVOAvatar::updateAttachmentVisibility(U32 camera_mode)
07653 {
07654         for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData();
07655                 attachmentPoint;
07656                 attachmentPoint = mAttachmentPoints.getNextData())
07657         {
07658                 if (attachmentPoint->getIsHUDAttachment())
07659                 {
07660                         attachmentPoint->setAttachmentVisibility(TRUE);
07661                 }
07662                 else
07663                 {
07664                         switch (camera_mode)
07665                         {
07666                         case CAMERA_MODE_MOUSELOOK:
07667                                 if (LLVOAvatar::sVisibleInFirstPerson && attachmentPoint->getVisibleInFirstPerson())
07668                                 {
07669                                         attachmentPoint->setAttachmentVisibility(TRUE);
07670                                 }
07671                                 else
07672                                 {
07673                                         attachmentPoint->setAttachmentVisibility(FALSE);
07674                                 }
07675                                 break;
07676                         default:
07677                                 attachmentPoint->setAttachmentVisibility(TRUE);
07678                                 break;
07679                         }
07680                 }
07681         }
07682 }
07683 
07684 // Given a texture entry, determine which wearable type owns it.
07685 // static
07686 LLUUID LLVOAvatar::getDefaultTEImageID( S32 te )
07687 {
07688         switch( te )
07689         {
07690         case TEX_UPPER_SHIRT:           return LLUUID( gSavedSettings.getString("UIImgDefaultShirtUUID") );
07691         case TEX_LOWER_PANTS:           return LLUUID( gSavedSettings.getString("UIImgDefaultPantsUUID") );
07692         case TEX_EYES_IRIS:                     return LLUUID( gSavedSettings.getString("UIImgDefaultEyesUUID") );
07693         case TEX_HAIR:                          return LLUUID( gSavedSettings.getString("UIImgDefaultHairUUID") );
07694         case TEX_LOWER_SHOES:           return LLUUID( gSavedSettings.getString("UIImgDefaultShoesUUID") );
07695         case TEX_LOWER_SOCKS:           return LLUUID( gSavedSettings.getString("UIImgDefaultSocksUUID") );
07696         case TEX_UPPER_GLOVES:          return LLUUID( gSavedSettings.getString("UIImgDefaultGlovesUUID") );
07697         
07698         case TEX_UPPER_JACKET:
07699         case TEX_LOWER_JACKET:          return LLUUID( gSavedSettings.getString("UIImgDefaultJacketUUID") );
07700 
07701         case TEX_UPPER_UNDERSHIRT:
07702         case TEX_LOWER_UNDERPANTS:      return LLUUID( gSavedSettings.getString("UIImgDefaultUnderwearUUID") );
07703 
07704         case TEX_SKIRT:                         return LLUUID( gSavedSettings.getString("UIImgDefaultSkirtUUID") );
07705 
07706         default:                                        return IMG_DEFAULT_AVATAR;
07707         }
07708 }
07709 
07710 
07711 
07712 // Given a texture entry, determine which wearable type owns it.
07713 // static
07714 EWearableType LLVOAvatar::getTEWearableType( S32 te )
07715 {
07716         switch( te )
07717         {
07718         case TEX_UPPER_SHIRT:
07719                 return WT_SHIRT;
07720 
07721         case TEX_LOWER_PANTS:
07722                 return WT_PANTS;
07723 
07724         case TEX_EYES_IRIS:
07725                 return WT_EYES;
07726 
07727         case TEX_HAIR:
07728                 return WT_HAIR;
07729         
07730         case TEX_HEAD_BODYPAINT:
07731         case TEX_UPPER_BODYPAINT:
07732         case TEX_LOWER_BODYPAINT:
07733                 return WT_SKIN;
07734 
07735         case TEX_LOWER_SHOES:
07736                 return WT_SHOES;
07737 
07738         case TEX_LOWER_SOCKS:
07739                 return WT_SOCKS;
07740 
07741         case TEX_UPPER_JACKET:
07742         case TEX_LOWER_JACKET:
07743                 return WT_JACKET;
07744 
07745         case TEX_UPPER_GLOVES:
07746                 return WT_GLOVES;
07747 
07748         case TEX_UPPER_UNDERSHIRT:
07749                 return WT_UNDERSHIRT;
07750 
07751         case TEX_LOWER_UNDERPANTS:
07752                 return WT_UNDERPANTS;
07753 
07754         case TEX_SKIRT:
07755                 return WT_SKIRT;
07756 
07757         default:
07758                 return WT_INVALID;
07759         }
07760 }
07761 
07762 // Unlike most wearable functions, this works for both self and other.
07763 BOOL LLVOAvatar::isWearingWearableType( EWearableType type )
07764 {
07765         if (mIsDummy) return TRUE;
07766 
07767         ETextureIndex indicator_te;
07768         switch( type )
07769         {
07770                 case WT_SHIRT:
07771                         indicator_te = TEX_UPPER_SHIRT;
07772                         break;
07773 
07774                 case WT_PANTS: 
07775                         indicator_te = TEX_LOWER_PANTS;
07776                         break;
07777 
07778                 case WT_SHOES:
07779                         indicator_te = TEX_LOWER_SHOES;
07780                         break;
07781 
07782                 case WT_SOCKS:
07783                         indicator_te = TEX_LOWER_SOCKS;
07784                         break;
07785 
07786                 case WT_JACKET:
07787                         indicator_te = TEX_UPPER_JACKET;
07788                         // Note: no need to test both upper and lower jacket
07789                         break;
07790 
07791                 case WT_GLOVES:
07792                         indicator_te = TEX_UPPER_GLOVES;
07793                         break;
07794 
07795                 case WT_UNDERSHIRT:
07796                         indicator_te = TEX_UPPER_UNDERSHIRT;
07797                         break;
07798 
07799                 case WT_UNDERPANTS:
07800                         indicator_te = TEX_LOWER_UNDERPANTS;
07801                         break;
07802 
07803                 case WT_SKIRT:
07804                         indicator_te = TEX_SKIRT;
07805                         break;
07806                 
07807                 case WT_SHAPE:
07808                 case WT_SKIN:
07809                 case WT_HAIR:
07810                 case WT_EYES:
07811                         return TRUE;  // everyone has all bodyparts
07812 
07813                 default:
07814                         return FALSE;
07815         }
07816 
07817         return ( getTEImage(indicator_te)->getID() != IMG_DEFAULT_AVATAR );
07818 }
07819 
07820 
07821 //-----------------------------------------------------------------------------
07822 // clampAttachmentPositions()
07823 //-----------------------------------------------------------------------------
07824 void LLVOAvatar::clampAttachmentPositions()
07825 {
07826         if (isDead()) return;
07827         for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData();
07828                 attachment;
07829                 attachment = mAttachmentPoints.getNextData())
07830                 {
07831                         if (attachment)
07832                         {
07833                                 attachment->clampObjectPosition();
07834                         }
07835                 }
07836 }
07837 
07838 BOOL LLVOAvatar::hasHUDAttachment()
07839 {
07840         for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData();
07841                 attachment;
07842                 attachment = mAttachmentPoints.getNextData())
07843                 {
07844                         if (attachment->getIsHUDAttachment() && attachment->getObject())
07845                         {
07846                                 return TRUE;
07847                         }
07848                 }
07849         return FALSE;
07850 }
07851 
07852 LLBBox LLVOAvatar::getHUDBBox()
07853 {
07854         LLBBox bbox;
07855         for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData();
07856         attachment;
07857         attachment = mAttachmentPoints.getNextData())
07858         {
07859                 if (attachment->getIsHUDAttachment() && attachment->getObject())
07860                 {
07861                         LLViewerObject* hud_object = attachment->getObject();
07862 
07863                         // initialize bounding box to contain identity orientation and center point for attached object
07864                         bbox.addPointLocal(hud_object->getPosition());
07865                         // add rotated bounding box for attached object
07866                         bbox.addBBoxAgent(hud_object->getBoundingBoxAgent());
07867                         for (U32 i = 0; i < hud_object->mChildList.size(); i++)
07868                         {
07869                                 bbox.addBBoxAgent(hud_object->mChildList[i]->getBoundingBoxAgent());
07870                         }
07871                 }
07872         }
07873 
07874         return bbox;
07875 }
07876 
07877 void LLVOAvatar::rebuildHUD()
07878 {
07879 }
07880 
07881 //-----------------------------------------------------------------------------
07882 // onFirstTEMessageReceived()
07883 //-----------------------------------------------------------------------------
07884 void LLVOAvatar::onFirstTEMessageReceived()
07885 {
07886         if( !mFirstTEMessageReceived )
07887         {
07888                 mFirstTEMessageReceived = TRUE;
07889 
07890                 BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07891                 BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07892                 BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07893                 BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07894                 BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR );
07895 
07896                 // Use any baked textures that we have even if they haven't downloaded yet.
07897                 // (That is, don't do a transition from unbaked to baked.)
07898                 if( head_baked )
07899                 {
07900                         mLastHeadBakedID = getTEImage( TEX_HEAD_BAKED )->getID();
07901                         LLViewerImage* image = getTEImage( TEX_HEAD_BAKED );
07902                         image->setNeedsAux(TRUE);
07903                         image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); 
07904                         image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
07905                 }
07906 
07907                 if( upper_baked )
07908                 {
07909                         mLastUpperBodyBakedID = getTEImage( TEX_UPPER_BAKED )->getID();
07910                         LLViewerImage* image = getTEImage( TEX_UPPER_BAKED );
07911                         image->setNeedsAux(TRUE);
07912                         image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); 
07913                         image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
07914                 }
07915                 
07916                 if( lower_baked )
07917                 {
07918                         mLastLowerBodyBakedID = getTEImage( TEX_LOWER_BAKED )->getID();
07919                         LLViewerImage* image = getTEImage( TEX_LOWER_BAKED );
07920                         image->setNeedsAux(TRUE);
07921                         image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); 
07922                         image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
07923                 }
07924 
07925                 if( eyes_baked )
07926                 {
07927                         mLastEyesBakedID = getTEImage( TEX_EYES_BAKED )->getID();
07928                         LLViewerImage* image = getTEImage( TEX_EYES_BAKED );
07929                         image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
07930                 }
07931 
07932                 if( skirt_baked )
07933                 {
07934                         mLastSkirtBakedID = getTEImage( TEX_SKIRT_BAKED )->getID();
07935                         LLViewerImage* image = getTEImage( TEX_SKIRT_BAKED );
07936                         image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) );
07937                 }
07938 
07939                 updateMeshTextures();
07940         }
07941 }
07942 
07943 //-----------------------------------------------------------------------------
07944 // processAvatarAppearance()
07945 //-----------------------------------------------------------------------------
07946 void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
07947 {
07948         LLMemType mt(LLMemType::MTYPE_AVATAR);
07949         
07950 //      llinfos << "processAvatarAppearance start " << mID << llendl;
07951         BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
07952 
07953         mFirstAppearanceMessageReceived = TRUE;
07954 
07955         if( mIsSelf )
07956         {
07957                 llwarns << "Received AvatarAppearance for self" << llendl;
07958                 if( mFirstTEMessageReceived )
07959                 {
07960 //                      llinfos << "processAvatarAppearance end  " << mID << llendl;
07961                         return;
07962                 }
07963         }
07964 
07965         if (gNoRender)
07966         {
07967                 return;
07968         }
07969 
07970         ESex old_sex = getSex();
07971 
07972 //      llinfos << "ady LLVOAvatar::processAvatarAppearance()" << llendl;
07973 //      dumpAvatarTEs( "PRE  processAvatarAppearance()" );
07974         unpackTEMessage(mesgsys, _PREHASH_ObjectData);
07975 //      dumpAvatarTEs( "POST processAvatarAppearance()" );
07976 
07977 //      llinfos << "Received AvatarAppearance: " << (mIsSelf ? "(self): " : "(other): " ) << 
07978 //              (( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "HEAD " : "head " ) <<
07979 //              (( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "UPPER " : "upper " ) <<
07980 //              (( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "LOWER " : "lower " ) <<
07981 //              (( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "EYES" : "eyes" ) << llendl;
07982  
07983         if( !mFirstTEMessageReceived )
07984         {
07985                 onFirstTEMessageReceived();
07986         }
07987 
07988         setCompositeUpdatesEnabled( FALSE );
07989         updateMeshTextures(); // enables updates for laysets without baked textures.
07990 
07991         // parse visual params
07992         S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
07993         if( num_blocks > 1 )
07994         {
07995                 BOOL params_changed = FALSE;
07996                 BOOL interp_params = FALSE;
07997                 
07998                 LLVisualParam* param = getFirstVisualParam();
07999                 if (!param)
08000                 {
08001                         llwarns << "No visual params!" << llendl;
08002                 }
08003                 else
08004                 {
08005                         for( S32 i = 0; i < num_blocks; i++ )
08006                         {
08007                                 while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) )
08008                                 {
08009                                         param = getNextVisualParam();
08010                                 }
08011                                                 
08012                                 if( !param )
08013                                 {
08014                                         llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl;
08015                                         return;
08016                                 }
08017 
08018                                 U8 value;
08019                                 mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
08020                                 F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
08021 
08022                                 if (is_first_appearance_message || (param->getWeight() != newWeight))
08023                                 {
08024                                         //llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl;
08025                                         params_changed = TRUE;
08026                                         if(is_first_appearance_message)
08027                                         {
08028                                                 param->setWeight(newWeight, FALSE);
08029                                         }
08030                                         else
08031                                         {
08032                                                 interp_params = TRUE;
08033                                                 param->setAnimationTarget(newWeight, FALSE);
08034                                         }
08035                                 }
08036                                 
08037                                 param = getNextVisualParam();
08038                         }
08039                 }
08040 
08041                 while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) )
08042                 {
08043                         param = getNextVisualParam();
08044                 }
08045                 if( param )
08046                 {
08047                         llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl;
08048                         return;
08049                 }
08050 
08051                 if (params_changed)
08052                 {
08053                         if (interp_params)
08054                         {
08055                                 startAppearanceAnimation(FALSE, FALSE);
08056                         }
08057                         updateVisualParams();
08058 
08059                         ESex new_sex = getSex();
08060                         if( old_sex != new_sex )
08061                         {
08062                                 updateSexDependentLayerSets( FALSE );
08063                         }       
08064                 }
08065         }
08066         else
08067         {
08068                 llwarns << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
08069         }
08070 
08071         setCompositeUpdatesEnabled( TRUE );
08072 
08073         llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) );
08074 
08075         // If all of the avatars are completely baked, release the global image caches to conserve memory.
08076         LLVOAvatar::cullAvatarsByPixelArea();
08077 
08078 //      llinfos << "processAvatarAppearance end " << mID << llendl;
08079 }
08080 
08081 // static
08082 void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels )
08083 {
08084         S32 i;
08085         for( i = 0; i < gUserAnimStatesCount; i++ )
08086         {
08087                 labels->put( gUserAnimStates[i].mLabel );
08088         }
08089 
08090         // Special case to trigger away (AFK) state
08091         labels->put( "Away From Keyboard" );
08092 }
08093 
08094 // static 
08095 void LLVOAvatar::getAnimNames( LLDynamicArray<const char*>* names )
08096 {
08097         S32 i;
08098 
08099         for( i = 0; i < gUserAnimStatesCount; i++ )
08100         {
08101                 names->put( gUserAnimStates[i].mName );
08102         }
08103 
08104         // Special case to trigger away (AFK) state
08105         names->put( "enter_away_from_keyboard_state" );
08106 }
08107 
08108 void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
08109 {
08110         //llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl;
08111         LLMemType mt(LLMemType::MTYPE_AVATAR);
08112         
08113         LLUUID id = src_vi->getID();
08114 
08115         if (!userdata)
08116         {
08117                 return;
08118         }
08119  
08120         LLTextureMaskData* maskData = (LLTextureMaskData*) userdata;
08121         LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID );
08122 
08123         // if discard level is 2 less than last discard level we processed, or we hit 0,
08124         // then generate morph masks
08125         if( self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0) )
08126         {
08127                 LLViewerImage* head_baked =             self->getTEImage( TEX_HEAD_BAKED );
08128                 LLViewerImage* upper_baked =    self->getTEImage( TEX_UPPER_BAKED );
08129                 LLViewerImage* lower_baked =    self->getTEImage( TEX_LOWER_BAKED );
08130         
08131                 if( aux_src && aux_src->getComponents() == 1 )
08132                 {
08133                         if (!aux_src->getData())
08134                         {
08135                                 llerrs << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl;
08136                                 return;
08137                         }
08138 
08139                         U32 gl_name;
08140                         glGenTextures(1, (GLuint*) &gl_name );
08141                         stop_glerror();
08142 
08143                         LLImageGL::bindExternalTexture( gl_name, 0, GL_TEXTURE_2D ); 
08144                         stop_glerror();
08145 
08146                         glTexImage2D(
08147                                 GL_TEXTURE_2D, 0, GL_ALPHA8, 
08148                                 aux_src->getWidth(), aux_src->getHeight(),
08149                                 0, GL_ALPHA, GL_UNSIGNED_BYTE, aux_src->getData());
08150                         stop_glerror();
08151 
08152                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
08153                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
08154 
08155                         if( id == head_baked->getID() )
08156                         {
08157                                 if (self->mHeadLayerSet)
08158                                 {
08159                                         //llinfos << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << llendl;
08160                                         self->mHeadLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
08161                                         maskData->mLastDiscardLevel = discard_level;
08162                                         self->mHeadMaskDiscard = discard_level;
08163                                         if (self->mHeadMaskTexName)
08164                                         {
08165                                                 glDeleteTextures(1, (GLuint*) &self->mHeadMaskTexName);
08166                                         }
08167                                         self->mHeadMaskTexName = gl_name;
08168                                 }
08169                                 else
08170                                 {
08171                                         llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl;
08172                                 }
08173                         }
08174                         else
08175                         if( id == upper_baked->getID() )
08176                         {
08177                                 if ( self->mUpperBodyLayerSet)
08178                                 {
08179                                         //llinfos << "onBakedTextureMasksLoaded for upper body " << id << " discard = " << discard_level << llendl;
08180                                         self->mUpperBodyLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
08181                                         maskData->mLastDiscardLevel = discard_level;
08182                                         self->mUpperMaskDiscard = discard_level;
08183                                         if (self->mUpperMaskTexName)
08184                                         {
08185                                                 glDeleteTextures(1, (GLuint*) &self->mUpperMaskTexName);
08186                                         }
08187                                         self->mUpperMaskTexName = gl_name;
08188                                 }
08189                                 else
08190                                 {
08191                                         llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl;
08192                                 }
08193                         }
08194                         else
08195                         if( id == lower_baked->getID() )
08196                         {
08197                                 if ( self->mLowerBodyLayerSet )
08198                                 {
08199                                         //llinfos << "onBakedTextureMasksLoaded for lower body " << id << " discard = " << discard_level << llendl;
08200                                         self->mLowerBodyLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
08201                                         maskData->mLastDiscardLevel = discard_level;
08202                                         self->mLowerMaskDiscard = discard_level;
08203                                         if (self->mLowerMaskTexName)
08204                                         {
08205                                                 glDeleteTextures(1, (GLuint*) &self->mLowerMaskTexName);
08206                                         }
08207                                         self->mLowerMaskTexName = gl_name;
08208                                 }
08209                                 else
08210                                 {
08211                                         llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl;
08212                                 }
08213                         }
08214                         else
08215                         {
08216                                 llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl;
08217                         }
08218 
08219                         self->dirtyMesh();
08220                 }
08221                 else
08222                 {
08223             // this can happen when someone uses an old baked texture possibly provided by 
08224             // viewer-side baked texture caching
08225                         llwarns << "Masks loaded callback but NO aux source!" << llendl;
08226                 }
08227         }
08228 
08229         if (final || !success)
08230         {
08231                 delete maskData;
08232         }
08233 
08234 }
08235 
08236 // static
08237 void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
08238 {
08239         LLUUID *avatar_idp = (LLUUID *)userdata;
08240         LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
08241 
08242         if (!success && selfp)
08243         {
08244                 selfp->removeMissingBakedTextures();
08245         }
08246         if (final || !success )
08247         {
08248                 delete avatar_idp;
08249         }
08250 }
08251 
08252 void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
08253 {
08254         //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl;
08255 
08256         LLUUID id = src_vi->getID();
08257         LLUUID *avatar_idp = (LLUUID *)userdata;
08258         LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
08259 
08260         if (selfp && !success)
08261         {
08262                 selfp->removeMissingBakedTextures();
08263         }
08264 
08265         if( final || !success )
08266         {
08267                 delete avatar_idp;
08268         }
08269 
08270         if( selfp && success && final )
08271         {
08272                 selfp->useBakedTexture( id );
08273         }
08274 }
08275 
08276 
08277 // Called when baked texture is loaded and also when we start up with a baked texture
08278 void LLVOAvatar::useBakedTexture( const LLUUID& id )
08279 {
08280 //      llinfos << "useBakedTexture" << llendl;
08281         LLViewerImage* head_baked =             getTEImage( TEX_HEAD_BAKED );
08282         LLViewerImage* upper_baked =    getTEImage( TEX_UPPER_BAKED );
08283         LLViewerImage* lower_baked =    getTEImage( TEX_LOWER_BAKED );
08284         LLViewerImage* eyes_baked =             getTEImage( TEX_EYES_BAKED );
08285         LLViewerImage* skirt_baked =    getTEImage( TEX_SKIRT_BAKED );
08286 
08287         if( id == head_baked->getID() )
08288         {
08289                 mHeadBakedLoaded = TRUE;
08290                 
08291                 mLastHeadBakedID = id;
08292                 mHeadMesh0.setTexture( head_baked );
08293                 mHeadMesh1.setTexture( head_baked );
08294                 mHeadMesh2.setTexture( head_baked );
08295                 mHeadMesh3.setTexture( head_baked );
08296                 mHeadMesh4.setTexture( head_baked );
08297                 mEyeLashMesh0.setTexture( head_baked );
08298                 if( mHeadLayerSet )
08299                 {
08300                         mHeadLayerSet->destroyComposite();
08301                 }
08302                 setLocalTexture( LOCTEX_HEAD_BODYPAINT,         getTEImage( TEX_HEAD_BODYPAINT ),       TRUE );
08303         }
08304         else
08305         if( id == upper_baked->getID() )
08306         {
08307                 mUpperBakedLoaded = TRUE;
08308 
08309                 mLastUpperBodyBakedID = id;
08310                 mUpperBodyMesh0.setTexture( upper_baked );
08311                 mUpperBodyMesh1.setTexture( upper_baked );
08312                 mUpperBodyMesh2.setTexture( upper_baked );
08313                 mUpperBodyMesh3.setTexture( upper_baked );
08314                 mUpperBodyMesh4.setTexture( upper_baked );
08315                 if( mUpperBodyLayerSet )
08316                 {
08317                         mUpperBodyLayerSet->destroyComposite();
08318                 }
08319 
08320                 setLocalTexture( LOCTEX_UPPER_SHIRT,            getTEImage( TEX_UPPER_SHIRT ),          TRUE );
08321                 setLocalTexture( LOCTEX_UPPER_BODYPAINT,        getTEImage( TEX_UPPER_BODYPAINT ),      TRUE );
08322                 setLocalTexture( LOCTEX_UPPER_JACKET,           getTEImage( TEX_UPPER_JACKET ),         TRUE );
08323                 setLocalTexture( LOCTEX_UPPER_GLOVES,           getTEImage( TEX_UPPER_GLOVES ),         TRUE );
08324                 setLocalTexture( LOCTEX_UPPER_UNDERSHIRT,       getTEImage( TEX_UPPER_UNDERSHIRT ),     TRUE );
08325         }
08326         else
08327         if( id == lower_baked->getID() )
08328         {
08329                 mLowerBakedLoaded = TRUE;
08330 
08331                 mLastLowerBodyBakedID = id;
08332                 mLowerBodyMesh0.setTexture( lower_baked );
08333                 mLowerBodyMesh1.setTexture( lower_baked );
08334                 mLowerBodyMesh2.setTexture( lower_baked );
08335                 mLowerBodyMesh3.setTexture( lower_baked );
08336                 mLowerBodyMesh4.setTexture( lower_baked );
08337                 if( mLowerBodyLayerSet )
08338                 {
08339                         mLowerBodyLayerSet->destroyComposite();
08340                 }
08341 
08342                 setLocalTexture( LOCTEX_LOWER_PANTS,            getTEImage( TEX_LOWER_PANTS ),          TRUE );
08343                 setLocalTexture( LOCTEX_LOWER_BODYPAINT,        getTEImage( TEX_LOWER_BODYPAINT ),      TRUE );
08344                 setLocalTexture( LOCTEX_LOWER_SHOES,            getTEImage( TEX_LOWER_SHOES ),          TRUE );
08345                 setLocalTexture( LOCTEX_LOWER_SOCKS,            getTEImage( TEX_LOWER_SOCKS ),          TRUE );
08346                 setLocalTexture( LOCTEX_LOWER_JACKET,           getTEImage( TEX_LOWER_JACKET ),         TRUE );
08347                 setLocalTexture( LOCTEX_LOWER_UNDERPANTS,       getTEImage( TEX_LOWER_UNDERPANTS ),     TRUE );
08348         }
08349         else
08350         if( id == eyes_baked->getID() )
08351         {
08352                 mEyesBakedLoaded = TRUE;
08353 
08354                 mLastEyesBakedID = id;
08355                 mEyeBallLeftMesh0.setTexture(  eyes_baked );
08356                 mEyeBallLeftMesh1.setTexture(  eyes_baked );
08357                 mEyeBallRightMesh0.setTexture( eyes_baked );
08358                 mEyeBallRightMesh1.setTexture( eyes_baked );
08359                 if( mEyesLayerSet )
08360                 {
08361                         mEyesLayerSet->destroyComposite();
08362                 }
08363 
08364                 setLocalTexture( LOCTEX_EYES_IRIS,                      getTEImage( TEX_EYES_IRIS ), TRUE );
08365         }
08366         else
08367         if( id == skirt_baked->getID() )
08368         {
08369                 mSkirtBakedLoaded = TRUE;
08370 
08371                 mLastSkirtBakedID = id;
08372                 mSkirtMesh0.setTexture( skirt_baked );
08373                 mSkirtMesh1.setTexture( skirt_baked );
08374                 mSkirtMesh2.setTexture( skirt_baked );
08375                 mSkirtMesh3.setTexture( skirt_baked );
08376                 mSkirtMesh4.setTexture( skirt_baked );
08377                 if( mSkirtLayerSet )
08378                 {
08379                         mSkirtLayerSet->destroyComposite();
08380                 }
08381 
08382                 setLocalTexture( LOCTEX_SKIRT,                          getTEImage( TEX_SKIRT ), TRUE );
08383         }
08384 
08385         dirtyMesh();
08386 }
08387 
08388 // static
08389 void LLVOAvatar::dumpArchetypeXML( void* )
08390 {
08391         LLVOAvatar* avatar = gAgent.getAvatarObject();
08392         apr_file_t* file = ll_apr_file_open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB );
08393         if( !file )
08394         {
08395                 return;
08396         }
08397 
08398         apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );
08399         apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
08400         apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
08401 
08402         // only body parts, not clothing.
08403         for( S32 type = WT_SHAPE; type <= WT_EYES; type++ )
08404         {
08405                 const char* wearable_name = LLWearable::typeToTypeName( (EWearableType) type );
08406                 apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name );
08407 
08408                 for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() )
08409                 {
08410                         LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
08411                         if( (viewer_param->getWearableType() == type) && 
08412                                 (viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) )
08413                         {
08414                                 apr_file_printf( file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
08415                                                  viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight() );
08416                         }
08417                 }
08418 
08419                 for( S32 te = 0; te < TEX_NUM_ENTRIES; te++ )
08420                 {
08421                         if( LLVOAvatar::getTEWearableType( te ) == type )
08422                         {
08423                                 LLViewerImage* te_image = avatar->getTEImage( te );
08424                                 if( te_image )
08425                                 {
08426                                         char uuid_str[UUID_STR_LENGTH];         /* Flawfinder: ignore */
08427                                         te_image->getID().toString( uuid_str );
08428                                         apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str);
08429                                 }
08430                         }
08431                 }
08432         }
08433         apr_file_printf( file, "\t</archetype>\n" );
08434         apr_file_printf( file, "\n</linden_genepool>\n" );
08435         apr_file_close( file );
08436 }
08437 
08438 
08439 // Assumes LLVOAvatar::sInstances has already been sorted.
08440 S32 LLVOAvatar::getUnbakedPixelAreaRank()
08441 {
08442         S32 rank = 1;
08443         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
08444                 iter != LLCharacter::sInstances.end(); ++iter)
08445         {
08446                 LLVOAvatar* inst = (LLVOAvatar*) *iter;
08447                 if( inst == this )
08448                 {
08449                         return rank;
08450                 }
08451                 else
08452                 if( !inst->isDead() && !inst->isFullyBaked() )
08453                 {
08454                         rank++;
08455                 }
08456         }
08457 
08458         llassert(0);
08459         return 0;
08460 }
08461 
08462 // static
08463 void LLVOAvatar::cullAvatarsByPixelArea()
08464 {
08465         std::sort(LLCharacter::sInstances.begin(), LLCharacter::sInstances.end(), CompareScreenAreaGreater());
08466         
08467         // Update the avatars that have changed status
08468         S32 rank = 1;
08469 
08470         for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
08471                 iter != LLCharacter::sInstances.end(); ++iter)
08472         {
08473                 LLVOAvatar* inst = (LLVOAvatar*) *iter;
08474                 BOOL culled;
08475                 if( inst->isDead() )
08476                 {
08477                         culled = TRUE;
08478                 }
08479                 else if( inst->isSelf() || inst->isFullyBaked() )
08480                 {
08481                         culled = FALSE;
08482                 }
08483                 else
08484                 {
08485                         culled = (rank > LLVOAvatar::sMaxOtherAvatarsToComposite) || (inst->mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE);
08486                         rank++;
08487                 }
08488 
08489                 if( inst->mCulled != culled )
08490                 {
08491                         inst->mCulled = culled;
08492 
08493                         lldebugs << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << llendl;
08494 
08495                         inst->updateMeshTextures();
08496                 }
08497         }
08498 
08499         if( LLVOAvatar::areAllNearbyInstancesBaked() )
08500         {
08501                 LLVOAvatar::deleteCachedImages();
08502         }
08503 }
08504 
08505 const LLUUID& LLVOAvatar::grabLocalTexture(ETextureIndex index)
08506 {
08507         if (canGrabLocalTexture(index))
08508         {
08509                 return getTEImage( index )->getID();
08510         }
08511         return LLUUID::null;
08512 }
08513 
08514 BOOL LLVOAvatar::canGrabLocalTexture(ETextureIndex index)
08515 {
08516         // Check if the texture hasn't been baked yet.
08517         if ( getTEImage( index )->getID() == IMG_DEFAULT_AVATAR )
08518         {
08519                 lldebugs << "getTEImage( " << (U32) index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl;
08520                 return FALSE;
08521         }
08522 
08523         // Check permissions of textures that show up in the
08524         // baked texture.  We don't want people copying people's
08525         // work via baked textures.
08526         std::vector<ETextureIndex> textures;
08527         switch (index)
08528         {
08529         case TEX_EYES_BAKED:
08530                 textures.push_back(TEX_EYES_IRIS);
08531                 break;
08532         case TEX_HEAD_BAKED:
08533                 textures.push_back(TEX_HEAD_BODYPAINT);
08534                 break;
08535         case TEX_UPPER_BAKED:
08536                 textures.push_back(TEX_UPPER_BODYPAINT);
08537                 textures.push_back(TEX_UPPER_UNDERSHIRT);
08538                 textures.push_back(TEX_UPPER_SHIRT);
08539                 textures.push_back(TEX_UPPER_JACKET);
08540                 textures.push_back(TEX_UPPER_GLOVES);
08541                 break;
08542         case TEX_LOWER_BAKED:
08543                 textures.push_back(TEX_LOWER_BODYPAINT);
08544                 textures.push_back(TEX_LOWER_UNDERPANTS);
08545                 textures.push_back(TEX_LOWER_PANTS);
08546                 textures.push_back(TEX_LOWER_JACKET);
08547                 textures.push_back(TEX_LOWER_SOCKS);
08548                 textures.push_back(TEX_LOWER_SHOES);
08549                 break;
08550         case TEX_SKIRT_BAKED:
08551                 textures.push_back(TEX_SKIRT);
08552                 break;
08553         default:
08554                 return FALSE;
08555                 break;
08556         }
08557 
08558         std::vector<ETextureIndex>::iterator iter = textures.begin();
08559         std::vector<ETextureIndex>::iterator end  = textures.end();
08560         for (; iter != end; ++iter)
08561         {
08562                 ETextureIndex t_index = (*iter);
08563                 lldebugs << "Checking index " << (U32) t_index << llendl;
08564                 const LLUUID& texture_id = getTEImage( t_index )->getID();
08565                 if (texture_id != IMG_DEFAULT_AVATAR)
08566                 {
08567                         // Search inventory for this texture.
08568                         LLViewerInventoryCategory::cat_array_t cats;
08569                         LLViewerInventoryItem::item_array_t items;
08570                         LLAssetIDMatches asset_id_matches(texture_id);
08571                         gInventory.collectDescendentsIf(LLUUID::null,
08572                                                                         cats,
08573                                                                         items,
08574                                                                         LLInventoryModel::INCLUDE_TRASH,
08575                                                                         asset_id_matches);
08576 
08577                         BOOL can_grab = FALSE;
08578                         lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl;
08579                         if (items.count())
08580                         {
08581                                 // search for full permissions version
08582                                 for (S32 i = 0; i < items.count(); i++)
08583                                 {
08584                                         LLInventoryItem* itemp = items[i];
08585                                         LLPermissions item_permissions = itemp->getPermissions();
08586                                         if ( item_permissions.allowOperationBy(
08587                                                                 PERM_MODIFY, gAgent.getID(), gAgent.getGroupID()) &&
08588                                                  item_permissions.allowOperationBy(
08589                                                                 PERM_COPY, gAgent.getID(), gAgent.getGroupID()) &&
08590                                                  item_permissions.allowOperationBy(
08591                                                                 PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()) )
08592                                         {
08593                                                 can_grab = TRUE;
08594                                                 break;
08595                                         }
08596                                 }
08597                         }
08598                         if (!can_grab) return FALSE;
08599                 }
08600         }
08601 
08602         return TRUE;
08603 }
08604 
08605 void LLVOAvatar::dumpLocalTextures()
08606 {
08607         llinfos << "Local Textures:" << llendl;
08608 
08609         char* names[] = {
08610                 "Shirt     ",
08611                 "UpperTatoo",
08612                 "Pants     ",
08613                 "LowerTatoo",
08614                 "Head Tatoo",
08615                 "Shoes     ",
08616                 "Socks     ",
08617                 "Upper Jckt",
08618                 "Lower Jckt",
08619                 "Gloves    ",
08620                 "Undershirt",
08621                 "Underpants",
08622                 "Iris      ",
08623                 "Skirt      "};
08624 
08625         ETextureIndex baked_equiv[] = {
08626                 TEX_UPPER_BAKED,
08627                 TEX_UPPER_BAKED,
08628                 TEX_LOWER_BAKED,
08629                 TEX_LOWER_BAKED,
08630                 TEX_HEAD_BAKED,
08631                 TEX_LOWER_BAKED,
08632                 TEX_LOWER_BAKED,
08633                 TEX_UPPER_BAKED,
08634                 TEX_LOWER_BAKED,
08635                 TEX_UPPER_BAKED,
08636                 TEX_UPPER_BAKED,
08637                 TEX_LOWER_BAKED,
08638                 TEX_EYES_BAKED,
08639                 TEX_SKIRT_BAKED };
08640 
08641 
08642         for( S32 i = 0; i < LOCTEX_NUM_ENTRIES; i++ )
08643         {
08644                 if( getTEImage( baked_equiv[i] )->getID() != IMG_DEFAULT_AVATAR )
08645                 {
08646 #if LL_RELEASE_FOR_DOWNLOAD
08647                         // End users don't get to trivially see avatar texture IDs, makes textures
08648                         // easier to steal. JC
08649                         llinfos << "LocTex " << names[i] << ": Baked " << llendl;
08650 #else
08651                         llinfos << "LocTex " << names[i] << ": Baked " << getTEImage( baked_equiv[i] )->getID() << llendl;
08652 #endif
08653                 }
08654                 else if (mLocalTexture[i].notNull())
08655                 {
08656                         if( mLocalTexture[i]->getID() == IMG_DEFAULT_AVATAR )
08657                         {
08658                                 llinfos << "LocTex " << names[i] << ": None" << llendl;
08659                         }
08660                         else
08661                         {
08662                                 LLViewerImage* image = mLocalTexture[i];
08663 
08664                                 llinfos << "LocTex " << names[i] << ": "
08665                                                 << "Discard " << image->getDiscardLevel() << ", "
08666                                                 << "(" << image->getWidth() << ", " << image->getHeight() << ") " 
08667 #if !LL_RELEASE_FOR_DOWNLOAD
08668                                         // End users don't get to trivially see avatar texture IDs,
08669                                         // makes textures easier to steal
08670                                                 << image->getID() << " "
08671 #endif
08672                                                 << "Priority: " << image->getDecodePriority()
08673                                                 << llendl;
08674                         }
08675                 }
08676                 else
08677                 {
08678                         llinfos << "LocTex " << names[i] << ": No LLViewerImage" << llendl;
08679                 }
08680         }
08681 }
08682 
08683 void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound)
08684 {
08685         if(!mAppearanceAnimating)
08686         {
08687                 mAppearanceAnimSetByUser = set_by_user;
08688                 mAppearanceAnimating = TRUE;
08689                 mAppearanceMorphTimer.reset();
08690                 mLastAppearanceBlendTime = 0.f;
08691         }
08692 }
08693 
08694 
08695 void LLVOAvatar::removeMissingBakedTextures()
08696 {       
08697         if (!mIsSelf)
08698         {
08699                 return;
08700         }
08701         BOOL removed = FALSE;
08702 
08703         for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ )
08704         {
08705                 S32 te = sBakedTextureIndices[i];
08706 
08707                 if( getTEImage( te )->isMissingAsset() )
08708                 {
08709                         setTEImage( te, gImageList.getImage(IMG_DEFAULT_AVATAR) );
08710                         removed = TRUE;
08711                 }
08712         }
08713 
08714         if( removed )
08715         {
08716                 invalidateComposite( mEyesLayerSet,                     FALSE );
08717                 invalidateComposite( mHeadLayerSet,                     FALSE );
08718                 invalidateComposite( mUpperBodyLayerSet,        FALSE );
08719                 invalidateComposite( mLowerBodyLayerSet,        FALSE );
08720                 invalidateComposite( mSkirtLayerSet,            FALSE );
08721                 updateMeshTextures();
08722                 requestLayerSetUploads();
08723         }
08724 }
08725 
08726 
08727 //-----------------------------------------------------------------------------
08728 // LLVOAvatarInfo
08729 //-----------------------------------------------------------------------------
08730 
08731 LLVOAvatarInfo::LLVOAvatarInfo()
08732         : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
08733 {
08734 }
08735 
08736 LLVOAvatarInfo::~LLVOAvatarInfo()
08737 {
08738         std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
08739         std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());         
08740         std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
08741         delete mTexSkinColorInfo;
08742         delete mTexHairColorInfo;
08743         delete mTexEyeColorInfo;
08744         std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());           
08745         std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());         
08746 }
08747 
08748 //-----------------------------------------------------------------------------
08749 // LLVOAvatarBoneInfo::parseXml()
08750 //-----------------------------------------------------------------------------
08751 BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
08752 {
08753         if (node->hasName("bone"))
08754         {
08755                 mIsJoint = TRUE;
08756                 static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
08757                 if (!node->getFastAttributeString(name_string, mName))
08758                 {
08759                         llwarns << "Bone without name" << llendl;
08760                         return FALSE;
08761                 }
08762         }
08763         else if (node->hasName("collision_volume"))
08764         {
08765                 mIsJoint = FALSE;
08766                 static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
08767                 if (!node->getFastAttributeString(name_string, mName))
08768                 {
08769                         mName = "Collision Volume";
08770                 }
08771         }
08772         else
08773         {
08774                 llwarns << "Invalid node " << node->getName() << llendl;
08775                 return FALSE;
08776         }
08777 
08778         static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
08779         if (!node->getFastAttributeVector3(pos_string, mPos))
08780         {
08781                 llwarns << "Bone without position" << llendl;
08782                 return FALSE;
08783         }
08784 
08785         static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
08786         if (!node->getFastAttributeVector3(rot_string, mRot))
08787         {
08788                 llwarns << "Bone without rotation" << llendl;
08789                 return FALSE;
08790         }
08791         
08792         static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
08793         if (!node->getFastAttributeVector3(scale_string, mScale))
08794         {
08795                 llwarns << "Bone without scale" << llendl;
08796                 return FALSE;
08797         }
08798 
08799         if (mIsJoint)
08800         {
08801                 static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
08802                 if (!node->getFastAttributeVector3(pivot_string, mPivot))
08803                 {
08804                         llwarns << "Bone without pivot" << llendl;
08805                         return FALSE;
08806                 }
08807         }
08808 
08809         // parse children
08810         LLXmlTreeNode* child;
08811         for( child = node->getFirstChild(); child; child = node->getNextChild() )
08812         {
08813                 LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
08814                 if (!child_info->parseXml(child))
08815                 {
08816                         delete child_info;
08817                         return FALSE;
08818                 }
08819                 mChildList.push_back(child_info);
08820         }
08821         return TRUE;
08822 }
08823 
08824 //-----------------------------------------------------------------------------
08825 // LLVOAvatarSkeletonInfo::parseXml()
08826 //-----------------------------------------------------------------------------
08827 BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
08828 {
08829         static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
08830         if (!node->getFastAttributeS32(num_bones_string, mNumBones))
08831         {
08832                 llwarns << "Couldn't find number of bones." << llendl;
08833                 return FALSE;
08834         }
08835 
08836         static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
08837         node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
08838 
08839         LLXmlTreeNode* child;
08840         for( child = node->getFirstChild(); child; child = node->getNextChild() )
08841         {
08842                 LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
08843                 if (!info->parseXml(child))
08844                 {
08845                         delete info;
08846                         llwarns << "Error parsing bone in skeleton file" << llendl;
08847                         return FALSE;
08848                 }
08849                 mBoneInfoList.push_back(info);
08850         }
08851         return TRUE;
08852 }
08853 
08854 //-----------------------------------------------------------------------------
08855 // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
08856 //-----------------------------------------------------------------------------
08857 BOOL LLVOAvatarInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
08858 {
08859         LLXmlTreeNode* node = root->getChildByName( "skeleton" );
08860         if( !node )
08861         {
08862                 llwarns << "avatar file: missing <skeleton>" << llendl;
08863                 return FALSE;
08864         }
08865 
08866         LLXmlTreeNode* child;
08867 
08868         // SKELETON DISTORTIONS
08869         for (child = node->getChildByName( "param" );
08870                  child;
08871                  child = node->getNextNamedChild())
08872         {
08873                 if (!child->getChildByName("param_skeleton"))
08874                 {
08875                         if (child->getChildByName("param_morph"))
08876                         {
08877                                 llwarns << "Can't specify morph param in skeleton definition." << llendl;
08878                         }
08879                         else
08880                         {
08881                                 llwarns << "Unknown param type." << llendl;
08882                         }
08883                         continue;
08884                 }
08885                 
08886                 LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
08887                 if (!info->parseXml(child))
08888                 {
08889                         delete info;
08890                         return FALSE;
08891                 }
08892 
08893                 mSkeletalDistortionInfoList.push_back(info);
08894         }
08895 
08896         // ATTACHMENT POINTS
08897         for (child = node->getChildByName( "attachment_point" );
08898                  child;
08899                  child = node->getNextNamedChild())
08900         {
08901                 LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo();
08902 
08903                 static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
08904                 if (!child->getFastAttributeString(name_string, info->mName))
08905                 {
08906                         llwarns << "No name supplied for attachment point." << llendl;
08907                         delete info;
08908                         continue;
08909                 }
08910 
08911                 static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
08912                 if (!child->getFastAttributeString(joint_string, info->mJointName))
08913                 {
08914                         llwarns << "No bone declared in attachment point " << info->mName << llendl;
08915                         delete info;
08916                         continue;
08917                 }
08918 
08919                 static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
08920                 if (child->getFastAttributeVector3(position_string, info->mPosition))
08921                 {
08922                         info->mHasPosition = TRUE;
08923                 }
08924 
08925                 static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
08926                 if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
08927                 {
08928                         info->mHasRotation = TRUE;
08929                 }
08930                  static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
08931                 if (child->getFastAttributeS32(group_string, info->mGroup))
08932                 {
08933                         if (info->mGroup == -1)
08934                                 info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
08935                 }
08936 
08937                 static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
08938                 if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
08939                 {
08940                         llwarns << "No id supplied for attachment point " << info->mName << llendl;
08941                         delete info;
08942                         continue;
08943                 }
08944 
08945                 static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
08946                 child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
08947                         
08948                 static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
08949                 child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
08950 
08951                 static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
08952                 child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
08953 
08954                 mAttachmentInfoList.push_back(info);
08955         }
08956 
08957         return TRUE;
08958 }
08959 
08960 //-----------------------------------------------------------------------------
08961 // parseXmlMeshNodes(): parses <mesh> nodes from XML tree
08962 //-----------------------------------------------------------------------------
08963 BOOL LLVOAvatarInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
08964 {
08965         for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
08966                  node;
08967                  node = root->getNextNamedChild())
08968         {
08969                 LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo;
08970 
08971                 // attribute: type
08972                 static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
08973                 if( !node->getFastAttributeString( type_string, info->mType ) )
08974                 {
08975                         llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl;
08976                         delete info;
08977                         return FALSE;  // Ignore this element
08978                 }
08979                 
08980                 static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
08981                 if (!node->getFastAttributeS32( lod_string, info->mLOD ))
08982                 {
08983                         llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl;
08984                         delete info;
08985                         return FALSE;  // Ignore this element
08986                 }
08987 
08988                 static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
08989                 if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
08990                 {
08991                         llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl;
08992                         delete info;
08993                         return FALSE;  // Ignore this element
08994                 }
08995 
08996                 static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
08997                 node->getFastAttributeString( reference_string, info->mReferenceMeshName );
08998                 
08999                 // attribute: min_pixel_area
09000                 static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
09001                 static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
09002                 if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
09003                 {
09004                         F32 min_pixel_area = 0.1f;
09005                         if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
09006                         {
09007                                 // this is square root of pixel area (sensible to use linear space in defining lods)
09008                                 min_pixel_area = min_pixel_area * min_pixel_area;
09009                         }
09010                         info->mMinPixelArea = min_pixel_area;
09011                 }
09012                 
09013                 // Parse visual params for this node only if we haven't already
09014                 for (LLXmlTreeNode* child = node->getChildByName( "param" );
09015                          child;
09016                          child = node->getNextNamedChild())
09017                 {
09018                         if (!child->getChildByName("param_morph"))
09019                         {
09020                                 if (child->getChildByName("param_skeleton"))
09021                                 {
09022                                         llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
09023                                 }
09024                                 else
09025                                 {
09026                                         llwarns << "Unknown param type." << llendl;
09027                                 }
09028                                 continue;
09029                         }
09030 
09031                         LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
09032                         if (!morphinfo->parseXml(child))
09033                         {
09034                                 delete morphinfo;
09035                                 delete info;
09036                                 return -1;
09037                         }
09038                         BOOL shared = FALSE;
09039                         static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
09040                         child->getFastAttributeBOOL(shared_string, shared);
09041 
09042                         info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
09043                 }
09044 
09045                 mMeshInfoList.push_back(info);
09046         }
09047         return TRUE;
09048 }
09049 
09050 //-----------------------------------------------------------------------------
09051 // parseXmlColorNodes(): parses <global_color> nodes from XML tree
09052 //-----------------------------------------------------------------------------
09053 BOOL LLVOAvatarInfo::parseXmlColorNodes(LLXmlTreeNode* root)
09054 {
09055         for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
09056                  color_node;
09057                  color_node = root->getNextNamedChild())
09058         {
09059                 LLString global_color_name;
09060                 static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
09061                 if (color_node->getFastAttributeString( name_string, global_color_name ) )
09062                 {
09063                         if( global_color_name == "skin_color" )
09064                         {
09065                                 if (mTexSkinColorInfo)
09066                                 {
09067                                         llwarns << "avatar file: multiple instances of skin_color" << llendl;
09068                                         return FALSE;
09069                                 }
09070                                 mTexSkinColorInfo = new LLTexGlobalColorInfo;
09071                                 if( !mTexSkinColorInfo->parseXml( color_node ) )
09072                                 {
09073                                         delete mTexSkinColorInfo; mTexSkinColorInfo = 0;
09074                                         llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
09075                                         return FALSE;
09076                                 }
09077                         }
09078                         else if( global_color_name == "hair_color" )
09079                         {
09080                                 if (mTexHairColorInfo)
09081                                 {
09082                                         llwarns << "avatar file: multiple instances of hair_color" << llendl;
09083                                         return FALSE;
09084                                 }
09085                                 mTexHairColorInfo = new LLTexGlobalColorInfo;
09086                                 if( !mTexHairColorInfo->parseXml( color_node ) )
09087                                 {
09088                                         delete mTexHairColorInfo; mTexHairColorInfo = 0;
09089                                         llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
09090                                         return FALSE;
09091                                 }
09092                         }
09093                         else if( global_color_name == "eye_color" )
09094                         {
09095                                 if (mTexEyeColorInfo)
09096                                 {
09097                                         llwarns << "avatar file: multiple instances of eye_color" << llendl;
09098                                         return FALSE;
09099                                 }
09100                                 mTexEyeColorInfo = new LLTexGlobalColorInfo;
09101                                 if( !mTexEyeColorInfo->parseXml( color_node ) )
09102                                 {
09103                                         llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
09104                                         return FALSE;
09105                                 }
09106                         }
09107                 }
09108         }
09109         return TRUE;
09110 }
09111 
09112 //-----------------------------------------------------------------------------
09113 // parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
09114 //-----------------------------------------------------------------------------
09115 BOOL LLVOAvatarInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
09116 {
09117         for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
09118                  layer_node;
09119                  layer_node = root->getNextNamedChild())
09120         {
09121                 LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
09122                 if( layer_info->parseXml( layer_node ) )
09123                 {
09124                         mLayerInfoList.push_back(layer_info);
09125                 }
09126                 else
09127                 {
09128                         delete layer_info;
09129                         llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
09130                         return FALSE;
09131                 }
09132         }
09133         return TRUE;
09134 }
09135 
09136 //-----------------------------------------------------------------------------
09137 // parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
09138 //-----------------------------------------------------------------------------
09139 BOOL LLVOAvatarInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
09140 {
09141         LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
09142         if( driver )
09143         {
09144                 for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
09145                          grand_child;
09146                          grand_child = driver->getNextNamedChild())
09147                 {
09148                         if( grand_child->getChildByName( "param_driver" ) )
09149                         {
09150                                 LLDriverParamInfo* driver_info = new LLDriverParamInfo();
09151                                 if( driver_info->parseXml( grand_child ) )
09152                                 {
09153                                         mDriverInfoList.push_back(driver_info);
09154                                 }
09155                                 else
09156                                 {
09157                                         delete driver_info;
09158                                         llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
09159                                         return FALSE;
09160                                 }
09161                         }
09162                 }
09163         }
09164         return TRUE;
09165 }
09166 
09167 void LLVOAvatar::writeCAL3D(std::string& path, std::string& file_base)
09168 {
09169         char filename[MAX_PATH];                /* Flawfinder: ignore */
09170 
09171         // reset animated morphs
09172         setVisualParamWeight("Blink_Left", 0.f);
09173         setVisualParamWeight("Blink_Right", 0.f);
09174         setVisualParamWeight("Hands_Relaxed", 1.f);
09175         setVisualParamWeight("Hands_Point", 0.f);
09176         setVisualParamWeight("Hands_Fist", 0.f);
09177         setVisualParamWeight("Hands_Relaxed_L", 0.f);
09178         setVisualParamWeight("Hands_Point_L", 0.f);
09179         setVisualParamWeight("Hands_Fist_L", 0.f);
09180         setVisualParamWeight("Hands_Relaxed_R", 0.f);
09181         setVisualParamWeight("Hands_Point_R", 0.f);
09182         setVisualParamWeight("Hands_Fist_R", 0.f);
09183         setVisualParamWeight("Hands_Salute_R", 0.f);
09184         setVisualParamWeight("Hands_Typing", 0.f);
09185         setVisualParamWeight("Hands_Peace_R", 0.f);
09186         setVisualParamWeight("Hands_Spread_R", 0.f);
09187         updateVisualParams();
09188 
09189         snprintf(filename, MAX_PATH, "%s\\%s_skeleton.xsf", path.c_str(), file_base.c_str());           /* Flawfinder: ignore */
09190         apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W);
09191         if (!fp)
09192         {
09193                 llwarns << "Unable to write avatar file " << filename << llendl;
09194                 return;
09195         }
09196         apr_file_printf(fp, "<SKELETON VERSION=\"1000\" NUMBONES=\"%d\">\n", sSkeletonInfo->getNumBones() - sSkeletonInfo->getNumCollisionVolumes());
09197         mRoot.writeCAL3D(fp);
09198         apr_file_printf(fp, "</SKELETON>\n");
09199         apr_file_close(fp);
09200 
09201         snprintf(filename, MAX_PATH, "%s\\%s_mesh_body.xmf", path.c_str(), file_base.c_str());          /* Flawfinder: ignore */
09202         //gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"avatar.cal").c_str()
09203         fp = ll_apr_file_open(filename, LL_APR_W);
09204         if (!fp)
09205         {
09206                 llwarns << "Unable to write avatar file " << filename << llendl;
09207                 return;
09208         }
09209 
09210         BOOL has_skirt = isWearingWearableType(WT_SKIRT);
09211 
09212         apr_file_printf(fp, "<MESH VERSION=\"1000\" NUMSUBMESH=\"%d\">\n", has_skirt ? 8 : 7);
09213         mHairMesh0.writeCAL3D(fp, 5, this);
09214         mHeadMesh0.writeCAL3D(fp, 0, this);
09215         mEyeLashMesh0.writeCAL3D(fp, 0, this);
09216         mUpperBodyMesh0.writeCAL3D(fp, 1, this);
09217         mLowerBodyMesh0.writeCAL3D(fp, 2, this);
09218         mEyeBallLeftMesh0.writeCAL3D(fp, 3, this);
09219         mEyeBallRightMesh0.writeCAL3D(fp, 3, this);
09220         if (has_skirt)
09221         {
09222                 mSkirtMesh0.writeCAL3D(fp, 4, this);
09223         }
09224         apr_file_printf(fp, "</MESH>\n");
09225         apr_file_close(fp);
09226 
09227         // write out material files
09228         LLPointer<LLImageTGA> tga_image = new LLImageTGA;
09229 
09230         for (S32 i = 0; i < (has_skirt ? BAKED_TEXTURE_COUNT : BAKED_TEXTURE_COUNT - 1); i++)
09231         {
09232                 snprintf(filename, MAX_PATH, "%s\\%s_material_tex_%d.tga", path.c_str(), file_base.c_str(), i);         /* Flawfinder: ignore */
09233 
09234                 LLViewerImage* viewer_imagep = mTEImages[sBakedTextureIndices[i]];
09235                 if (!viewer_imagep->getHasGLTexture())
09236                 {
09237                         llinfos << "No image data available for " << filename << llendl;
09238                         continue;
09239                 }
09240                 LLPointer<LLImageRaw> raw_image = new LLImageRaw;
09241                 viewer_imagep->readBackRaw(-1, raw_image, false);
09242                 BOOL success = tga_image->encode(raw_image);
09243                 success = tga_image->save(filename);
09244         }
09245 
09246         // output image for hair
09247         snprintf(filename, MAX_PATH, "%s\\%s_material_tex_5.tga", path.c_str(), file_base.c_str());             /* Flawfinder: ignore */
09248         LLViewerImage* viewer_imagep = mTEImages[TEX_HAIR];
09249         if (!viewer_imagep->getHasGLTexture())
09250         {
09251                 llinfos << "No image data available for " << filename << llendl;
09252         }
09253         else
09254         {
09255                 LLPointer<LLImageRaw> raw_image = new LLImageRaw;
09256                 viewer_imagep->readBackRaw(-1, raw_image, false);
09257                 BOOL success = tga_image->encode(raw_image);
09258                 success = tga_image->save(filename);
09259         }
09260 
09261         // save out attachments
09262         snprintf(filename, MAX_PATH, "%s\\%s_mesh_attachments.xmf", path.c_str(), file_base.c_str());           /* Flawfinder: ignore */
09263         fp = ll_apr_file_open(filename, LL_APR_W);
09264         if (!fp)
09265         {
09266                 llwarns << "Unable to write attachments file " << filename << llendl;
09267                 return;
09268         }
09269 
09270         typedef std::multimap<LLUUID, LLMaterialExportInfo*>::iterator material_it_t;
09271         std::multimap<LLUUID, LLMaterialExportInfo*> material_map;
09272 
09273         S32 num_attachment_objects = 0;
09274         for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData();
09275                 attachment;
09276                 attachment = mAttachmentPoints.getNextData())
09277                 {
09278                         LLViewerObject *attached_object = attachment->getObject();
09279                         if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull() &&
09280                                 attached_object->getPCode() == LL_PCODE_VOLUME)
09281                         {
09282                                 num_attachment_objects += attached_object->mDrawable->getNumFaces(); 
09283                                 for (U32 i = 0; i < attached_object->mChildList.size(); i++)
09284                                 {
09285                                         LLViewerObject* child_object = attached_object->mChildList[i];
09286                                         num_attachment_objects += child_object->mDrawable->getNumFaces();
09287                                 }
09288                         }
09289                 }
09290 
09291         apr_file_printf(fp, "<MESH VERSION=\"1000\" NUMSUBMESH=\"%d\">\n", num_attachment_objects);
09292 
09293         S32 material_index = 6;
09294         S32 texture_index = 6;
09295         for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData();
09296                 attachment;
09297                 attachment = mAttachmentPoints.getNextData())
09298                 {
09299                         LLViewerObject *attached_object = attachment->getObject();
09300                         if (attached_object && !attached_object->isDead() && attached_object->getPCode() == LL_PCODE_VOLUME)
09301                         {
09302                                 LLVOVolume* attached_volume = (LLVOVolume*)attached_object;
09303                                 LLVector3 pos = attachment->getPosition();
09304                                 LLJoint* cur_joint = attachment->getParent();
09305                                 while (cur_joint)
09306                                 {
09307                                         pos += cur_joint->getSkinOffset();
09308                                         cur_joint = (LLViewerJoint*)cur_joint->getParent();
09309                                 }
09310                                 pos *= 100.f;
09311                                 S32 attached_joint_num = attachment->getParent()->mJointNum;
09312                                 LLQuaternion rot = attachment->getRotation();
09313                                 attached_volume->writeCAL3D(fp, path, file_base, attached_joint_num, pos, rot, material_index, texture_index, material_map);
09314                         }
09315                 }
09316         apr_file_printf(fp, "</MESH>\n");
09317         apr_file_close(fp);
09318 
09319         // now dump sample animation
09320         LLKeyframeMotion* walk_motion = 
09321                 getSex() == SEX_MALE ? (LLKeyframeMotion*)findMotion(ANIM_AGENT_WALK) : (LLKeyframeMotion*)findMotion(ANIM_AGENT_FEMALE_WALK);
09322         if (FALSE)//(walk_motion)
09323         {
09324                 snprintf(filename, MAX_PATH, "%s\\%s_anim.xaf", path.c_str(), file_base.c_str());               /* Flawfinder: ignore */
09325                 apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W);
09326                 if (!fp)
09327                 {
09328                         llwarns << "Unable to write avatar animation file " << filename << llendl;
09329                         return;
09330                 }
09331 
09332                 walk_motion->writeCAL3D(fp);
09333 
09334                 apr_file_close(fp);
09335         }
09336 
09337         // finally, write out .cfg file
09338         snprintf(filename, MAX_PATH, "%s\\%s_avatar.cfg", path.c_str(), file_base.c_str());             /* Flawfinder: ignore */
09339         fp = ll_apr_file_open(filename, LL_APR_W);
09340         if (!fp)
09341         {
09342                 llwarns << "Unable to write avatar config file " << filename << llendl;
09343                 return;
09344         }
09345 
09346         // this version exports animation
09347         //apr_file_printf(fp, "#\n# cal3d model configuration file\n#\n# model: %s_avatar\n#\n\nscale=1.0\n\nskeleton=%s_skeleton.xsf\n\nanimation=%s_anim.xaf\n\n", file_base.c_str(), file_base.c_str(), file_base.c_str());
09348         apr_file_printf(fp, "#\n# cal3d model configuration file\n#\n# model: %s_avatar\n#\n\nscale=1.0\n\nskeleton=%s_skeleton.xsf\n\n", file_base.c_str(), file_base.c_str());
09349         apr_file_printf(fp, "mesh=%s_mesh_body.xmf\nmesh=%s_mesh_attachments.xmf\n", file_base.c_str(), file_base.c_str());
09350 
09351         for (S32 i = 0; i < material_index; i++)
09352         {
09353                 apr_file_printf(fp, "material=%s_material_%d.xrf\n", file_base.c_str(), i);
09354         }
09355         apr_file_close(fp);
09356 
09357         for(S32 i = 0; i < 6; i++)
09358         {
09359                 snprintf(filename, MAX_PATH, "%s\\%s_material_%d.xrf", path.c_str(), file_base.c_str(), i);             /* Flawfinder: ignore */
09360                 apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W);
09361                 if (!fp)
09362                 {
09363                         llwarns << "Unable to write material definition file " << filename << llendl;
09364                         return;
09365                 }
09366 
09367                 // for hair material, use hair color...otherwise use white for entire body
09368                 LLColor4U material_color = (i == 5) ? mTexHairColor->getColor() : LLColor4U::white;
09369 
09370                 apr_file_printf(fp, "<HEADER MAGIC=\"XRF\" VERSION=\"900\" />\n<MATERIAL NUMMAPS=\"1\">\n");
09371                 apr_file_printf(fp, "   <AMBIENT>%d %d %d %d</AMBIENT>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
09372                 apr_file_printf(fp, "   <DIFFUSE>%d %d %d %d</DIFFUSE>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
09373                 apr_file_printf(fp, "   <SPECULAR>0 0 0 0</SPECULAR>\n");
09374                 apr_file_printf(fp, "   <SHININESS>1.0</SHININESS>\n");
09375                 apr_file_printf(fp, "   <MAP>%s_material_tex_%d.tga</MAP>\n", file_base.c_str(), i);
09376                 apr_file_printf(fp, "</MATERIAL>\n");
09377 
09378                 apr_file_close(fp);
09379         }
09380         
09381         // write out material files
09382         for(material_it_t material_it = material_map.begin(); material_it != material_map.end(); ++material_it)
09383         {
09384                 LLMaterialExportInfo* export_info = material_it->second;
09385 
09386                 snprintf(filename, MAX_PATH, "%s\\%s_material_%d.xrf", path.c_str(), file_base.c_str(), export_info->mMaterialIndex);           /* Flawfinder: ignore */
09387                 apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W);
09388                 if (!fp)
09389                 {
09390                         llwarns << "Unable to write material definition file " << filename << llendl;
09391                         return;
09392                 }
09393 
09394                 LLColor4U material_color = export_info->mColor;
09395 
09396                 apr_file_printf(fp, "<HEADER MAGIC=\"XRF\" VERSION=\"900\" />\n<MATERIAL NUMMAPS=\"1\">\n");
09397                 apr_file_printf(fp, "   <AMBIENT>%d %d %d %d</AMBIENT>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
09398                 apr_file_printf(fp, "   <DIFFUSE>%d %d %d %d</DIFFUSE>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]);
09399                 apr_file_printf(fp, "   <SPECULAR>0 0 0 0</SPECULAR>\n");
09400                 apr_file_printf(fp, "   <SHININESS>1.0</SHININESS>\n");
09401                 apr_file_printf(fp, "   <MAP>%s_material_tex_%d.tga</MAP>\n", file_base.c_str(), export_info->mTextureIndex);
09402                 apr_file_printf(fp, "</MATERIAL>\n");
09403 
09404                 apr_file_close(fp);
09405         }
09406 
09407 
09408         std::for_each(material_map.begin(), material_map.end(), DeletePairedPointer());
09409         material_map.clear();
09410 }
09411 
09412 // warning: order(N) not order(1)
09413 S32 LLVOAvatar::getAttachmentCount()
09414 {
09415         S32 count = mAttachmentPoints.getLength();
09416         return count;
09417 }
09418 
09419 //virtual
09420 void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
09421 {
09422         if (mIsSelf)
09423         {
09424                 if (regionp->getHandle() != mLastRegionHandle)
09425                 {
09426                         if (mLastRegionHandle != 0)
09427                         {
09428                                 ++mRegionCrossingCount;
09429                                 F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32();
09430                                 F64 avg = (mRegionCrossingCount == 1) ? 0 : gViewerStats->getStat(LLViewerStats::ST_CROSSING_AVG);
09431                                 F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount;
09432                                 gViewerStats->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg);
09433 
09434                                 F64 max = (mRegionCrossingCount == 1) ? 0 : gViewerStats->getStat(LLViewerStats::ST_CROSSING_MAX);
09435                                 max = llmax(delta, max);
09436                                 gViewerStats->setStat(LLViewerStats::ST_CROSSING_MAX, max);
09437                         }
09438                         mLastRegionHandle = regionp->getHandle();
09439                 }
09440                 mRegionCrossingTimer.reset();
09441         }
09442 }
09443 
09444 LLString LLVOAvatar::getFullname() const
09445 {
09446         LLString name;
09447 
09448         LLNameValue* first = getNVPair("FirstName"); 
09449         LLNameValue* last  = getNVPair("LastName"); 
09450         if (first && last)
09451         {
09452                 name += first->getString();
09453                 name += " ";
09454                 name += last->getString();
09455         }
09456 
09457         return name;
09458 }
09459 
09460 LLTexLayerSet* LLVOAvatar::getLayerSet(ETextureIndex index) const
09461 {
09462         switch( index )
09463         {
09464         case TEX_HEAD_BAKED:
09465         case TEX_HEAD_BODYPAINT:
09466                 return mHeadLayerSet;
09467 
09468         case TEX_UPPER_BAKED:
09469         case TEX_UPPER_SHIRT:
09470         case TEX_UPPER_BODYPAINT:
09471         case TEX_UPPER_JACKET:
09472         case TEX_UPPER_GLOVES:
09473         case TEX_UPPER_UNDERSHIRT:
09474                 return mUpperBodyLayerSet;
09475 
09476         case TEX_LOWER_BAKED:
09477         case TEX_LOWER_PANTS:
09478         case TEX_LOWER_BODYPAINT:
09479         case TEX_LOWER_SHOES:
09480         case TEX_LOWER_SOCKS:
09481         case TEX_LOWER_JACKET:
09482         case TEX_LOWER_UNDERPANTS:
09483                 return mLowerBodyLayerSet;
09484         
09485         case TEX_EYES_BAKED:
09486         case TEX_EYES_IRIS:
09487                 return mEyesLayerSet;
09488 
09489         case TEX_SKIRT_BAKED:
09490         case TEX_SKIRT:
09491                 return mSkirtLayerSet;
09492 
09493         case TEX_HAIR:
09494         default:
09495                 return NULL;
09496         }
09497 }
09498 
09499 LLHost LLVOAvatar::getObjectHost() const
09500 {
09501         LLViewerRegion* region = getRegion();
09502         if (region && !isDead())
09503         {
09504                 return region->getHost();
09505         }
09506         else
09507         {
09508                 return LLHost::invalid;
09509         }
09510 }
09511 
09512 BOOL LLVOAvatar::updateLOD()
09513 {
09514         BOOL res = updateJointLODs();
09515 
09516         LLFace* facep = mDrawable->getFace(0);
09517         if (facep->mVertexBuffer.isNull() ||
09518                 LLVertexBuffer::sEnableVBOs &&
09519                 ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
09520                 (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))
09521         {
09522                 mDirtyMesh = TRUE;
09523         }
09524 
09525         if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
09526         {       //LOD changed or new mesh created, allocate new vertex buffer if needed
09527                 updateMeshData();
09528         mDirtyMesh = FALSE;
09529                 mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
09530         }
09531         
09532         if (facep->getPool()->getVertexShaderLevel() <= 0)
09533         {
09534                 //generate animated mesh
09535                 mLowerBodyLOD.updateGeometry();
09536                 mUpperBodyLOD.updateGeometry();
09537 
09538                 if( isWearingWearableType( WT_SKIRT ) )
09539                 {
09540                         mSkirtLOD.updateGeometry();
09541                 }
09542 
09543                 if (!mIsSelf || gAgent.needsRenderHead())
09544                 {
09545                         mEyeLashLOD.updateGeometry();
09546                         mHeadLOD.updateGeometry();
09547                         mHairLOD.updateGeometry();
09548                 }
09549         }
09550 
09551         // Update the shadow, tractor, and text label geometry.
09552         if (mDrawable->isState(LLDrawable::REBUILD_SHADOW))
09553         {
09554                 updateShadowFaces();
09555                 mDrawable->clearState(LLDrawable::REBUILD_SHADOW);
09556         }
09557 
09558         return res;
09559 }
09560 
09561 U32 LLVOAvatar::getPartitionType() const
09562 { //avatars merely exist as drawables in the bridge partition
09563         return LLPipeline::PARTITION_BRIDGE;
09564 }
09565 

Generated on Thu Jul 1 06:09:36 2010 for Second Life Viewer by  doxygen 1.4.7