00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "stdtypes.h"
00035 #include "stdenums.h"
00036 
00037 #include "llagent.h" 
00038 
00039 #include "llcoordframe.h"
00040 #include "indra_constants.h"
00041 #include "llmath.h"
00042 #include "llcriticaldamp.h"
00043 #include "llfocusmgr.h"
00044 #include "llglheaders.h"
00045 #include "llparcel.h"
00046 #include "llpermissions.h"
00047 #include "llregionhandle.h"
00048 #include "m3math.h"
00049 #include "m4math.h"
00050 #include "message.h"
00051 #include "llquaternion.h"
00052 #include "v3math.h"
00053 #include "v4math.h"
00054 #include "llsdutil.h"
00055 
00056 
00057 #include "imageids.h"
00058 #include "llbox.h"
00059 #include "llbutton.h"
00060 #include "llcameraview.h"
00061 #include "llcallingcard.h"
00062 #include "llchatbar.h"
00063 #include "llconsole.h"
00064 #include "lldrawable.h"
00065 #include "llface.h"
00066 #include "llfirstuse.h"
00067 #include "llfloater.h"
00068 #include "llfloateractivespeakers.h"
00069 #include "llfloateravatarinfo.h"
00070 #include "llfloateravatarlist.h"
00071 #include "llfloaterbuildoptions.h"
00072 #include "llfloaterchat.h"
00073 #include "llfloatercustomize.h"
00074 #include "llfloaterdirectory.h"
00075 #include "llfloatergroupinfo.h"
00076 #include "llfloatergroups.h"
00077 #include "llfloatermap.h"
00078 #include "llfloatermute.h"
00079 #include "llfloatersnapshot.h"
00080 #include "llfloatertools.h"
00081 #include "llfloaterworldmap.h"
00082 #include "llgroupmgr.h"
00083 #include "llhudeffectlookat.h"
00084 #include "llhudmanager.h"
00085 #include "llinventorymodel.h"
00086 #include "llinventoryview.h"
00087 #include "lljoystickbutton.h"
00088 #include "llmenugl.h"
00089 #include "llmorphview.h"
00090 #include "llmoveview.h"
00091 #include "llnotify.h"
00092 #include "llquantize.h"
00093 #include "llselectmgr.h"
00094 #include "llsky.h"
00095 #include "llsphere.h"
00096 #include "llstatusbar.h"
00097 #include "llimview.h"
00098 #include "lltool.h"
00099 #include "lltoolcomp.h"         
00100 #include "lltoolfocus.h"
00101 #include "lltoolgrab.h"
00102 #include "lltoolmgr.h"
00103 #include "lltoolpie.h"
00104 #include "lltoolview.h"
00105 #include "llui.h"                       
00106 #include "llviewercamera.h"
00107 #include "llviewerinventory.h"
00108 #include "llviewermenu.h"
00109 #include "llviewernetwork.h"
00110 #include "llviewerobjectlist.h"
00111 #include "llviewerparcelmgr.h"
00112 #include "llviewerparceloverlay.h"
00113 #include "llviewerregion.h"
00114 #include "llviewerstats.h"
00115 #include "llviewerwindow.h"
00116 #include "llvoavatar.h"
00117 #include "llvoground.h"
00118 #include "llvosky.h"
00119 #include "llwearable.h"
00120 #include "llwearablelist.h"
00121 #include "llworld.h"
00122 #include "llworldmap.h"
00123 #include "pipeline.h"
00124 #include "roles_constants.h"
00125 #include "viewer.h"
00126 #include "llvoiceclient.h"
00127 
00128 
00129 #include "llfollowcam.h"
00130 
00131 
00132 extern LLMenuBarGL* gMenuBarView;
00133 extern U8 gLastPickAlpha;
00134 extern F32 gFrameDTClamped;
00135 
00136 
00137 const F32 MAX_WANDER_TIME = 20.f;                                               
00138 const F32 MAX_HEADING_HALF_ERROR = 0.2f;                                
00139 const F32 WANDER_MAX_SLEW_RATE = 2.f * DEG_TO_RAD;              
00140 const F32 WANDER_TARGET_MIN_DISTANCE = 10.f;                    
00141 
00142 
00143 const F32 AUTOPILOT_HEADING_HALF_ERROR = 10.f * DEG_TO_RAD;     
00144 const F32 AUTOPILOT_MAX_SLEW_RATE = 1.f * DEG_TO_RAD;           
00145 const F32 AUTOPILOT_STOP_DISTANCE = 2.f;                                        
00146 const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f;                       
00147 const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f; 
00148 const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f;                
00149 
00150 
00151 const LLVector3d FACE_EDIT_CAMERA_OFFSET(0.4f, -0.05f, 0.07f);
00152 const LLVector3d FACE_EDIT_TARGET_OFFSET(0.f, 0.f, 0.05f);
00153 
00154 
00155 const F32 MIN_ZOOM_FRACTION = 0.25f;
00156 const F32 INITIAL_ZOOM_FRACTION = 1.f;
00157 const F32 MAX_ZOOM_FRACTION = 8.f;
00158 const F32 METERS_PER_WHEEL_CLICK = 1.f;
00159 
00160 const F32 MAX_TIME_DELTA = 1.f;
00161 
00162 const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f;        
00163 const F32 FOV_ZOOM_HALF_LIFE = 0.07f;   
00164 
00165 const F32 CAMERA_FOCUS_HALF_LIFE = 0.f;
00166 const F32 CAMERA_LAG_HALF_LIFE = 0.25f;
00167 const F32 MIN_CAMERA_LAG = 0.5f;
00168 const F32 MAX_CAMERA_LAG = 5.f;
00169 
00170 const F32 CAMERA_COLLIDE_EPSILON = 0.1f;
00171 const F32 MIN_CAMERA_DISTANCE = 0.1f;
00172 const F32 AVATAR_ZOOM_MIN_X_FACTOR = 0.55f;
00173 const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
00174 const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
00175 
00176 const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
00177 
00178 const F32 HEAD_BUFFER_SIZE = 0.3f;
00179 const F32 CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP = 0.2f;
00180 
00181 const F32 LAND_MIN_ZOOM = 0.15f;
00182 const F32 AVATAR_MIN_ZOOM = 0.5f;
00183 const F32 OBJECT_MIN_ZOOM = 0.02f;
00184 
00185 const F32 APPEARANCE_MIN_ZOOM = 0.39f;
00186 const F32 APPEARANCE_MAX_ZOOM = 8.f;
00187 
00188 
00189 const F32 MIN_FIDGET_TIME = 8.f; 
00190 const F32 MAX_FIDGET_TIME = 20.f; 
00191 
00192 const S32 MAX_NUM_CHAT_POSITIONS = 10;
00193 const F32 GROUND_TO_AIR_CAMERA_TRANSITION_TIME = 0.5f;
00194 const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f;
00195 
00196 const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
00197 
00198 const F32 MAX_FOCUS_OFFSET = 20.f;
00199 
00200 const F32 OBJECT_EXTENTS_PADDING = 0.5f;
00201 
00202 const F32 MIN_RADIUS_ALPHA_SIZZLE = 0.5f;
00203 
00204 const F64 CHAT_AGE_FAST_RATE = 3.0;
00205 
00206 const S32 MAX_WEARABLES_PER_LAYERSET = 7;
00207 
00208 const EWearableType WEARABLE_BAKE_TEXTURE_MAP[BAKED_TEXTURE_COUNT][MAX_WEARABLES_PER_LAYERSET] = 
00209 {
00210         { WT_SHAPE,     WT_SKIN,        WT_HAIR,        WT_INVALID,     WT_INVALID,     WT_INVALID,             WT_INVALID    },        
00211         { WT_SHAPE, WT_SKIN,    WT_SHIRT,       WT_JACKET,      WT_GLOVES,      WT_UNDERSHIRT,  WT_INVALID        },    
00212         { WT_SHAPE, WT_SKIN,    WT_PANTS,       WT_SHOES,       WT_SOCKS,       WT_JACKET,              WT_UNDERPANTS },        
00213         { WT_EYES,      WT_INVALID,     WT_INVALID,     WT_INVALID,     WT_INVALID,     WT_INVALID,             WT_INVALID    },        
00214         { WT_SKIRT,     WT_INVALID,     WT_INVALID,     WT_INVALID,     WT_INVALID,     WT_INVALID,             WT_INVALID    }         
00215 };
00216 
00217 const LLUUID BAKED_TEXTURE_HASH[BAKED_TEXTURE_COUNT] = 
00218 {
00219         LLUUID("18ded8d6-bcfc-e415-8539-944c0f5ea7a6"),
00220         LLUUID("338c29e3-3024-4dbb-998d-7c04cf4fa88f"),
00221         LLUUID("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f"),
00222         LLUUID("b2cf28af-b840-1071-3c6a-78085d8128b5"),
00223         LLUUID("ea800387-ea1a-14e0-56cb-24f2022f969a")
00224 };
00225 
00226 
00227 
00228 
00229 BOOL LLAgent::sDebugDisplayTarget = FALSE;
00230 
00231 const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
00232 
00233 std::map<LLString, LLString> LLAgent::sTeleportErrorMessages;
00234 std::map<LLString, LLString> LLAgent::sTeleportProgressMessages;
00235 
00236 class LLAgentFriendObserver : public LLFriendObserver
00237 {
00238 public:
00239         LLAgentFriendObserver() {}
00240         virtual ~LLAgentFriendObserver() {}
00241         virtual void changed(U32 mask);
00242 };
00243 
00244 void LLAgentFriendObserver::changed(U32 mask)
00245 {
00246         
00247         if((mask & (LLFriendObserver::POWERS)) != 0)
00248         {
00249                 gAgent.friendsChanged();
00250         }
00251 }
00252 
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 LLAgent::LLAgent()
00269 :       mViewerPort(NET_USE_OS_ASSIGNED_PORT),
00270         mDrawDistance( DEFAULT_FAR_PLANE ),
00271         mAccess(SIM_ACCESS_PG),
00272         mGroupPowers(0),
00273         mGroupID(),
00274         
00275         mMapOriginX(0),
00276         mMapOriginY(0),
00277         mMapWidth(0),
00278         mMapHeight(0),
00279         mLookAt(NULL),
00280         mPointAt(NULL),
00281         mInitialized(FALSE),
00282         mNumPendingQueries(0),
00283         mForceMouselook(FALSE),
00284         mTeleportState( TELEPORT_NONE ),
00285         mRegionp(NULL),
00286 
00287         mAgentOriginGlobal(),
00288         mPositionGlobal(),
00289 
00290         mDistanceTraveled(0),
00291         mLastPositionGlobal(LLVector3d::zero),
00292 
00293         mAvatarObject(NULL),
00294 
00295         mRenderState(0),
00296         mTypingTimer(),
00297 
00298         mCameraMode( CAMERA_MODE_THIRD_PERSON ),
00299         mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
00300         mViewsPushed(FALSE),
00301 
00302         mbAlwaysRun(FALSE),
00303         mShowAvatar(TRUE),
00304 
00305         mCameraAnimating( FALSE ),
00306         mAnimationCameraStartGlobal(),
00307         mAnimationFocusStartGlobal(),
00308         mAnimationTimer(),
00309         mAnimationDuration(0.33f),
00310         mCameraFOVZoomFactor(0.f),
00311         mCameraCurrentFOVZoomFactor(0.f),
00312         mCameraFocusOffset(),
00313         mCameraOffsetDefault(),
00314 
00315         mCameraCollidePlane(),
00316         mCurrentCameraDistance(2.f),            
00317         mTargetCameraDistance(2.f),
00318         mCameraZoomFraction(1.f),                       
00319         mThirdPersonHeadOffset(0.f, 0.f, 1.f),
00320         mSitCameraEnabled(FALSE),
00321         mFocusOnAvatar(TRUE),
00322         mFocusGlobal(),
00323         mFocusTargetGlobal(),
00324         mFocusObject(NULL),
00325         mFocusObjectOffset(),
00326         mFocusDotRadius( 0.1f ),                        
00327         mTrackFocusObject(TRUE),
00328 
00329         mFrameAgent(),
00330 
00331         mCrouching(FALSE),
00332         mIsBusy(FALSE),
00333 
00334         
00335 
00336         mControlFlags(0x00000000),
00337         mbFlagsDirty(FALSE),
00338         mbFlagsNeedReset(FALSE),
00339 
00340         mbJump(FALSE),
00341 
00342         mAutoPilot(FALSE),
00343         mAutoPilotFlyOnStop(FALSE),
00344         mAutoPilotTargetGlobal(),
00345         mAutoPilotStopDistance(1.f),
00346         mAutoPilotUseRotation(FALSE),
00347         mAutoPilotTargetFacing(LLVector3::zero),
00348         mAutoPilotTargetDist(0.f),
00349         mAutoPilotFinishedCallback(NULL),
00350         mAutoPilotCallbackData(NULL),
00351         
00352 
00353         mEffectColor(0.f, 1.f, 1.f, 1.f),
00354         mHaveHomePosition(FALSE),
00355         mHomeRegionHandle( 0 ),
00356         mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f),
00357         mGodLevel( GOD_NOT ),
00358 
00359 
00360         mNextFidgetTime(0.f),
00361         mCurrentFidget(0),
00362         mFirstLogin(FALSE),
00363         mGenderChosen(FALSE),
00364         mAgentWearablesUpdateSerialNum(0),
00365         mWearablesLoaded(FALSE),
00366         mTextureCacheQueryID(0),
00367         mAppearanceSerialNum(0)
00368 {
00369 
00370         U32 i;
00371         for (i = 0; i < TOTAL_CONTROLS; i++)
00372         {
00373                 mControlsTakenCount[i] = 0;
00374                 mControlsTakenPassedOnCount[i] = 0;
00375         }
00376 
00377         
00378         mAtKey                          = 0;    
00379         mWalkKey                        = 0;    
00380         mLeftKey                        = 0;
00381         mUpKey                          = 0;
00382         mYawKey                         = 0.f;
00383         mPitchKey                       = 0;
00384 
00385         mOrbitLeftKey           = 0.f;
00386         mOrbitRightKey          = 0.f;
00387         mOrbitUpKey                     = 0.f;
00388         mOrbitDownKey           = 0.f;
00389         mOrbitInKey                     = 0.f;
00390         mOrbitOutKey            = 0.f;
00391 
00392         mPanUpKey                       = 0.f;
00393         mPanDownKey                     = 0.f;
00394         mPanLeftKey                     = 0.f;
00395         mPanRightKey            = 0.f;
00396         mPanInKey                       = 0.f;
00397         mPanOutKey                      = 0.f;
00398 
00399         mActiveCacheQueries = new S32[BAKED_TEXTURE_COUNT];
00400         for (i = 0; i < (U32)BAKED_TEXTURE_COUNT; i++)
00401         {
00402                 mActiveCacheQueries[i] = 0;
00403         }
00404 
00405         
00406         mCameraUpVector = LLVector3::z_axis;
00407         mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
00408         
00409 }
00410 
00411 
00412 
00413 
00414 
00415 void LLAgent::init()
00416 {
00417         mDrawDistance = gSavedSettings.getF32("RenderFarClip");
00418 
00419         gCamera = new LLViewerCamera();
00420 
00421         gCamera->setView(DEFAULT_FIELD_OF_VIEW);
00422         
00423         gCamera->setNear(0.1f);
00424         gCamera->setFar(mDrawDistance);                 
00425         gCamera->setAspect( gViewerWindow->getDisplayAspectRatio() );           
00426         gCamera->setViewHeightInPixels(768);                    
00427 
00428         setFlying( gSavedSettings.getBOOL("FlyingAtExit") );
00429 
00430         mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
00431         mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault");
00432 
00433 
00434         mCameraCollidePlane.clearVec();
00435         mCurrentCameraDistance = mCameraOffsetDefault.magVec();
00436         mTargetCameraDistance = mCurrentCameraDistance;
00437         mCameraZoomFraction = 1.f;
00438         mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
00439 
00440 
00441         gSavedSettings.getControl("RenderHideGroupTitle")->addListener(&mHideGroupTitleListener);
00442         gSavedSettings.getControl("EffectColor")->addListener(&mEffectColorListener);
00443 
00444         mEffectColor = gSavedSettings.getColor4("EffectColor");
00445         
00446         mInitialized = TRUE;
00447 }
00448 
00449 
00450 
00451 
00452 void LLAgent::cleanup()
00453 {
00454         setSitCamera(LLUUID::null);
00455         mAvatarObject = NULL;
00456         mLookAt = NULL;
00457         mPointAt = NULL;
00458         mRegionp = NULL;
00459         setFocusObject(NULL);
00460         mFadeObjects.clear();
00461 }
00462 
00463 
00464 
00465 
00466 LLAgent::~LLAgent()
00467 {
00468         cleanup();
00469 
00470         delete [] mActiveCacheQueries;
00471         mActiveCacheQueries = NULL;
00472 
00473         delete gCamera;
00474         gCamera = NULL;
00475 }
00476 
00477 
00478 
00479 
00480 
00481 
00482 void LLAgent::resetView(BOOL reset_camera)
00483 {
00484         if (mAutoPilot)
00485         {
00486                 stopAutoPilot(TRUE);
00487         }
00488 
00489         if (!gNoRender)
00490         {
00491                 gSelectMgr->unhighlightAll();
00492 
00493                 
00494                 
00495 
00496                 
00497                 
00498                 if (gSelectMgr->getSelection()->isAttachment())
00499                 {
00500                         gSelectMgr->deselectAll();
00501                 }
00502 
00503                 
00504                 gMenuHolder->hideMenus();
00505         }
00506 
00507         if (reset_camera && !gSavedSettings.getBOOL("FreezeTime"))
00508         {
00509                 if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson())
00510                 {
00511                         
00512                         LLVector3 agent_at_axis = getAtAxis();
00513                         agent_at_axis -= projected_vec(agent_at_axis, getReferenceUpVector());
00514                         agent_at_axis.normVec();
00515                         gAgent.resetAxes(lerp(getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f)));
00516                 }
00517 
00518                 setFocusOnAvatar(TRUE, ANIMATE);
00519         }
00520 
00521         if (mAvatarObject.notNull())
00522         {
00523                 mAvatarObject->mHUDTargetZoom = 1.f;
00524         }
00525 }
00526 
00527 void LLAgent::ageChat()
00528 {
00529         if (mAvatarObject)
00530         {
00531                 
00532                 F64 elapsed_time = (F64)mAvatarObject->mChatTimer.getElapsedTimeF32();
00533                 
00534                 mAvatarObject->mChatTimer.setAge(elapsed_time + (F64)gFrameDTClamped * (CHAT_AGE_FAST_RATE - 1.0));
00535         }
00536 }
00537 
00538 
00539 
00540 
00541 
00542 void LLAgent::unlockView()
00543 {
00544         if (getFocusOnAvatar())
00545         {
00546                 if (mAvatarObject)
00547                 {
00548                         setFocusGlobal( LLVector3d::zero, mAvatarObject->mID );
00549                 }
00550                 setFocusOnAvatar(FALSE, FALSE); 
00551         }
00552 }
00553 
00554 
00555 
00556 
00557 
00558 void LLAgent::moveAt(S32 direction)
00559 {
00560         
00561         ageChat();
00562 
00563         setKey(direction, mAtKey);
00564 
00565         if (direction > 0)
00566         {
00567                 setControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_FAST_AT);
00568         }
00569         else if (direction < 0)
00570         {
00571                 setControlFlags(AGENT_CONTROL_AT_NEG | AGENT_CONTROL_FAST_AT);
00572         }
00573 
00574         resetView();
00575 }
00576 
00577 
00578 
00579 
00580 void LLAgent::moveAtNudge(S32 direction)
00581 {
00582         
00583         ageChat();
00584 
00585         setKey(direction, mWalkKey);
00586 
00587         if (direction > 0)
00588         {
00589                 setControlFlags(AGENT_CONTROL_NUDGE_AT_POS);
00590         }
00591         else if (direction < 0)
00592         {
00593                 setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG);
00594         }
00595 
00596         resetView();
00597 }
00598 
00599 
00600 
00601 
00602 void LLAgent::moveLeft(S32 direction)
00603 {
00604         
00605         ageChat();
00606 
00607         setKey(direction, mLeftKey);
00608 
00609         if (direction > 0)
00610         {
00611                 setControlFlags(AGENT_CONTROL_LEFT_POS | AGENT_CONTROL_FAST_LEFT);
00612         }
00613         else if (direction < 0)
00614         {
00615                 setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT);
00616         }
00617 
00618         resetView();
00619 }
00620 
00621 
00622 
00623 
00624 void LLAgent::moveLeftNudge(S32 direction)
00625 {
00626         
00627         ageChat();
00628 
00629         setKey(direction, mLeftKey);
00630 
00631         if (direction > 0)
00632         {
00633                 setControlFlags(AGENT_CONTROL_NUDGE_LEFT_POS);
00634         }
00635         else if (direction < 0)
00636         {
00637                 setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG);
00638         }
00639 
00640         resetView();
00641 }
00642 
00643 
00644 
00645 
00646 void LLAgent::moveUp(S32 direction)
00647 {
00648         
00649         ageChat();
00650 
00651         setKey(direction, mUpKey);
00652 
00653         if (direction > 0)
00654         {
00655                 setControlFlags(AGENT_CONTROL_UP_POS | AGENT_CONTROL_FAST_UP);
00656         }
00657         else if (direction < 0)
00658         {
00659                 setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP);
00660         }
00661 
00662         resetView();
00663 }
00664 
00665 
00666 
00667 
00668 void LLAgent::moveYaw(F32 mag)
00669 {
00670         mYawKey = mag;
00671 
00672         if (mag > 0)
00673         {
00674                 setControlFlags(AGENT_CONTROL_YAW_POS);
00675         }
00676         else if (mag < 0)
00677         {
00678                 setControlFlags(AGENT_CONTROL_YAW_NEG);
00679         }
00680 
00681         resetView();
00682 }
00683 
00684 
00685 
00686 
00687 void LLAgent::movePitch(S32 direction)
00688 {
00689         setKey(direction, mPitchKey);
00690 
00691         if (direction > 0)
00692         {
00693                 setControlFlags(AGENT_CONTROL_PITCH_POS );
00694         }
00695         else if (direction < 0)
00696         {
00697                 setControlFlags(AGENT_CONTROL_PITCH_NEG);
00698         }
00699 }
00700 
00701 
00702 
00703 BOOL LLAgent::canFly()
00704 {
00705         if (isGodlike()) return TRUE;
00706 
00707         if (!gParcelMgr) return FALSE;
00708 
00709         LLViewerRegion* regionp = getRegion();
00710         if (regionp && regionp->getBlockFly()) return FALSE;
00711         
00712         LLParcel* parcel = gParcelMgr->getAgentParcel();
00713         if (!parcel) return FALSE;
00714 
00715         
00716         if (LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_ALLOW_FLY))
00717         {
00718                 return TRUE;
00719         }
00720 
00721         return parcel->getAllowFly();
00722 }
00723 
00724 
00725 
00726 
00727 
00728 void LLAgent::setFlying(BOOL fly)
00729 {
00730         if (mAvatarObject.notNull())
00731         {
00732                 if(mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_STANDUP) != mAvatarObject->mSignaledAnimations.end())
00733                 {
00734                         return;
00735                 }
00736 
00737                 
00738                 if (fly && mAvatarObject->mIsSitting)
00739                 {
00740                         return;
00741                 }
00742         }
00743 
00744         if (fly)
00745         {
00746                 BOOL was_flying = getFlying();
00747                 if (gParcelMgr)
00748                 {
00749                         if (!canFly() && !was_flying)
00750                         {
00751                                 
00752                                 
00753                                 
00754                                 make_ui_sound("UISndBadKeystroke");
00755                                 return;
00756                         }
00757                 }
00758                 if( !was_flying )
00759                 {
00760                         gViewerStats->incStat(LLViewerStats::ST_FLY_COUNT);
00761                 }
00762                 setControlFlags(AGENT_CONTROL_FLY);
00763                 gSavedSettings.setBOOL("FlyBtnState", TRUE);
00764         }
00765         else
00766         {
00767                 clearControlFlags(AGENT_CONTROL_FLY);
00768                 gSavedSettings.setBOOL("FlyBtnState", FALSE);
00769         }
00770         mbFlagsDirty = TRUE;
00771 }
00772 
00773 
00774 
00775 
00776 
00777 
00778 void LLAgent::toggleFlying()
00779 {
00780         BOOL fly = !(mControlFlags & AGENT_CONTROL_FLY);
00781 
00782         setFlying( fly );
00783         resetView();
00784 }
00785 
00786 
00787 
00788 
00789 
00790 void LLAgent::setRegion(LLViewerRegion *regionp)
00791 {
00792         llassert(regionp);
00793         if (mRegionp != regionp)
00794         {
00795                 
00796                 
00797                 
00798                 
00799 
00800                 char ip[MAX_STRING];            
00801                 regionp->getHost().getString(ip, MAX_STRING);
00802                 llinfos << "Moving agent into region: " << regionp->getName()
00803                                 << " located at " << ip << llendl;
00804                 if (mRegionp)
00805                 {
00806                         
00807                         mAgentOriginGlobal = regionp->getOriginGlobal();
00808                         LLVector3d agent_offset_global = mRegionp->getOriginGlobal();
00809 
00810                         LLVector3 delta;
00811                         delta.setVec(regionp->getOriginGlobal() - mRegionp->getOriginGlobal());
00812 
00813                         setPositionAgent(getPositionAgent() - delta);
00814                         LLVector3 camera_position_agent = gCamera->getOrigin();
00815                         gCamera->setOrigin(camera_position_agent - delta);
00816 
00817                         
00818                         gWorldPointer->updateAgentOffset(agent_offset_global);
00819 
00820                         
00821                         if (gSky.mVOSkyp)
00822                         {
00823                                 gSky.mVOSkyp->setRegion(regionp);
00824                         }
00825                         if (gSky.mVOStarsp)
00826                         {
00827                                 gSky.mVOStarsp->setRegion(regionp);
00828                         }
00829                         if (gSky.mVOGroundp)
00830                         {
00831                                 gSky.mVOGroundp->setRegion(regionp);
00832                         }
00833 
00834                 }
00835                 else
00836                 {
00837                         
00838                         
00839                         mAgentOriginGlobal = regionp->getOriginGlobal();
00840 
00841                         LLVector3 delta;
00842                         delta.setVec(regionp->getOriginGlobal());
00843 
00844                         setPositionAgent(getPositionAgent() - delta);
00845                         LLVector3 camera_position_agent = gCamera->getOrigin();
00846                         gCamera->setOrigin(camera_position_agent - delta);
00847 
00848                         
00849                         gWorldPointer->updateAgentOffset(mAgentOriginGlobal);
00850                 }
00851         }
00852         mRegionp = regionp;
00853 
00854         
00855         
00856         gWorldPointer->updateWaterObjects();
00857 
00858         
00859         
00860         
00861         U64 handle = regionp->getHandle();
00862         mRegionsVisited.insert(handle);
00863 
00864         gSelectMgr->updateSelectionCenter();
00865 }
00866 
00867 
00868 
00869 
00870 
00871 LLViewerRegion *LLAgent::getRegion() const
00872 {
00873         return mRegionp;
00874 }
00875 
00876 
00877 const LLHost& LLAgent::getRegionHost() const
00878 {
00879         if (mRegionp)
00880         {
00881                 return mRegionp->getHost();
00882         }
00883         else
00884         {
00885                 return LLHost::invalid;
00886         }
00887 }
00888 
00889 
00890 
00891 
00892 
00893 BOOL LLAgent::inPrelude()
00894 {
00895         return mRegionp && mRegionp->isPrelude();
00896 }
00897 
00898 
00899 
00900 
00901 
00902 
00903 BOOL LLAgent::canManageEstate() const
00904 {
00905         return mRegionp && mRegionp->canManageEstate();
00906 }
00907 
00908 
00909 
00910 
00911 void LLAgent::sendMessage()
00912 {
00913         if (gDisconnected)
00914         {
00915                 llwarns << "Trying to send message when disconnected!" << llendl;
00916                 return;
00917         }
00918         if (!mRegionp)
00919         {
00920                 llerrs << "No region for agent yet!" << llendl;
00921         }
00922         gMessageSystem->sendMessage(mRegionp->getHost());
00923 }
00924 
00925 
00926 
00927 
00928 
00929 void LLAgent::sendReliableMessage()
00930 {
00931         if (gDisconnected)
00932         {
00933                 llwarns << "Trying to send message when disconnected!" << llendl;
00934                 return;
00935         }
00936         if (!mRegionp)
00937         {
00938                 llwarns << "LLAgent::sendReliableMessage No region for agent yet, not sending message!" << llendl;
00939                 return;
00940         }
00941         gMessageSystem->sendReliable(mRegionp->getHost());
00942 }
00943 
00944 
00945 
00946 
00947 LLVector3 LLAgent::getVelocity() const
00948 {
00949         if (mAvatarObject)
00950         {
00951                 return mAvatarObject->getVelocity();
00952         }
00953         else
00954         {
00955                 return LLVector3::zero;
00956         }
00957 }
00958 
00959 
00960 
00961 
00962 
00963 void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
00964 {
00965         if (!pos_agent.isFinite())
00966         {
00967                 llerrs << "setPositionAgent is not a number" << llendl;
00968         }
00969 
00970         if (!mAvatarObject.isNull() && mAvatarObject->getParent())
00971         {
00972                 LLVector3 pos_agent_sitting;
00973                 LLVector3d pos_agent_d;
00974                 LLViewerObject *parent = (LLViewerObject*)mAvatarObject->getParent();
00975 
00976                 pos_agent_sitting = mAvatarObject->getPosition() * parent->getRotation() + parent->getPositionAgent();
00977                 pos_agent_d.setVec(pos_agent_sitting);
00978 
00979                 mFrameAgent.setOrigin(pos_agent_sitting);
00980                 mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
00981         }
00982         else
00983         {
00984                 mFrameAgent.setOrigin(pos_agent);
00985 
00986                 LLVector3d pos_agent_d;
00987                 pos_agent_d.setVec(pos_agent);
00988                 mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
00989         }
00990 }
00991 
00992 
00993 
00994 
00995 void LLAgent::slamLookAt(const LLVector3 &look_at)
00996 {
00997         LLVector3 look_at_norm = look_at;
00998         look_at_norm.mV[VZ] = 0.f;
00999         look_at_norm.normVec();
01000         resetAxes(look_at_norm);
01001 }
01002 
01003 
01004 
01005 
01006 const LLVector3d &LLAgent::getPositionGlobal() 
01007 {
01008         if (!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull())
01009         {
01010                 mPositionGlobal = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());
01011         }
01012         else
01013         {
01014                 mPositionGlobal = getPosGlobalFromAgent(mFrameAgent.getOrigin());
01015         }
01016 
01017         return mPositionGlobal;
01018 }
01019 
01020 
01021 
01022 
01023 const LLVector3 &LLAgent::getPositionAgent()
01024 {
01025         if(!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull())
01026         {
01027                 mFrameAgent.setOrigin(mAvatarObject->getRenderPosition());      
01028         }
01029 
01030         return mFrameAgent.getOrigin();
01031 }
01032 
01033 
01034 
01035 
01036 S32 LLAgent::getRegionsVisited() const
01037 {
01038         return mRegionsVisited.size();
01039 }
01040 
01041 
01042 
01043 
01044 F64 LLAgent::getDistanceTraveled() const
01045 {
01046         return mDistanceTraveled;
01047 }
01048 
01049 
01050 
01051 
01052 
01053 LLVector3 LLAgent::getPosAgentFromGlobal(const LLVector3d &pos_global) const
01054 {
01055         LLVector3 pos_agent;
01056         pos_agent.setVec(pos_global - mAgentOriginGlobal);
01057         return pos_agent;
01058 }
01059 
01060 
01061 
01062 
01063 
01064 LLVector3d LLAgent::getPosGlobalFromAgent(const LLVector3 &pos_agent) const
01065 {
01066         LLVector3d pos_agent_d;
01067         pos_agent_d.setVec(pos_agent);
01068         return pos_agent_d + mAgentOriginGlobal;
01069 }
01070 
01071 
01072 
01073 
01074 
01075 void LLAgent::resetAxes()
01076 {
01077         mFrameAgent.resetAxes();
01078 }
01079 
01080 
01081 
01082 
01083 
01084 
01085 
01086 void LLAgent::resetAxes(const LLVector3 &look_at)
01087 {
01088         LLVector3       skyward = getReferenceUpVector();
01089 
01090         
01091         
01092         
01093         
01094         LLVector3 cross(look_at % skyward);
01095         if (cross.isNull())
01096         {
01097                 llinfos << "LLAgent::resetAxes cross-product is zero" << llendl;
01098                 return;
01099         }
01100 
01101         
01102         
01103         LLVector3 left(skyward % look_at);
01104         LLVector3 up(look_at % left);
01105 
01106         mFrameAgent.setAxes(look_at, left, up);
01107 }
01108 
01109 
01110 
01111 
01112 
01113 void LLAgent::rotate(F32 angle, const LLVector3 &axis) 
01114 { 
01115         mFrameAgent.rotate(angle, axis); 
01116 }
01117 
01118 
01119 
01120 
01121 
01122 void LLAgent::rotate(F32 angle, F32 x, F32 y, F32 z) 
01123 { 
01124         mFrameAgent.rotate(angle, x, y, z); 
01125 }
01126 
01127 
01128 
01129 
01130 
01131 void LLAgent::rotate(const LLMatrix3 &matrix) 
01132 { 
01133         mFrameAgent.rotate(matrix); 
01134 }
01135 
01136 
01137 
01138 
01139 
01140 void LLAgent::rotate(const LLQuaternion &quaternion) 
01141 { 
01142         mFrameAgent.rotate(quaternion); 
01143 }
01144 
01145 
01146 
01147 
01148 
01149 LLVector3 LLAgent::getReferenceUpVector()
01150 {
01151         
01152         LLVector3 up_vector = LLVector3::z_axis;
01153         if (mAvatarObject.notNull() && 
01154                 mAvatarObject->getParent() &&
01155                 mAvatarObject->mDrawable.notNull())
01156         {
01157                 U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
01158                 
01159                 if (camera_mode == CAMERA_MODE_THIRD_PERSON)
01160                 {
01161                         
01162                         up_vector = up_vector * ~((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
01163                 }
01164                 else if (camera_mode == CAMERA_MODE_MOUSELOOK)
01165                 {
01166                         
01167                         up_vector = up_vector * mAvatarObject->mDrawable->getRotation();
01168                 }
01169         }
01170 
01171         return up_vector;
01172 }
01173 
01174 
01175 
01176 
01177 
01178 
01179 void LLAgent::pitch(F32 angle)
01180 {
01181         
01182         
01183         
01184         
01185         
01186 
01187         LLVector3 skyward = getReferenceUpVector();
01188 
01189         F32                     look_down_limit;
01190         F32                     look_up_limit = 10.f * DEG_TO_RAD;
01191 
01192         F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward );
01193 
01194         if (mAvatarObject.notNull() && mAvatarObject->mIsSitting)
01195         {
01196                 look_down_limit = 130.f * DEG_TO_RAD;
01197         }
01198         else
01199         {
01200                 look_down_limit = 170.f * DEG_TO_RAD;
01201         }
01202 
01203         
01204         if ((angle >= 0.f) && (angle_from_skyward + angle > look_down_limit))
01205         {
01206                 angle = look_down_limit - angle_from_skyward;
01207         }
01208         else if ((angle < 0.f) && (angle_from_skyward + angle < look_up_limit))
01209         {
01210                 angle = look_up_limit - angle_from_skyward;
01211         }
01212 
01213         mFrameAgent.pitch(angle);
01214 }
01215 
01216 
01217 
01218 
01219 
01220 void LLAgent::roll(F32 angle)
01221 {
01222         mFrameAgent.roll(angle);
01223 }
01224 
01225 
01226 
01227 
01228 
01229 void LLAgent::yaw(F32 angle)
01230 {
01231         if (!rotateGrabbed())
01232         {
01233                 mFrameAgent.rotate(angle, getReferenceUpVector());
01234         }
01235 }
01236 
01237 
01238 
01239 
01240 
01241 
01242 LLQuaternion LLAgent::getQuat() const
01243 {
01244         return mFrameAgent.getQuaternion();
01245 }
01246 
01247 
01248 
01249 
01250 
01251 LLVector3d LLAgent::calcFocusOffset(LLViewerObject *object, S32 x, S32 y)
01252 {
01253         
01254         BOOL is_avatar = object->isAvatar();
01255         LLMatrix4 obj_matrix = is_avatar  ? ((LLVOAvatar*)object)->mPelvisp->getWorldMatrix() : object->getRenderMatrix();
01256         LLQuaternion obj_rot = is_avatar  ? ((LLVOAvatar*)object)->mPelvisp->getWorldRotation() : object->getRenderRotation();
01257         LLVector3 obj_pos = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldPosition() : object->getRenderPosition();
01258         LLQuaternion inv_obj_rot = ~obj_rot;
01259 
01260         LLVector3 obj_dir_abs = obj_pos - gCamera->getOrigin();
01261         obj_dir_abs.rotVec(inv_obj_rot);
01262         obj_dir_abs.normVec();
01263         obj_dir_abs.abs();
01264 
01265         LLVector3 object_extents = object->getScale();
01266         
01267         object_extents.clamp(0.001f, F32_MAX);
01268         LLVector3 object_half_extents = object_extents * 0.5f;
01269 
01270         obj_dir_abs.mV[VX] = obj_dir_abs.mV[VX] / object_extents.mV[VX];
01271         obj_dir_abs.mV[VY] = obj_dir_abs.mV[VY] / object_extents.mV[VY];
01272         obj_dir_abs.mV[VZ] = obj_dir_abs.mV[VZ] / object_extents.mV[VZ];
01273 
01274         LLVector3 normal;
01275         if (obj_dir_abs.mV[VX] > obj_dir_abs.mV[VY] && obj_dir_abs.mV[VX] > obj_dir_abs.mV[VZ])
01276         {
01277                 normal.setVec(obj_matrix.getFwdRow4());
01278         }
01279         else if (obj_dir_abs.mV[VY] > obj_dir_abs.mV[VZ])
01280         {
01281                 normal.setVec(obj_matrix.getLeftRow4());
01282         }
01283         else
01284         {
01285                 normal.setVec(obj_matrix.getUpRow4());
01286         }
01287         normal.normVec();
01288 
01289         LLVector3d focus_pt_global;
01290         
01291         gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), normal);
01292         LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global);
01293         
01294         LLVector3 camera_focus_vec = focus_pt - gCamera->getOrigin();
01295         
01296         camera_focus_vec.rotVec(inv_obj_rot);
01297 
01298         
01299         LLVector3 focus_delta = focus_pt - obj_pos;
01300         
01301         focus_delta.rotVec(inv_obj_rot);
01302 
01303         
01304         LLVector3 clip_fraction;
01305 
01306         for (U32 axis = VX; axis <= VZ; axis++)
01307         {
01308                 F32 clip_amt;
01309                 if (focus_delta.mV[axis] > 0.f)
01310                 {
01311                         clip_amt = llmax(0.f, focus_delta.mV[axis] - object_half_extents.mV[axis]);
01312                 }
01313                 else
01314                 {
01315                         clip_amt = llmin(0.f, focus_delta.mV[axis] + object_half_extents.mV[axis]);
01316                 }
01317 
01318                 
01319                 if (llabs(camera_focus_vec.mV[axis]) < 0.0001f)
01320                 {
01321                         clip_fraction.mV[axis] = 0.f;
01322                 }
01323                 else
01324                 {
01325                         clip_fraction.mV[axis] = clip_amt / camera_focus_vec.mV[axis];
01326                 }
01327         }
01328 
01329         LLVector3 abs_clip_fraction = clip_fraction;
01330         abs_clip_fraction.abs();
01331 
01332         
01333         
01334         if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY] &&
01335                 abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ])
01336         {
01337                 focus_delta -= clip_fraction.mV[VX] * camera_focus_vec;
01338         }
01339         else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ])
01340         {
01341                 focus_delta -= clip_fraction.mV[VY] * camera_focus_vec;
01342         }
01343         else
01344         {
01345                 focus_delta -= clip_fraction.mV[VZ] * camera_focus_vec;
01346         }
01347 
01348         
01349         focus_delta.rotVec(obj_rot);
01350         
01351         if (!is_avatar) 
01352         {
01353                 
01354                 glPushMatrix();
01355                 glMatrixMode(GL_PROJECTION);
01356                 glLoadMatrixf((const GLfloat*) gCamera->getProjection().mMatrix);
01357                 glMatrixMode(GL_MODELVIEW);
01358                 glLoadMatrixf((const GLfloat*) gCamera->getModelview().mMatrix);
01359                 glMultMatrixf((const GLfloat*) obj_matrix.mMatrix);
01360 
01361                 GLint viewport[4];
01362                 GLdouble modelview[16];
01363                 GLdouble projection[16];
01364                 GLfloat winX, winY, winZ;
01365                 GLdouble posX, posY, posZ;
01366 
01367                 glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
01368                 glGetDoublev( GL_PROJECTION_MATRIX, projection );
01369                 glGetIntegerv( GL_VIEWPORT, viewport );
01370 
01371                 winX = ((F32)x) * gViewerWindow->getDisplayScale().mV[VX];
01372                 winY = ((F32)y) * gViewerWindow->getDisplayScale().mV[VY];
01373                 glReadPixels( llfloor(winX), llfloor(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
01374 
01375                 gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
01376 
01377                 glPopMatrix();
01378 
01379                 LLVector3 obj_rel = LLVector3((F32)posX, (F32)posY, (F32)posZ);
01380                 LLVector3 obj_center = LLVector3(0, 0, 0);
01381                 obj_rel = obj_rel * object->getRenderMatrix(); 
01382                 obj_center = obj_center * object->getRenderMatrix();
01383                 obj_rel -= object->getRenderPosition();
01384                 
01385                 
01386                 
01387 
01388                 F32 relDist = llabs(obj_rel * gCamera->getAtAxis());
01389                 F32 viewDist = dist_vec(obj_center + obj_rel, gCamera->getOrigin());
01390 
01391 
01392                 LLBBox obj_bbox = object->getBoundingBoxAgent();
01393                 F32 bias = 0.f;
01394 
01395                 LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor));
01396 
01397                 if(obj_bbox.containsPointAgent(virtual_camera_pos))
01398                 {
01399                         
01400                         
01401                         bias = 1.f;
01402                 }
01403                 else
01404                 {
01405                         
01406                         bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f);
01407                 }
01408                 
01409                 obj_rel = lerp(focus_delta, obj_rel, bias);
01410                 
01411                 return LLVector3d(obj_rel);
01412         }
01413 
01414         return LLVector3d(focus_delta.mV[VX], focus_delta.mV[VY], focus_delta.mV[VZ]);
01415 }
01416 
01417 
01418 
01419 
01420 BOOL LLAgent::calcCameraMinDistance(F32 &obj_min_distance)
01421 {
01422         BOOL soft_limit = FALSE; 
01423 
01424         if (!mFocusObject || mFocusObject->isDead())
01425         {
01426                 obj_min_distance = 0.f;
01427                 return TRUE;
01428         }
01429 
01430         if (mFocusObject->mDrawable.isNull())
01431         {
01432 #ifdef LL_RELEASE_FOR_DOWNLOAD
01433                 llwarns << "Focus object with no drawable!" << llendl;
01434 #else
01435                 mFocusObject->dump();
01436                 llerrs << "Focus object with no drawable!" << llendl;
01437 #endif
01438                 obj_min_distance = 0.f;
01439                 return TRUE;
01440         }
01441         
01442         LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation();
01443         LLVector3 target_offset_origin = mFocusObjectOffset;
01444         LLVector3 camera_offset_target(getCameraPositionAgent() - getPosAgentFromGlobal(mFocusTargetGlobal));
01445 
01446         
01447         camera_offset_target.rotVec(inv_object_rot);
01448         target_offset_origin.rotVec(inv_object_rot);
01449 
01450         
01451         LLVector3 object_extents = mFocusObject->getScale();
01452         if (mFocusObject->isAvatar())
01453         {
01454                 
01455                 object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR;
01456                 object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR;
01457                 object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR;
01458                 soft_limit = TRUE;
01459         }
01460         LLVector3 abs_target_offset = target_offset_origin;
01461         abs_target_offset.abs();
01462 
01463         LLVector3 target_offset_dir = target_offset_origin;
01464         F32 object_radius = mFocusObject->getVObjRadius();
01465 
01466         BOOL target_outside_object_extents = FALSE;
01467 
01468         for (U32 i = VX; i <= VZ; i++)
01469         {
01470                 if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING)
01471                 {
01472                         target_outside_object_extents = TRUE;
01473                 }
01474                 if (camera_offset_target.mV[i] > 0.f)
01475                 {
01476                         object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f;
01477                 }
01478                 else
01479                 {
01480                         object_extents.mV[i] += target_offset_origin.mV[i] * 2.f;
01481                 }
01482         }
01483 
01484         
01485         object_extents.clamp(0.001f, F32_MAX);
01486 
01487         
01488         LLVector3 camera_offset_target_abs_norm = camera_offset_target;
01489         camera_offset_target_abs_norm.abs();
01490         
01491         camera_offset_target_abs_norm.clamp(0.001f, F32_MAX);
01492         camera_offset_target_abs_norm.normVec();
01493 
01494         
01495         LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm;
01496         camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX];
01497         camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY];
01498         camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ];
01499 
01500         if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] && 
01501                 camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ])
01502         {
01503                 if (camera_offset_target_abs_norm.mV[VX] < 0.001f)
01504                 {
01505                         obj_min_distance = object_extents.mV[VX] * 0.5f;
01506                 }
01507                 else
01508                 {
01509                         obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX];
01510                 }
01511         }
01512         else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ])
01513         {
01514                 if (camera_offset_target_abs_norm.mV[VY] < 0.001f)
01515                 {
01516                         obj_min_distance = object_extents.mV[VY] * 0.5f;
01517                 }
01518                 else
01519                 {
01520                         obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY];
01521                 }
01522         }
01523         else
01524         {
01525                 if (camera_offset_target_abs_norm.mV[VZ] < 0.001f)
01526                 {
01527                         obj_min_distance = object_extents.mV[VZ] * 0.5f;
01528                 }
01529                 else
01530                 {
01531                         obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ];
01532                 }
01533         }
01534 
01535         LLVector3 object_split_axis;
01536         LLVector3 target_offset_scaled = target_offset_origin;
01537         target_offset_scaled.abs();
01538         target_offset_scaled.normVec();
01539         target_offset_scaled.mV[VX] /= object_extents.mV[VX];
01540         target_offset_scaled.mV[VY] /= object_extents.mV[VY];
01541         target_offset_scaled.mV[VZ] /= object_extents.mV[VZ];
01542 
01543         if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] && 
01544                 target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ])
01545         {
01546                 object_split_axis = LLVector3::x_axis;
01547         }
01548         else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ])
01549         {
01550                 object_split_axis = LLVector3::y_axis;
01551         }
01552         else
01553         {
01554                 object_split_axis = LLVector3::z_axis;
01555         }
01556 
01557         LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
01558 
01559         
01560         F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
01561 
01562         
01563         
01564         BOOL exterior_target_visible = FALSE;
01565         if (camera_offset_dist > object_radius)
01566         {
01567                 
01568                 exterior_target_visible = TRUE;
01569         }
01570 
01571         F32 camera_offset_clip = camera_offset_object * object_split_axis;
01572         F32 target_offset_clip = target_offset_dir * object_split_axis;
01573 
01574         
01575         
01576         if (target_outside_object_extents)
01577         {
01578                 if (camera_offset_clip > 0.f && target_offset_clip > 0.f)
01579                 {
01580                         return FALSE;
01581                 }
01582                 else if (camera_offset_clip < 0.f && target_offset_clip < 0.f)
01583                 {
01584                         return FALSE;
01585                 }
01586         }
01587 
01588         
01589         obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3);
01590 
01591         obj_min_distance += gCamera->getNear() + (soft_limit ? 0.1f : 0.2f);
01592         
01593         return TRUE;
01594 }
01595 
01596 F32 LLAgent::getCameraZoomFraction()
01597 {
01598         
01599         
01600         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
01601         if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
01602         {
01603                 
01604                 return mAvatarObject->mHUDTargetZoom;
01605         }
01606         else if (mFocusOnAvatar && cameraThirdPerson())
01607         {
01608                 return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
01609         }
01610         else if (cameraCustomizeAvatar())
01611         {
01612                 F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
01613                 return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f );
01614         }
01615         else
01616         {
01617                 F32 min_zoom;
01618                 const F32 DIST_FUDGE = 16.f; 
01619                 F32 max_zoom = gWorldPointer ? llmin(mDrawDistance - DIST_FUDGE, 
01620                                                                 gWorldPointer->getRegionWidthInMeters() - DIST_FUDGE,
01621                                                                 MAX_CAMERA_DISTANCE_FROM_AGENT) : MAX_CAMERA_DISTANCE_FROM_AGENT;
01622 
01623                 F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
01624                 if (mFocusObject.notNull())
01625                 {
01626                         if (mFocusObject->isAvatar())
01627                         {
01628                                 min_zoom = AVATAR_MIN_ZOOM;
01629                         }
01630                         else
01631                         {
01632                                 min_zoom = OBJECT_MIN_ZOOM;
01633                         }
01634                 }
01635                 else
01636                 {
01637                         min_zoom = LAND_MIN_ZOOM;
01638                 }
01639 
01640                 return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
01641         }
01642 }
01643 
01644 void LLAgent::setCameraZoomFraction(F32 fraction)
01645 {
01646         
01647         
01648         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
01649 
01650         if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
01651         {
01652                 mAvatarObject->mHUDTargetZoom = fraction;
01653         }
01654         else if (mFocusOnAvatar && cameraThirdPerson())
01655         {
01656                 mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
01657         }
01658         else if (cameraCustomizeAvatar())
01659         {
01660                 LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
01661                 camera_offset_dir.normVec();
01662                 mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM);
01663         }
01664         else
01665         {
01666                 F32 min_zoom = LAND_MIN_ZOOM;
01667                 const F32 DIST_FUDGE = 16.f; 
01668                 F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
01669                                                                 gWorldPointer->getRegionWidthInMeters() - DIST_FUDGE,
01670                                                                 MAX_CAMERA_DISTANCE_FROM_AGENT);
01671 
01672                 if (mFocusObject.notNull())
01673                 {
01674                         if (mFocusObject.notNull())
01675                         {
01676                                 if (mFocusObject->isAvatar())
01677                                 {
01678                                         min_zoom = AVATAR_MIN_ZOOM;
01679                                 }
01680                                 else
01681                                 {
01682                                         min_zoom = OBJECT_MIN_ZOOM;
01683                                 }
01684                         }
01685                 }
01686 
01687                 LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
01688                 camera_offset_dir.normVec();
01689                 mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
01690         }
01691         startCameraAnimation();
01692 }
01693 
01694 
01695 
01696 
01697 
01698 void LLAgent::cameraOrbitAround(const F32 radians)
01699 {
01700         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
01701         if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
01702         {
01703                 
01704         }
01705         else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW))
01706         {
01707                 mFrameAgent.rotate(radians, getReferenceUpVector());
01708         }
01709         else
01710         {
01711                 mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
01712                 
01713                 cameraZoomIn(1.f);
01714         }
01715 }
01716 
01717 
01718 
01719 
01720 
01721 void LLAgent::cameraOrbitOver(const F32 angle)
01722 {
01723         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
01724         if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
01725         {
01726                 
01727         }
01728         else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
01729         {
01730                 pitch(angle);
01731         }
01732         else
01733         {
01734                 LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
01735                 camera_offset_unit.normVec();
01736 
01737                 F32 angle_from_up = acos( camera_offset_unit * getReferenceUpVector() );
01738 
01739                 LLVector3d left_axis;
01740                 left_axis.setVec(gCamera->getLeftAxis());
01741                 F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
01742                 mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
01743 
01744                 cameraZoomIn(1.f);
01745         }
01746 }
01747 
01748 
01749 
01750 
01751 void LLAgent::cameraZoomIn(const F32 fraction)
01752 {
01753         if (gDisconnected)
01754         {
01755                 return;
01756         }
01757 
01758         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
01759         if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
01760         {
01761                 
01762                 mAvatarObject->mHUDTargetZoom /= fraction;
01763                 return;
01764         }
01765 
01766 
01767         LLVector3d      camera_offset(mCameraFocusOffsetTarget);
01768         LLVector3d      camera_offset_unit(mCameraFocusOffsetTarget);
01769         F32 min_zoom = LAND_MIN_ZOOM;
01770         F32 current_distance = (F32)camera_offset_unit.normVec();
01771         F32 new_distance = current_distance * fraction;
01772 
01773         
01774         if (mFocusObject)
01775         {
01776                 LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
01777 
01778                 if (mFocusObject->isAvatar())
01779                 {
01780                         calcCameraMinDistance(min_zoom);
01781                 }
01782                 else
01783                 {
01784                         min_zoom = OBJECT_MIN_ZOOM;
01785                 }
01786         }
01787 
01788         new_distance = llmax(new_distance, min_zoom); 
01789 
01790         
01791         const F32 DIST_FUDGE = 16.f; 
01792         F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
01793                                                          gWorldPointer->getRegionWidthInMeters() - DIST_FUDGE );
01794 
01795         if (new_distance > max_distance)
01796         {
01797                 new_distance = max_distance;
01798 
01799                 
01800 
01801 
01802 
01803 
01804 
01805 
01806         }
01807 
01808         if( cameraCustomizeAvatar() )
01809         {
01810                 new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
01811         }
01812 
01813         mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
01814 }
01815 
01816 
01817 
01818 
01819 void LLAgent::cameraOrbitIn(const F32 meters)
01820 {
01821         if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
01822         {
01823                 F32 camera_offset_dist = llmax(0.001f, mCameraOffsetDefault.magVec());
01824                 
01825                 mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
01826 
01827                 if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f)
01828                 {
01829                         
01830                         changeCameraToMouselook(FALSE);
01831                 }
01832 
01833                 mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
01834         }
01835         else
01836         {
01837                 LLVector3d      camera_offset(mCameraFocusOffsetTarget);
01838                 LLVector3d      camera_offset_unit(mCameraFocusOffsetTarget);
01839                 F32 current_distance = (F32)camera_offset_unit.normVec();
01840                 F32 new_distance = current_distance - meters;
01841                 F32 min_zoom = LAND_MIN_ZOOM;
01842                 
01843                 
01844                 if (mFocusObject.notNull())
01845                 {
01846                         if (mFocusObject->isAvatar())
01847                         {
01848                                 min_zoom = AVATAR_MIN_ZOOM;
01849                         }
01850                         else
01851                         {
01852                                 min_zoom = OBJECT_MIN_ZOOM;
01853                         }
01854                 }
01855 
01856                 new_distance = llmax(new_distance, min_zoom);
01857 
01858                 
01859                 const F32 DIST_FUDGE = 16.f; 
01860                 F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
01861                                                                  gWorldPointer->getRegionWidthInMeters() - DIST_FUDGE );
01862 
01863                 if (new_distance > max_distance)
01864                 {
01865                         
01866                         if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
01867                         {
01868                                 return;
01869                         }
01870                 }
01871 
01872                 if( CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode() )
01873                 {
01874                         llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
01875                 }
01876 
01877                 
01878                 mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
01879                 cameraZoomIn(1.f);
01880         }
01881 }
01882 
01883 
01884 
01885 
01886 
01887 void LLAgent::cameraPanIn(F32 meters)
01888 {
01889         LLVector3d at_axis;
01890         at_axis.setVec(gCamera->getAtAxis());
01891 
01892         mFocusTargetGlobal += meters * at_axis;
01893         mFocusGlobal = mFocusTargetGlobal;
01894         
01895         updateFocusOffset();
01896 }
01897 
01898 
01899 
01900 
01901 void LLAgent::cameraPanLeft(F32 meters)
01902 {
01903         LLVector3d left_axis;
01904         left_axis.setVec(gCamera->getLeftAxis());
01905 
01906         mFocusTargetGlobal += meters * left_axis;
01907         mFocusGlobal = mFocusTargetGlobal;
01908         cameraZoomIn(1.f);
01909         updateFocusOffset();
01910 }
01911 
01912 
01913 
01914 
01915 void LLAgent::cameraPanUp(F32 meters)
01916 {
01917         LLVector3d up_axis;
01918         up_axis.setVec(gCamera->getUpAxis());
01919 
01920         mFocusTargetGlobal += meters * up_axis;
01921         mFocusGlobal = mFocusTargetGlobal;
01922         cameraZoomIn(1.f);
01923         updateFocusOffset();
01924 }
01925 
01926 
01927 
01928 
01929 void LLAgent::setKey(const S32 direction, S32 &key)
01930 {
01931         if (direction > 0)
01932         {
01933                 key = 1;
01934         }
01935         else if (direction < 0)
01936         {
01937                 key = -1;
01938         }
01939         else
01940         {
01941                 key = 0;
01942         }
01943 }
01944 
01945 
01946 
01947 
01948 
01949 U32 LLAgent::getControlFlags()
01950 {
01951 
01952 
01953 
01954 
01955 
01956 
01957 
01958 
01959 
01960 
01961 
01962         return mControlFlags;
01963 }
01964 
01965 
01966 
01967 
01968 void LLAgent::setControlFlags(U32 mask)
01969 {
01970         mControlFlags |= mask;
01971         mbFlagsDirty = TRUE;
01972 }
01973 
01974 
01975 
01976 
01977 
01978 void LLAgent::clearControlFlags(U32 mask)
01979 {
01980         U32 old_flags = mControlFlags;
01981         mControlFlags &= ~mask;
01982         if (old_flags != mControlFlags)
01983         {
01984                 mbFlagsDirty = TRUE;
01985         }
01986 }
01987 
01988 
01989 
01990 
01991 BOOL LLAgent::controlFlagsDirty() const
01992 {
01993         return mbFlagsDirty;
01994 }
01995 
01996 
01997 
01998 
01999 void LLAgent::enableControlFlagReset()
02000 {
02001         mbFlagsNeedReset = TRUE;
02002 }
02003 
02004 
02005 
02006 
02007 void LLAgent::resetControlFlags()
02008 {
02009         if (mbFlagsNeedReset)
02010         {
02011                 mbFlagsNeedReset = FALSE;
02012                 mbFlagsDirty = FALSE;
02013                 
02014                 
02015                 mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK;
02016         }
02017 }
02018 
02019 
02020 
02021 
02022 void LLAgent::setAFK()
02023 {
02024         
02025         if (gNoRender)
02026         {
02027                 return;
02028         }
02029 
02030         if (!gAgent.getRegion())
02031         {
02032                 
02033                 return;
02034         }
02035 
02036         if (!(mControlFlags & AGENT_CONTROL_AWAY))
02037         {
02038                 sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
02039                 setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
02040                 gAwayTimer.start();
02041                 if (gAFKMenu)
02042                 {
02043                         
02044                         gAFKMenu->setLabel(LLString("Set Not Away"));
02045                 }
02046         }
02047 }
02048 
02049 
02050 
02051 
02052 void LLAgent::clearAFK()
02053 {
02054         gAwayTriggerTimer.reset();
02055 
02056         
02057         
02058         LLVOAvatar* av = mAvatarObject;
02059         if (mControlFlags & AGENT_CONTROL_AWAY
02060                 || (av
02061                         && (av->mSignaledAnimations.find(ANIM_AGENT_AWAY) != av->mSignaledAnimations.end())))
02062         {
02063                 sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
02064                 clearControlFlags(AGENT_CONTROL_AWAY);
02065                 if (gAFKMenu)
02066                 {
02067                         
02068                         gAFKMenu->setLabel(LLString("Set Away"));
02069                 }
02070         }
02071 }
02072 
02073 
02074 
02075 
02076 BOOL LLAgent::getAFK() const
02077 {
02078         return (mControlFlags & AGENT_CONTROL_AWAY) != 0;
02079 }
02080 
02081 
02082 
02083 
02084 void LLAgent::setBusy()
02085 {
02086         sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START);
02087         mIsBusy = TRUE;
02088         if (gBusyMenu)
02089         {
02090                 
02091                 gBusyMenu->setLabel(LLString("Set Not Busy"));
02092         }
02093         if (gFloaterMute)
02094         {
02095                 gFloaterMute->updateButtons();
02096         }
02097 }
02098 
02099 
02100 
02101 
02102 void LLAgent::clearBusy()
02103 {
02104         mIsBusy = FALSE;
02105         sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
02106         if (gBusyMenu)
02107         {
02108                 
02109                 gBusyMenu->setLabel(LLString("Set Busy"));
02110         }
02111         if (gFloaterMute)
02112         {
02113                 gFloaterMute->updateButtons();
02114         }
02115 }
02116 
02117 
02118 
02119 
02120 BOOL LLAgent::getBusy() const
02121 {
02122         return mIsBusy;
02123 }
02124 
02125 
02126 
02127 
02128 
02129 void LLAgent::startAutoPilotGlobal(const LLVector3d &target_global, const std::string& behavior_name, const LLQuaternion *target_rotation, void (*finish_callback)(BOOL, void *),  void *callback_data, F32 stop_distance, F32 rot_threshold)
02130 {
02131         if (!gAgent.getAvatarObject() || !gWorldPointer)
02132         {
02133                 return;
02134         }
02135         
02136         mAutoPilotFinishedCallback = finish_callback;
02137         mAutoPilotCallbackData = callback_data;
02138         mAutoPilotRotationThreshold = rot_threshold;
02139         mAutoPilotBehaviorName = behavior_name;
02140 
02141         LLVector3d delta_pos( target_global );
02142         delta_pos -= getPositionGlobal();
02143         F64 distance = delta_pos.magVec();
02144         LLVector3d trace_target = target_global;
02145 
02146         trace_target.mdV[VZ] -= 10.f;
02147 
02148         LLVector3d intersection;
02149         LLVector3 normal;
02150         LLViewerObject *hit_obj;
02151         F32 heightDelta = gWorldPointer->resolveStepHeightGlobal(NULL, target_global, trace_target, intersection, normal, &hit_obj);
02152 
02153         if (stop_distance > 0.f)
02154         {
02155                 mAutoPilotStopDistance = stop_distance;
02156         }
02157         else
02158         {
02159                 
02160                 mAutoPilotStopDistance = fsqrtf( distance );
02161                 if (mAutoPilotStopDistance < 0.5f) 
02162                 {
02163                         mAutoPilotStopDistance = 0.5f;
02164                 }
02165         }
02166 
02167         mAutoPilotFlyOnStop = getFlying();
02168 
02169         if (distance > 30.0)
02170         {
02171                 setFlying(TRUE);
02172         }
02173 
02174         if ( distance > 1.f && heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f))
02175         {
02176                 setFlying(TRUE);
02177                 mAutoPilotFlyOnStop = TRUE;
02178         }
02179 
02180         mAutoPilot = TRUE;
02181         mAutoPilotTargetGlobal = target_global;
02182 
02183         
02184         LLVector3d traceEndPt = target_global;
02185         traceEndPt.mdV[VZ] -= 20.f;
02186 
02187         LLVector3d targetOnGround;
02188         LLVector3 groundNorm;
02189         LLViewerObject *obj;
02190 
02191         gWorldPointer->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj);
02192         F64 target_height = llmax((F64)gAgent.getAvatarObject()->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]);
02193 
02194         
02195         mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height;
02196         mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal);
02197         if (target_rotation)
02198         {
02199                 mAutoPilotUseRotation = TRUE;
02200                 mAutoPilotTargetFacing = LLVector3::x_axis * *target_rotation;
02201                 mAutoPilotTargetFacing.mV[VZ] = 0.f;
02202                 mAutoPilotTargetFacing.normVec();
02203         }
02204         else
02205         {
02206                 mAutoPilotUseRotation = FALSE;
02207         }
02208 
02209         mAutoPilotNoProgressFrameCount = 0;
02210 }
02211 
02212 
02213 
02214 
02215 
02216 void LLAgent::startFollowPilot(const LLUUID &leader_id)
02217 {
02218         if (!mAutoPilot) return;
02219 
02220         mLeaderID = leader_id;
02221         if ( mLeaderID.isNull() ) return;
02222 
02223         LLViewerObject* object = gObjectList.findObject(mLeaderID);
02224         if (!object) 
02225         {
02226                 mLeaderID = LLUUID::null;
02227                 return;
02228         }
02229 
02230         startAutoPilotGlobal(object->getPositionGlobal());
02231 }
02232 
02233 
02234 
02235 
02236 
02237 void LLAgent::stopAutoPilot(BOOL user_cancel)
02238 {
02239         if (mAutoPilot)
02240         {
02241                 mAutoPilot = FALSE;
02242                 if (mAutoPilotUseRotation && !user_cancel)
02243                 {
02244                         resetAxes(mAutoPilotTargetFacing);
02245                 }
02246                 
02247                 if (mAutoPilotFinishedCallback)
02248                 {
02249                         mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData);
02250                 }
02251                 mLeaderID = LLUUID::null;
02252 
02253                 
02254                 if (!user_cancel)
02255                 {
02256                         setFlying(mAutoPilotFlyOnStop);
02257                 }
02258                 setControlFlags(AGENT_CONTROL_STOP);
02259 
02260                 if (user_cancel && !mAutoPilotBehaviorName.empty())
02261                 {
02262                         if (mAutoPilotBehaviorName == "Sit")
02263                                 LLNotifyBox::showXml("CancelledSit");
02264                         else if (mAutoPilotBehaviorName == "Attach")
02265                                 LLNotifyBox::showXml("CancelledAttach");
02266                         else
02267                                 LLNotifyBox::showXml("Cancelled");
02268                 }
02269         }
02270 }
02271 
02272 
02273 
02274 
02275 
02276 
02277 void LLAgent::autoPilot(F32 *delta_yaw)
02278 {
02279         if (mAutoPilot)
02280         {
02281                 if (!mLeaderID.isNull())
02282                 {
02283                         LLViewerObject* object = gObjectList.findObject(mLeaderID);
02284                         if (!object) 
02285                         {
02286                                 stopAutoPilot();
02287                                 return;
02288                         }
02289                         mAutoPilotTargetGlobal = object->getPositionGlobal();
02290                 }
02291                 
02292                 if (!mAvatarObject)
02293                 {
02294                         return;
02295                 }
02296 
02297                 if (mAvatarObject->mInAir)
02298                 {
02299                         setFlying(TRUE);
02300                 }
02301         
02302                 LLVector3 at;
02303                 at.setVec(mFrameAgent.getAtAxis());
02304                 LLVector3 target_agent = getPosAgentFromGlobal(mAutoPilotTargetGlobal);
02305                 LLVector3 direction = target_agent - getPositionAgent();
02306 
02307                 F32 target_dist = direction.magVec();
02308 
02309                 if (target_dist >= mAutoPilotTargetDist)
02310                 {
02311                         mAutoPilotNoProgressFrameCount++;
02312                         if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped)
02313                         {
02314                                 stopAutoPilot();
02315                                 return;
02316                         }
02317                 }
02318 
02319                 mAutoPilotTargetDist = target_dist;
02320 
02321                 
02322                 at.mV[VZ] = 0.f;
02323                 direction.mV[VZ] = 0.f;
02324 
02325                 at.normVec();
02326                 F32 xy_distance = direction.normVec();
02327 
02328                 F32 yaw = 0.f;
02329                 if (mAutoPilotTargetDist > mAutoPilotStopDistance)
02330                 {
02331                         yaw = angle_between(mFrameAgent.getAtAxis(), direction);
02332                 }
02333                 else if (mAutoPilotUseRotation)
02334                 {
02335                         
02336                         yaw = angle_between(at, mAutoPilotTargetFacing);
02337                         direction = mAutoPilotTargetFacing;
02338                 }
02339 
02340                 yaw = 4.f * yaw / gFPSClamped;
02341 
02342                 
02343                 LLVector3 scratch(at % direction);
02344 
02345                 if (scratch.mV[VZ] > 0.f)
02346                 {
02347                         setControlFlags(AGENT_CONTROL_YAW_POS);
02348                 }
02349                 else
02350                 {
02351                         yaw = -yaw;
02352                         setControlFlags(AGENT_CONTROL_YAW_NEG);
02353                 }
02354 
02355                 *delta_yaw = yaw;
02356 
02357                 
02358                 F32 stop_distance = mAutoPilotStopDistance;
02359                 F32 slow_distance;
02360                 if (getFlying())
02361                 {
02362                         slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
02363                         stop_distance = llmax(2.f, mAutoPilotStopDistance);
02364                 }
02365                 else
02366                 {
02367                         slow_distance = llmax(3.f, mAutoPilotStopDistance + 2.f);
02368                 }
02369 
02370                 
02371                 if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE)
02372                 {
02373                         if (mAvatarObject)
02374                         {
02375                                 F64 current_height = mAvatarObject->getPositionGlobal().mdV[VZ];
02376                                 F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height);
02377                                 F32 slope = delta_z / xy_distance;
02378                                 if (slope > 0.45f && delta_z > 6.f)
02379                                 {
02380                                         setControlFlags(AGENT_CONTROL_FAST_UP | AGENT_CONTROL_UP_POS);
02381                                 }
02382                                 else if (slope > 0.002f && delta_z > 0.5f)
02383                                 {
02384                                         setControlFlags(AGENT_CONTROL_UP_POS);
02385                                 }
02386                                 else if (slope < -0.45f && delta_z < -6.f && current_height > AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND)
02387                                 {
02388                                         setControlFlags(AGENT_CONTROL_FAST_UP | AGENT_CONTROL_UP_NEG);
02389                                 }
02390                                 else if (slope < -0.002f && delta_z < -0.5f && current_height > AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND)
02391                                 {
02392                                         setControlFlags(AGENT_CONTROL_UP_NEG);
02393                                 }
02394                         }
02395                 }
02396 
02397                 
02398                 F32 delta_target_heading = angle_between(mFrameAgent.getAtAxis(), mAutoPilotTargetFacing);
02399 
02400                 if (xy_distance > slow_distance && yaw < (F_PI / 10.f))
02401                 {
02402                         
02403                         setControlFlags(AGENT_CONTROL_FAST_AT | AGENT_CONTROL_AT_POS);
02404                 }
02405                 else if (mAutoPilotTargetDist > mAutoPilotStopDistance)
02406                 {
02407                         
02408                         if (at * direction > 0.9f)
02409                         {
02410                                 setControlFlags(AGENT_CONTROL_AT_POS);
02411                         }
02412                         else if (at * direction < -0.9f)
02413                         {
02414                                 setControlFlags(AGENT_CONTROL_AT_NEG);
02415                         }
02416                 }
02417 
02418                 
02419                 if (mAutoPilotTargetDist < mAutoPilotStopDistance)
02420                 {
02421                         setControlFlags(AGENT_CONTROL_STOP);
02422                         if(!mAutoPilotUseRotation || (delta_target_heading < mAutoPilotRotationThreshold))
02423                         {
02424                                 stopAutoPilot();
02425                         }
02426                 }
02427         }
02428 }
02429 
02430 
02431 
02432 
02433 
02434 void LLAgent::propagate(const F32 dt)
02435 {
02436         
02437         LLFloaterMove *floater_move = LLFloaterMove::getInstance();
02438         if (floater_move)
02439         {
02440                 floater_move->mForwardButton   ->setToggleState( mAtKey > 0 || mWalkKey > 0 );
02441                 floater_move->mBackwardButton  ->setToggleState( mAtKey < 0 || mWalkKey < 0 );
02442                 floater_move->mSlideLeftButton ->setToggleState( mLeftKey > 0 );
02443                 floater_move->mSlideRightButton->setToggleState( mLeftKey < 0 );
02444                 floater_move->mTurnLeftButton  ->setToggleState( mYawKey > 0.f );
02445                 floater_move->mTurnRightButton ->setToggleState( mYawKey < 0.f );
02446                 floater_move->mMoveUpButton    ->setToggleState( mUpKey > 0 );
02447                 floater_move->mMoveDownButton  ->setToggleState( mUpKey < 0 );
02448         }
02449 
02450         
02451         const F32 YAW_RATE = 90.f * DEG_TO_RAD;                         
02452         yaw( YAW_RATE * mYawKey * dt );
02453 
02454         const F32 PITCH_RATE = 90.f * DEG_TO_RAD;                       
02455         pitch(PITCH_RATE * (F32) mPitchKey * dt);
02456         
02457         
02458         if (mAvatarObject)
02459         {
02460                 BOOL in_air = mAvatarObject->mInAir;
02461                 LLVector3 land_vel = getVelocity();
02462                 land_vel.mV[VZ] = 0.f;
02463 
02464                 if (!in_air 
02465                         && mUpKey < 0 
02466                         && land_vel.magVecSquared() < MAX_VELOCITY_AUTO_LAND_SQUARED
02467                         && gSavedSettings.getBOOL("AutomaticFly"))
02468                 {
02469                         
02470                         setFlying(FALSE);
02471                 }
02472         }
02473 
02474         
02475         mAtKey = 0;
02476         mWalkKey = 0;
02477         mLeftKey = 0;
02478         mUpKey = 0;
02479         mYawKey = 0.f;
02480         mPitchKey = 0;
02481 }
02482 
02483 
02484 
02485 
02486 void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
02487 {
02488         propagate(dt);
02489 
02490         
02491 
02492         rotate(yaw_radians, 0, 0, 1);
02493         
02494         
02495         
02496         
02497 
02498         updateLookAt(mouse_x, mouse_y);
02499 }
02500 
02501 
02502 
02503 
02504 void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
02505 {
02506         static LLVector3 last_at_axis;
02507 
02508 
02509         if ( mAvatarObject.isNull() )
02510         {
02511                 return;
02512         }
02513 
02514         LLQuaternion av_inv_rot = ~mAvatarObject->mRoot.getWorldRotation();
02515         LLVector3 root_at = LLVector3::x_axis * mAvatarObject->mRoot.getWorldRotation();
02516 
02517         if      ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
02518                 (root_at * last_at_axis > 0.95f ))
02519         {
02520                 LLVector3 vel = mAvatarObject->getVelocity();
02521                 if (vel.magVecSquared() > 4.f)
02522                 {
02523                         setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, vel * av_inv_rot);
02524                 }
02525                 else
02526                 {
02527                         
02528                         LLQuaternion look_rotation = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); 
02529                         LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot;
02530                         setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, look_offset);
02531                 }
02532                 last_at_axis = root_at;
02533                 return;
02534         }
02535 
02536         last_at_axis = root_at;
02537         
02538         if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
02539         {
02540                 setLookAt(LOOKAT_TARGET_NONE, mAvatarObject, LLVector3(-2.f, 0.f, 0.f));        
02541         }
02542         else
02543         {
02544                 
02545                 ELookAtType lookAtType = LOOKAT_TARGET_NONE;
02546                 LLVector3 headLookAxis;
02547                 LLCoordFrame frameCamera = *((LLCoordFrame*)gCamera);
02548 
02549                 F32 x_from_center = mouse_x_from_center( mouse_x );     
02550                 F32 y_from_center = mouse_y_from_center( mouse_y );     
02551 
02552                 if (cameraMouselook())
02553                 {
02554                         lookAtType = LOOKAT_TARGET_MOUSELOOK;
02555                 }
02556                 else if (cameraThirdPerson())
02557                 {
02558                         frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD);
02559                         frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD);
02560                         lookAtType = LOOKAT_TARGET_FREELOOK;
02561                 }
02562 
02563                 headLookAxis = frameCamera.getAtAxis();
02564                 
02565                 
02566                 setLookAt(lookAtType, mAvatarObject, headLookAxis);
02567         }
02568 }
02569 
02570 
02571 
02572 std::ostream& operator<<(std::ostream &s, const LLAgent &agent)
02573 {
02574         
02575         
02576         s << " { "
02577           << "  Frame = " << agent.mFrameAgent << "\n"
02578           << " }";
02579         return s;
02580 }
02581 
02582 
02583 
02584 
02585 
02586 
02587 
02588 
02589 
02590 
02591 void LLAgent::setAvatarObject(LLVOAvatar *avatar)                       
02592 { 
02593         mAvatarObject = avatar;
02594 
02595         if (!avatar)
02596         {
02597                 llinfos << "Setting LLAgent::mAvatarObject to NULL" << llendl;
02598                 return;
02599         }
02600 
02601         if (!mLookAt)
02602         {
02603                 mLookAt = (LLHUDEffectLookAt *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
02604         }
02605         if (!mPointAt)
02606         {
02607                 mPointAt = (LLHUDEffectPointAt *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
02608         }
02609         
02610         if (!mLookAt.isNull())
02611         {
02612                 mLookAt->setSourceObject(avatar);
02613         }
02614         if (!mPointAt.isNull())
02615         {
02616                 mPointAt->setSourceObject(avatar);
02617         }
02618 
02619         sendAgentWearablesRequest();
02620 }
02621 
02622 
02623 
02624 
02625 
02626 
02627 BOOL LLAgent::needsRenderAvatar()
02628 {
02629         if (cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson)
02630         {
02631                 return FALSE;
02632         }
02633 
02634         return mShowAvatar && mGenderChosen;
02635 }
02636 
02637 
02638 BOOL LLAgent::needsRenderHead()
02639 {
02640         return mShowAvatar && !cameraMouselook();
02641 }
02642 
02643 
02644 
02645 
02646 void LLAgent::startTyping()
02647 {
02648         mTypingTimer.reset();
02649 
02650         if (getRenderState() & AGENT_STATE_TYPING)
02651         {
02652                 
02653                 return;
02654         }
02655         setRenderState(AGENT_STATE_TYPING);
02656 
02657         if (mChatTimer.getElapsedTimeF32() < 2.f)
02658         {
02659                 LLViewerObject* chatter = gObjectList.findObject(mLastChatterID);
02660                 if (chatter && chatter->isAvatar())
02661                 {
02662                         gAgent.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero);
02663                 }
02664         }
02665 
02666         if (gSavedSettings.getBOOL("PlayTypingAnim"))
02667         {
02668                 sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
02669         }
02670         sendChat("", 0, CHAT_TYPE_START, false);
02671 
02672         
02673         
02674         if ( NULL != gFloaterAvatarList )
02675         {
02676                 LLAvatarListEntry *ent = gFloaterAvatarList->getAvatarEntry(getID());
02677                 if ( NULL != ent )
02678                 {
02679                         ent->setActivity(ACTIVITY_TYPING);
02680                 }
02681         }
02682 }
02683 
02684 
02685 
02686 
02687 void LLAgent::stopTyping()
02688 {
02689         if (mRenderState & AGENT_STATE_TYPING)
02690         {
02691                 clearRenderState(AGENT_STATE_TYPING);
02692                 sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
02693                 sendChat("", 0, CHAT_TYPE_STOP, false);
02694         }
02695 }
02696 
02697 
02698 
02699 
02700 void LLAgent::setRenderState(U8 newstate)
02701 {
02702         mRenderState |= newstate;
02703 }
02704 
02705 
02706 
02707 
02708 void LLAgent::clearRenderState(U8 clearstate)
02709 {
02710         mRenderState &= ~clearstate;
02711 }
02712 
02713 
02714 
02715 
02716 
02717 U8 LLAgent::getRenderState()
02718 {
02719         if (gNoRender || gToolMgr == NULL || gSelectMgr == NULL || gKeyboard == NULL)
02720         {
02721                 return 0;
02722         }
02723 
02724         
02725         if ((mTypingTimer.getElapsedTimeF32() > TYPING_TIMEOUT_SECS) 
02726                 && (mRenderState & AGENT_STATE_TYPING))
02727         {
02728                 stopTyping();
02729         }
02730         
02731         if ((!gSelectMgr->getSelection()->isEmpty() && gSelectMgr->shouldShowSelection())
02732                 || gToolMgr->getCurrentTool()->isEditing() )
02733         {
02734                 setRenderState(AGENT_STATE_EDITING);
02735         }
02736         else
02737         {
02738                 clearRenderState(AGENT_STATE_EDITING);
02739         }
02740 
02741         return mRenderState;
02742 }
02743 
02744 
02745 
02746 
02747 static const LLFloaterView::skip_list_t& get_skip_list()
02748 {
02749         static LLFloaterView::skip_list_t skip_list;
02750         skip_list.insert(gFloaterMap);
02751         return skip_list;
02752 }
02753 
02754 
02755 
02756 
02757 void LLAgent::endAnimationUpdateUI()
02758 {
02759         if (mCameraMode == mLastCameraMode)
02760         {
02761                 
02762                 return;
02763         }
02764 
02765         
02766         if ( mLastCameraMode == CAMERA_MODE_MOUSELOOK )
02767         {
02768                 
02769                 gViewerWindow->showCursor();
02770                 
02771                 gMenuBarView->setVisible(TRUE);
02772                 gStatusBar->setVisibleForMouselook(true);
02773 
02774                 gToolMgr->setCurrentToolset(gBasicToolset);
02775 
02776                 
02777                 if (TRUE == mViewsPushed)
02778                 {
02779                         mViewsPushed = FALSE;
02780                         gFloaterView->popVisibleAll(get_skip_list());
02781                 }
02782 
02783                 gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
02784                 if( gMorphView )
02785                 {
02786                         gMorphView->setVisible( FALSE );
02787                 }
02788 
02789                 
02790                 if (mAvatarObject)
02791                 {
02792                         if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
02793                         {
02794                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_RIFLE_R) != mAvatarObject->mSignaledAnimations.end())
02795                                 {
02796                                         sendAnimationRequest(ANIM_AGENT_AIM_RIFLE_R, ANIM_REQUEST_STOP);
02797                                         sendAnimationRequest(ANIM_AGENT_HOLD_RIFLE_R, ANIM_REQUEST_START);
02798                                 }
02799                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_HANDGUN_R) != mAvatarObject->mSignaledAnimations.end())
02800                                 {
02801                                         sendAnimationRequest(ANIM_AGENT_AIM_HANDGUN_R, ANIM_REQUEST_STOP);
02802                                         sendAnimationRequest(ANIM_AGENT_HOLD_HANDGUN_R, ANIM_REQUEST_START);
02803                                 }
02804                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_BAZOOKA_R) != mAvatarObject->mSignaledAnimations.end())
02805                                 {
02806                                         sendAnimationRequest(ANIM_AGENT_AIM_BAZOOKA_R, ANIM_REQUEST_STOP);
02807                                         sendAnimationRequest(ANIM_AGENT_HOLD_BAZOOKA_R, ANIM_REQUEST_START);
02808                                 }
02809                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_BOW_L) != mAvatarObject->mSignaledAnimations.end())
02810                                 {
02811                                         sendAnimationRequest(ANIM_AGENT_AIM_BOW_L, ANIM_REQUEST_STOP);
02812                                         sendAnimationRequest(ANIM_AGENT_HOLD_BOW_L, ANIM_REQUEST_START);
02813                                 }
02814                         }
02815                 }
02816         }
02817         else
02818         if(     mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR )
02819         {
02820                 
02821 
02822                 gToolMgr->setCurrentToolset(gBasicToolset);
02823 
02824                 
02825                 
02826                 if (!gQuitRequested)
02827                 {
02828                         gFloaterMap->popVisible();
02829                 }
02830 
02831                 if( gMorphView )
02832                 {
02833                         gMorphView->setVisible( FALSE );
02834                 }
02835 
02836                 if (mAvatarObject)
02837                 {
02838                         sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_STOP);
02839                         sendAnimationRequest(ANIM_AGENT_CUSTOMIZE_DONE, ANIM_REQUEST_START);
02840                 }
02841                 setLookAt(LOOKAT_TARGET_CLEAR);
02842         }
02843 
02844         
02845         
02846         
02847         if (mCameraMode == CAMERA_MODE_MOUSELOOK)
02848         {
02849                 
02850                 gMenuBarView->setVisible(FALSE);
02851                 gStatusBar->setVisibleForMouselook(false);
02852 
02853                 
02854                 mCameraLag.clearVec();
02855 
02856                 
02857                 gFocusMgr.setKeyboardFocus(NULL, NULL);
02858 
02859                 gToolMgr->setCurrentToolset(gMouselookToolset);
02860 
02861                 mViewsPushed = TRUE;
02862 
02863                 gFloaterView->pushVisibleAll(FALSE, get_skip_list());
02864 
02865                 if( gMorphView )
02866                 {
02867                         gMorphView->setVisible(FALSE);
02868                 }
02869 
02870                 gIMMgr->setFloaterOpen( FALSE );
02871                 gConsole->setVisible( TRUE );
02872 
02873                 if (mAvatarObject)
02874                 {
02875                         
02876                         if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_HOLD_ANIMS, NUM_AGENT_GUN_HOLD_ANIMS) )
02877                         {
02878                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_RIFLE_R) != mAvatarObject->mSignaledAnimations.end())
02879                                 {
02880                                         sendAnimationRequest(ANIM_AGENT_HOLD_RIFLE_R, ANIM_REQUEST_STOP);
02881                                         sendAnimationRequest(ANIM_AGENT_AIM_RIFLE_R, ANIM_REQUEST_START);
02882                                 }
02883                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_HANDGUN_R) != mAvatarObject->mSignaledAnimations.end())
02884                                 {
02885                                         sendAnimationRequest(ANIM_AGENT_HOLD_HANDGUN_R, ANIM_REQUEST_STOP);
02886                                         sendAnimationRequest(ANIM_AGENT_AIM_HANDGUN_R, ANIM_REQUEST_START);
02887                                 }
02888                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_BAZOOKA_R) != mAvatarObject->mSignaledAnimations.end())
02889                                 {
02890                                         sendAnimationRequest(ANIM_AGENT_HOLD_BAZOOKA_R, ANIM_REQUEST_STOP);
02891                                         sendAnimationRequest(ANIM_AGENT_AIM_BAZOOKA_R, ANIM_REQUEST_START);
02892                                 }
02893                                 if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_BOW_L) != mAvatarObject->mSignaledAnimations.end())
02894                                 {
02895                                         sendAnimationRequest(ANIM_AGENT_HOLD_BOW_L, ANIM_REQUEST_STOP);
02896                                         sendAnimationRequest(ANIM_AGENT_AIM_BOW_L, ANIM_REQUEST_START);
02897                                 }
02898                         }
02899                         if (mAvatarObject->getParent())
02900                         {
02901                                 LLVector3 at_axis = gCamera->getAtAxis();
02902                                 LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
02903                                 if (root_object->flagCameraDecoupled())
02904                                 {
02905                                         resetAxes(at_axis);
02906                                 }
02907                                 else
02908                                 {
02909                                         resetAxes(at_axis * ~((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation());
02910                                 }
02911                         }
02912                 }
02913 
02914         }
02915         else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
02916         {
02917                 gToolMgr->setCurrentToolset(gFaceEditToolset);
02918 
02919                 gFloaterMap->pushVisible(FALSE);
02920                 
02921 
02922 
02923 
02924 
02925 
02926 
02927 
02928                 if( gMorphView )
02929                 {
02930                         gMorphView->setVisible( TRUE );
02931                 }
02932 
02933                 
02934                 if (mAvatarObject)
02935                 {
02936                         mPauseRequest = mAvatarObject->requestPause();
02937                 }
02938         }
02939 
02940         if (getAvatarObject())
02941         {
02942                 getAvatarObject()->updateAttachmentVisibility(mCameraMode);
02943         }
02944 
02945         gFloaterTools->dirty();
02946 
02947         
02948         
02949         mLastCameraMode = mCameraMode;
02950 
02951 }
02952 
02953 
02954 
02955 
02956 
02957 void LLAgent::updateCamera()
02958 {
02959         
02960         mCameraUpVector = LLVector3::z_axis;
02961         
02962         
02963 
02964         U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
02965 
02966         validateFocusObject();
02967 
02968         if (!mAvatarObject.isNull() && 
02969                 mAvatarObject->mIsSitting &&
02970                 camera_mode == CAMERA_MODE_MOUSELOOK)
02971         {
02972                 
02973                 
02974                 mCameraUpVector = mCameraUpVector * mAvatarObject->getRenderRotation();
02975                 
02976         }
02977 
02978         if (cameraThirdPerson() && mFocusOnAvatar && LLFollowCamMgr::getActiveFollowCamParams())
02979         {
02980                 changeCameraToFollow();
02981         }
02982 
02983         
02984         
02985         if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
02986         {
02987                 mCameraUpVector = mFollowCam.getUpVector();
02988         }
02989         
02990 
02991         if (mSitCameraEnabled)
02992         {
02993                 if (mSitCameraReferenceObject->isDead())
02994                 {
02995                         setSitCamera(LLUUID::null);
02996                 }
02997         }
02998 
02999         
03000         if (gFloaterCamera)
03001         {
03002                 gFloaterCamera->mRotate->setToggleState(
03003                         mOrbitRightKey > 0.f,   
03004                         mOrbitUpKey > 0.f,              
03005                         mOrbitLeftKey > 0.f,    
03006                         mOrbitDownKey > 0.f);   
03007 
03008                 gFloaterCamera->mZoom->setToggleState( 
03009                         mOrbitInKey > 0.f,              
03010                         mOrbitOutKey > 0.f);    
03011 
03012                 gFloaterCamera->mTrack->setToggleState(
03013                         mPanLeftKey > 0.f,              
03014                         mPanUpKey > 0.f,                
03015                         mPanRightKey > 0.f,             
03016                         mPanDownKey > 0.f);             
03017         }
03018 
03019         
03020         const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD;                  
03021         const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD;                
03022         const F32 PAN_RATE = 5.f;                                                               
03023 
03024         if( mOrbitUpKey || mOrbitDownKey )
03025         {
03026                 F32 input_rate = mOrbitUpKey - mOrbitDownKey;
03027                 cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped );
03028         }
03029 
03030         if( mOrbitLeftKey || mOrbitRightKey)
03031         {
03032                 F32 input_rate = mOrbitLeftKey - mOrbitRightKey;
03033                 cameraOrbitAround( input_rate * ORBIT_AROUND_RATE / gFPSClamped );
03034         }
03035 
03036         if( mOrbitInKey || mOrbitOutKey )
03037         {
03038                 F32 input_rate = mOrbitInKey - mOrbitOutKey;
03039                 
03040                 LLVector3d to_focus = gAgent.getPosGlobalFromAgent(gCamera->getOrigin()) - calcFocusPositionTargetGlobal();
03041                 F32 distance_to_focus = (F32)to_focus.magVec();
03042                 
03043                 cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped );
03044         }
03045 
03046         if( mPanInKey || mPanOutKey )
03047         {
03048                 F32 input_rate = mPanInKey - mPanOutKey;
03049                 cameraPanIn( input_rate * PAN_RATE / gFPSClamped );
03050         }
03051 
03052         if( mPanRightKey || mPanLeftKey )
03053         {
03054                 F32 input_rate = mPanRightKey - mPanLeftKey;
03055                 cameraPanLeft( input_rate * -PAN_RATE / gFPSClamped );
03056         }
03057 
03058         if( mPanUpKey || mPanDownKey )
03059         {
03060                 F32 input_rate = mPanUpKey - mPanDownKey;
03061                 cameraPanUp( input_rate * PAN_RATE / gFPSClamped );
03062         }
03063 
03064         
03065         mOrbitLeftKey           = 0.f;
03066         mOrbitRightKey          = 0.f;
03067         mOrbitUpKey                     = 0.f;
03068         mOrbitDownKey           = 0.f;
03069         mOrbitInKey                     = 0.f;
03070         mOrbitOutKey            = 0.f;
03071 
03072         mPanRightKey            = 0.f;
03073         mPanLeftKey                     = 0.f;
03074         mPanUpKey                       = 0.f;
03075         mPanDownKey                     = 0.f;
03076         mPanInKey                       = 0.f;
03077         mPanOutKey                      = 0.f;
03078 
03079         
03080         mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
03081 
03082         
03083         if ( mCameraMode == CAMERA_MODE_FOLLOW )
03084         {
03085                 if ( !mAvatarObject.isNull() )
03086                 {
03087                         
03088                         
03089                         
03090                         
03091                         
03092                         
03093                         LLQuaternion avatarRotationForFollowCam = mAvatarObject->mIsSitting ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion();
03094 
03095                         LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams();
03096                         if (current_cam)
03097                         {
03098                                 mFollowCam.copyParams(*current_cam);
03099                                 mFollowCam.setSubjectPositionAndRotation( mAvatarObject->getRenderPosition(), avatarRotationForFollowCam );
03100                                 mFollowCam.update();
03101                         }
03102                         else
03103                         {
03104                                 changeCameraToThirdPerson(TRUE);
03105                         }
03106                 }
03107         }
03108         
03109 
03110         BOOL hit_limit;
03111         LLVector3d camera_pos_global;
03112         LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit);
03113         mCameraVirtualPositionAgent = getPosAgentFromGlobal(camera_target_global);
03114         LLVector3d focus_target_global = calcFocusPositionTargetGlobal();
03115 
03116         
03117         mCameraFOVZoomFactor = calcCameraFOVZoomFactor();
03118         camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor);
03119 
03120         
03121         F32 fade_increment = mFocusObjectFadeTimer.getElapsedTimeAndResetF32();
03122 
03123         if (mFocusObject.notNull() && !mFocusObject->isAttachment() && mFocusObject->mDrawable.notNull())
03124         {
03125                 F32 increment = fade_increment;
03126                 if (mFocusObjectDist < -0.2f)
03127                 {
03128                         increment *= -1.f;
03129                 }
03130 
03131                 if (mFocusObject->getVObjRadius() > MIN_RADIUS_ALPHA_SIZZLE)
03132                 {
03133                         S32 num_faces = mFocusObject->mDrawable->getNumFaces();
03134                         for (S32 i = 0; i < num_faces; i++)
03135                         {
03136                                 LLFace* facep = mFocusObject->mDrawable->getFace(i);
03137                                 F32 fade = facep->mAlphaFade;
03138                                 fade = llclamp(fade + increment, 0.f, 1.f);
03139                                 facep->mAlphaFade = fade;
03140                         }
03141                 }
03142         }
03143 
03144         
03145         std::set< LLPointer<LLViewerObject> >::iterator fade_object_it;
03146         for (fade_object_it = mFadeObjects.begin(); fade_object_it != mFadeObjects.end(); )
03147         {
03148                 LLViewerObject* fade_object = *fade_object_it;
03149                 if (fade_object->isDead())
03150                 {
03151                         
03152                         mFadeObjects.erase(fade_object_it++);
03153                 }
03154                 else
03155                 {
03156                         LLDrawable* drawablep = fade_object->mDrawable;
03157                         if (drawablep && fade_object->getVObjRadius() > MIN_RADIUS_ALPHA_SIZZLE)
03158                         {
03159                                 S32 num_faces = drawablep->getNumFaces();
03160                                 BOOL fade_done = TRUE;
03161                                 for (S32 i = 0; i < num_faces; i++)
03162                                 {
03163                                         LLFace* facep = drawablep->getFace(i);
03164                                         F32 fade = facep->mAlphaFade;
03165                                         fade = llclamp(fade - fade_increment, 0.f, 1.f);
03166                                         facep->mAlphaFade = fade;
03167                                         if (fade > 0.f)
03168                                         {
03169                                                 fade_done = FALSE;
03170                                         }
03171                                 }
03172                                 if (fade_done)
03173                                 {
03174                                         mFadeObjects.erase(fade_object_it++);
03175                                 }
03176                                 else
03177                                 {
03178                                         fade_object_it++;
03179                                 }
03180                         }
03181                         else
03182                         {
03183                                 fade_object_it++;
03184                         }
03185                 }
03186         }
03187 
03188         mShowAvatar = TRUE; 
03189 
03190         
03191         if (mCameraAnimating)
03192         {
03193                 F32 time = mAnimationTimer.getElapsedTimeF32();
03194 
03195                 
03196                 
03197 
03198                 
03199                 F32 fraction_of_animation = time / mAnimationDuration;
03200 
03201                 BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK;
03202                 BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK;
03203                 F32 fraction_animation_to_skip;
03204 
03205                 if (mAnimationCameraStartGlobal == camera_target_global)
03206                 {
03207                         fraction_animation_to_skip = 0.f;
03208                 }
03209                 else
03210                 {
03211                         LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global;
03212                         fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec();
03213                 }
03214                 F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f;
03215                 F32 animation_finish_fraction =  (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f;
03216         
03217                 if (fraction_of_animation < animation_finish_fraction)
03218                 {
03219                         if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction )
03220                         {
03221                                 mShowAvatar = FALSE;
03222                         }
03223 
03224                         
03225                         camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, fraction_of_animation);
03226                         mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, fraction_of_animation);
03227                 }
03228                 else
03229                 {
03230                         
03231                         mCameraAnimating = FALSE;
03232 
03233                         camera_pos_global = camera_target_global;
03234                         mFocusGlobal = focus_target_global;
03235 
03236                         endAnimationUpdateUI();
03237                         mShowAvatar = TRUE;
03238                 }
03239 
03240                 if (getAvatarObject() && mCameraMode != CAMERA_MODE_MOUSELOOK)
03241                 {
03242                         getAvatarObject()->updateAttachmentVisibility(mCameraMode);
03243                 }
03244         }
03245         else
03246         {
03247                 camera_pos_global = camera_target_global;
03248                 mFocusGlobal = focus_target_global;
03249                 mShowAvatar = TRUE;
03250         }
03251 
03252         mCameraCurrentFOVZoomFactor = lerp(mCameraCurrentFOVZoomFactor, mCameraFOVZoomFactor, LLCriticalDamp::getInterpolant(FOV_ZOOM_HALF_LIFE));
03253 
03254 
03255 
03256         F32 ui_offset = 0.f;
03257         if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
03258         {
03259                 ui_offset = calcCustomizeAvatarUIOffset( camera_pos_global );
03260         }
03261 
03262 
03263         LLVector3 focus_agent = getPosAgentFromGlobal(mFocusGlobal);
03264         
03265         mCameraPositionAgent    = getPosAgentFromGlobal(camera_pos_global);
03266 
03267         
03268 
03269         
03270         gCamera->updateCameraLocation(mCameraPositionAgent, mCameraUpVector, focus_agent);
03271         
03272         
03273 
03274         
03275         gCamera->translate(gCamera->getLeftAxis() * ui_offset);
03276         
03277         
03278         gCamera->setView(gCamera->getDefaultFOV() / (1.f + mCameraCurrentFOVZoomFactor));
03279 
03280         
03281         if (cameraCustomizeAvatar())    
03282         {
03283                 setLookAt(LOOKAT_TARGET_FOCUS, NULL, mCameraPositionAgent);
03284         }
03285 
03286         
03287         if(gVoiceClient && getRegion())
03288         {
03289                 LLMatrix3 rot;
03290                 rot.setRows(gCamera->getAtAxis(), gCamera->getLeftAxis (),  gCamera->getUpAxis());              
03291 
03292                 
03293                 gVoiceClient->setCameraPosition(
03294                                 getRegion()->getPosGlobalFromRegion(gCamera->getOrigin()),
03295                                 LLVector3::zero,                        
03296                                 rot);                                           
03297         }
03298 
03299         
03300         
03301         
03302         LLVector3d global_pos = getPositionGlobal(); 
03303         if (! mLastPositionGlobal.isExactlyZero())
03304         {
03305                 LLVector3d delta = global_pos - mLastPositionGlobal;
03306                 mDistanceTraveled += delta.magVec();
03307         }
03308         mLastPositionGlobal = global_pos;
03309         
03310         if (LLVOAvatar::sVisibleInFirstPerson && mAvatarObject.notNull() && !mAvatarObject->mIsSitting && cameraMouselook())
03311         {
03312                 LLVector3 head_pos = mAvatarObject->mHeadp->getWorldPosition() + 
03313                         LLVector3(0.08f, 0.f, 0.05f) * mAvatarObject->mHeadp->getWorldRotation() + 
03314                         LLVector3(0.1f, 0.f, 0.f) * mAvatarObject->mPelvisp->getWorldRotation();
03315                 LLVector3 diff = mCameraPositionAgent - head_pos;
03316                 diff = diff * ~mAvatarObject->mRoot.getWorldRotation();
03317 
03318                 LLJoint* torso_joint = mAvatarObject->mTorsop;
03319                 LLJoint* chest_joint = mAvatarObject->mChestp;
03320                 LLVector3 torso_scale = torso_joint->getScale();
03321                 LLVector3 chest_scale = chest_joint->getScale();
03322 
03323                 
03324                 if (!mAvatarObject->mInAir)
03325                 {
03326                         LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
03327                         F32 z_compensate = llclamp(-diff.mV[VZ], -0.2f, 1.f);
03328                         F32 scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / chest_offset.mV[VZ]), 0.5f, 1.2f);
03329                         torso_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
03330 
03331                         LLJoint* neck_joint = mAvatarObject->mNeckp;
03332                         LLVector3 neck_offset = LLVector3(0.f, 0.f, neck_joint->getPosition().mV[VZ]) * chest_joint->getWorldRotation();
03333                         scale_factor = llclamp(1.f - ((z_compensate * 0.5f) / neck_offset.mV[VZ]), 0.5f, 1.2f);
03334                         chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
03335                         diff.mV[VZ] = 0.f;
03336                 }
03337 
03338                 mAvatarObject->mPelvisp->setPosition(mAvatarObject->mPelvisp->getPosition() + diff);
03339 
03340                 mAvatarObject->mRoot.updateWorldMatrixChildren();
03341 
03342                 for(LLViewerJointAttachment *attachment = mAvatarObject->mAttachmentPoints.getFirstData();
03343                         attachment;
03344                         attachment = mAvatarObject->mAttachmentPoints.getNextData())
03345                 {
03346                         LLViewerObject *attached_object = attachment->getObject();
03347                         if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull())
03348                         {
03349                                 
03350                                 attached_object->mDrawable->clearState(LLDrawable::EARLY_MOVE);
03351                                 gPipeline.updateMoveNormalAsync(attached_object->mDrawable);
03352                                 attached_object->updateText();
03353                         }
03354                 }
03355 
03356                 torso_joint->setScale(torso_scale);
03357                 chest_joint->setScale(chest_scale);
03358         }
03359 }
03360 
03361 void LLAgent::updateFocusOffset()
03362 {
03363         validateFocusObject();
03364         if (mFocusObject.notNull())
03365         {
03366                 LLVector3d obj_pos = getPosGlobalFromAgent(mFocusObject->getRenderPosition());
03367                 mFocusObjectOffset.setVec(mFocusTargetGlobal - obj_pos);
03368         }
03369 }
03370 
03371 void LLAgent::validateFocusObject()
03372 {
03373         if (mFocusObject.notNull() && 
03374                 (mFocusObject->isDead()))
03375         {
03376                 mFocusObjectOffset.clearVec();
03377                 clearFocusObject();
03378                 mCameraFOVZoomFactor = 0.f;
03379         }
03380 }
03381 
03382 
03383 
03384 
03385 F32 LLAgent::calcCustomizeAvatarUIOffset( const LLVector3d& camera_pos_global )
03386 {
03387         F32 ui_offset = 0.f;
03388 
03389         if( gFloaterCustomize )
03390         {
03391                 const LLRect& rect = gFloaterCustomize->getRect();
03392 
03393                 
03394                 F32 fraction_of_fov = 0.5f - (0.5f * (1.f - llmin(1.f, ((F32)rect.getWidth() / (F32)gViewerWindow->getWindowWidth()))));
03395                 F32 apparent_angle = fraction_of_fov * gCamera->getView() * gCamera->getAspect();  
03396                 F32 offset = tan(apparent_angle);
03397 
03398                 if( rect.mLeft < (gViewerWindow->getWindowWidth() - rect.mRight) )
03399                 {
03400                         
03401                         ui_offset = offset;
03402                 }
03403                 else
03404                 {
03405                         
03406                         ui_offset = -offset;
03407                 }
03408         }
03409         F32 range = (F32)dist_vec(camera_pos_global, gAgent.getFocusGlobal());
03410         mUIOffset = lerp(mUIOffset, ui_offset, LLCriticalDamp::getInterpolant(0.05f));
03411         return mUIOffset * range;
03412 }
03413 
03414 
03415 
03416 
03417 LLVector3d LLAgent::calcFocusPositionTargetGlobal()
03418 {
03419         if (mFocusObject.notNull() && mFocusObject->isDead())
03420         {
03421                 clearFocusObject();
03422         }
03423 
03424         
03425         if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
03426         {
03427                 mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
03428                 return mFocusTargetGlobal;
03429         }
03430         else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
03431         {
03432                 LLVector3d at_axis(1.0, 0.0, 0.0);
03433                 LLQuaternion agent_rot = mFrameAgent.getQuaternion();
03434                 if (!mAvatarObject.isNull() && mAvatarObject->getParent())
03435                 {
03436                         LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
03437                         if (!root_object->flagCameraDecoupled())
03438                         {
03439                                 agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
03440                         }
03441                 }
03442                 at_axis = at_axis * agent_rot;
03443                 mFocusTargetGlobal = calcCameraPositionTargetGlobal() + at_axis;
03444                 return mFocusTargetGlobal;
03445         }
03446         else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
03447         {
03448                 return mFocusTargetGlobal;
03449         }
03450         else if (!mFocusOnAvatar)
03451         {
03452                 if (mFocusObject.notNull() && !mFocusObject->isDead() && mFocusObject->mDrawable.notNull())
03453                 {
03454                         LLDrawable* drawablep = mFocusObject->mDrawable;
03455                         
03456                         if (mTrackFocusObject &&
03457                                 drawablep && 
03458                                 drawablep->isActive())
03459                         {
03460                                 if (!mFocusObject->isAvatar())
03461                                 {
03462                                         if (mFocusObject->isSelected())
03463                                         {
03464                                                 gPipeline.updateMoveNormalAsync(drawablep);
03465                                         }
03466                                         else
03467                                         {
03468                                                 if (drawablep->isState(LLDrawable::MOVE_UNDAMPED))
03469                                                 {
03470                                                         gPipeline.updateMoveNormalAsync(drawablep);
03471                                                 }
03472                                                 else
03473                                                 {
03474                                                         gPipeline.updateMoveDampedAsync(drawablep);
03475                                                 }
03476                                         }
03477                                 }
03478                         }
03479                         
03480                         else
03481                         {
03482                                 updateFocusOffset();
03483                         }
03484                         LLVector3 focus_agent = mFocusObject->getRenderPosition() + mFocusObjectOffset;
03485                         mFocusTargetGlobal.setVec(getPosGlobalFromAgent(focus_agent));
03486                 }
03487                 return mFocusTargetGlobal;
03488         }
03489         else if (mSitCameraEnabled && mAvatarObject.notNull() && mAvatarObject->mIsSitting && mSitCameraReferenceObject.notNull())
03490         {
03491                 
03492                 LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
03493                 LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
03494 
03495                 LLVector3 target_pos = object_pos + (mSitCameraFocus * object_rot);
03496                 return getPosGlobalFromAgent(target_pos);
03497         }
03498         else
03499         {
03500                 
03501                 LLVector3d focus_offset;
03502                 focus_offset.setVec(gSavedSettings.getVector3("FocusOffsetDefault"));
03503 
03504                 LLQuaternion agent_rot = mFrameAgent.getQuaternion();
03505                 if (!mAvatarObject.isNull() && mAvatarObject->getParent())
03506                 {
03507                         agent_rot *= ((LLViewerObject*)(mAvatarObject->getParent()))->getRenderRotation();
03508                 }
03509 
03510                 focus_offset = focus_offset * agent_rot;
03511 
03512                 return getPositionGlobal() + focus_offset;
03513         }
03514 }
03515 
03516 void LLAgent::setupSitCamera()
03517 {
03518         
03519         if (mAvatarObject.notNull() && mAvatarObject->getParent())
03520         {
03521                 LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
03522                 
03523                 LLVector3 at_axis = mFrameAgent.getAtAxis();
03524                 at_axis.mV[VZ] = 0.f;
03525                 at_axis.normVec();
03526                 resetAxes(at_axis * ~parent_rot);
03527         }
03528 }
03529 
03530 
03531 
03532 
03533 const LLVector3 &LLAgent::getCameraPositionAgent() const
03534 {
03535         return gCamera->getOrigin();
03536 }
03537 
03538 
03539 
03540 
03541 LLVector3d LLAgent::getCameraPositionGlobal() const
03542 {
03543         if (gCamera)
03544         {
03545                 return getPosGlobalFromAgent(gCamera->getOrigin());
03546         }
03547         else
03548         {
03549                 return (LLVector3d::zero);
03550         }
03551 }
03552 
03553 
03554 
03555 
03556 F32     LLAgent::calcCameraFOVZoomFactor()
03557 {
03558         LLVector3 camera_offset_dir;
03559         camera_offset_dir.setVec(mCameraFocusOffset);
03560 
03561         if (mCameraMode == CAMERA_MODE_MOUSELOOK)
03562         {
03563                 return 0.f;
03564         }
03565         else if (mFocusObject.notNull() && !mFocusObject->isAvatar())
03566         {
03567                 
03568                 LLVector3 focus_offset = mFocusObjectOffset;
03569                 F32 obj_min_dist = 0.f;
03570                 calcCameraMinDistance(obj_min_dist);
03571                 F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
03572 
03573                 mFocusObjectDist = obj_min_dist - current_distance;
03574 
03575                 F32 new_fov_zoom = llclamp(mFocusObjectDist / current_distance, 0.f, 1000.f);
03576                 return new_fov_zoom;
03577         }
03578         else 
03579         {
03580                 
03581                 return mCameraFOVZoomFactor;
03582                 
03583         }
03584 }
03585 
03586 
03587 
03588 
03589 LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
03590 {
03591         
03592         F32                     camera_land_height;
03593         LLVector3d      frame_center_global = mAvatarObject.isNull() ? getPositionGlobal() 
03594                                                                                                                          : getPosGlobalFromAgent(mAvatarObject->mRoot.getWorldPosition());
03595                 
03596         LLVector3   upAxis = getUpAxis();
03597         BOOL            isConstrained = FALSE;
03598         LLVector3d      head_offset;
03599         head_offset.setVec(mThirdPersonHeadOffset);
03600 
03601         LLVector3d camera_position_global;
03602 
03603         
03604         if ( mCameraMode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
03605         {
03606                 camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
03607         }
03608         else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
03609         {
03610                 if (mAvatarObject.isNull() || mAvatarObject->mDrawable.isNull())
03611                 {
03612                         llwarns << "Null avatar drawable!" << llendl;
03613                         return LLVector3d::zero;
03614                 }
03615                 head_offset.clearVec();
03616                 if (mAvatarObject->mIsSitting && mAvatarObject->getParent())
03617                 {
03618                         mAvatarObject->updateHeadOffset();
03619                         head_offset.mdV[VX] = mAvatarObject->mHeadOffset.mV[VX];
03620                         head_offset.mdV[VY] = mAvatarObject->mHeadOffset.mV[VY];
03621                         head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ] + 0.1f;
03622                         const LLMatrix4& mat = ((LLViewerObject*) mAvatarObject->getParent())->getRenderMatrix();
03623                         camera_position_global = getPosGlobalFromAgent
03624                                                                 ((mAvatarObject->getPosition()+
03625                                                                  LLVector3(head_offset)*mAvatarObject->getRotation()) * mat);
03626                 }
03627                 else
03628                 {
03629                         head_offset.mdV[VZ] = mAvatarObject->mHeadOffset.mV[VZ];
03630                         if (mAvatarObject->mIsSitting)
03631                         {
03632                                 head_offset.mdV[VZ] += 0.1;
03633                         }
03634                         camera_position_global = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());
03635                         head_offset = head_offset * mAvatarObject->getRenderRotation();
03636                         camera_position_global = camera_position_global + head_offset;
03637                 }
03638         }
03639         else if (mCameraMode == CAMERA_MODE_THIRD_PERSON && mFocusOnAvatar)
03640         {
03641                 LLVector3 local_camera_offset;
03642                 F32 camera_distance = 0.f;
03643 
03644                 if (mSitCameraEnabled 
03645                         && mAvatarObject.notNull() 
03646                         && mAvatarObject->mIsSitting 
03647                         && mSitCameraReferenceObject.notNull())
03648                 {
03649                         
03650                         LLVector3 object_pos = mSitCameraReferenceObject->getRenderPosition();
03651                         LLQuaternion object_rot = mSitCameraReferenceObject->getRenderRotation();
03652 
03653                         LLVector3 target_pos = object_pos + (mSitCameraPos * object_rot);
03654 
03655                         camera_position_global = getPosGlobalFromAgent(target_pos);
03656                 }
03657                 else
03658                 {
03659                         local_camera_offset = mCameraZoomFraction * mCameraOffsetDefault;
03660                         
03661                         
03662                         if (mAvatarObject.notNull() && mAvatarObject->getParent())
03663                         {
03664                                 LLQuaternion parent_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
03665                                 
03666                                 LLVector3 at_axis = mFrameAgent.getAtAxis() * parent_rot;
03667                                 at_axis.mV[VZ] = 0.f;
03668                                 at_axis.normVec();
03669                                 resetAxes(at_axis * ~parent_rot);
03670 
03671                                 local_camera_offset = local_camera_offset * mFrameAgent.getQuaternion() * parent_rot;
03672                         }
03673                         else
03674                         {
03675                                 local_camera_offset = mFrameAgent.rotateToAbsolute( local_camera_offset );
03676                         }
03677 
03678                         if (!mCameraCollidePlane.isExactlyZero() && (mAvatarObject.isNull() || !mAvatarObject->mIsSitting))
03679                         {
03680                                 LLVector3 plane_normal;
03681                                 plane_normal.setVec(mCameraCollidePlane.mV);
03682 
03683                                 F32 offset_dot_norm = local_camera_offset * plane_normal;
03684                                 if (llabs(offset_dot_norm) < 0.001f)
03685                                 {
03686                                         offset_dot_norm = 0.001f;
03687                                 }
03688                                 
03689                                 camera_distance = local_camera_offset.normVec();
03690 
03691                                 F32 pos_dot_norm = getPosAgentFromGlobal(frame_center_global + head_offset) * plane_normal;
03692                                 
03693                                 
03694                                 if (pos_dot_norm > mCameraCollidePlane.mV[VW])
03695                                 {
03696                                         
03697                                         if (offset_dot_norm + pos_dot_norm < mCameraCollidePlane.mV[VW])
03698                                         {
03699                                                 
03700                                                 camera_distance *= (pos_dot_norm - mCameraCollidePlane.mV[VW] - CAMERA_COLLIDE_EPSILON) / -offset_dot_norm;
03701                                         }
03702                                 }
03703                                 else
03704                                 {
03705                                         if (offset_dot_norm + pos_dot_norm > mCameraCollidePlane.mV[VW])
03706                                         {
03707                                                 camera_distance *= (mCameraCollidePlane.mV[VW] - pos_dot_norm - CAMERA_COLLIDE_EPSILON) / offset_dot_norm;
03708                                         }
03709                                 }
03710                         }
03711                         else
03712                         {
03713                                 camera_distance = local_camera_offset.normVec();
03714                         }
03715 
03716                         mTargetCameraDistance = llmax(camera_distance, MIN_CAMERA_DISTANCE);
03717 
03718                         if (mTargetCameraDistance != mCurrentCameraDistance)
03719                         {
03720                                 F32 camera_lerp_amt = LLCriticalDamp::getInterpolant(CAMERA_ZOOM_HALF_LIFE);
03721 
03722                                 mCurrentCameraDistance = lerp(mCurrentCameraDistance, mTargetCameraDistance, camera_lerp_amt);
03723                         }
03724 
03725                         
03726                         local_camera_offset *= mCurrentCameraDistance;
03727 
03728                         
03729                         LLVector3d camera_offset;
03730                         
03731                         LLVector3 av_pos = mAvatarObject.isNull() ? LLVector3::zero : mAvatarObject->getRenderPosition();
03732                         camera_offset.setVec( local_camera_offset );
03733                         camera_position_global = frame_center_global + head_offset + camera_offset;
03734 
03735                         if (!mAvatarObject.isNull())
03736                         {
03737                                 LLVector3d camera_lag_d;
03738                                 F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
03739                                 LLVector3 target_lag;
03740                                 LLVector3 vel = getVelocity();
03741 
03742                                 
03743                                 F32 time_in_air = mAvatarObject->mTimeInAir.getElapsedTimeF32();
03744                                 if(!mCameraAnimating && mAvatarObject->mInAir && time_in_air > GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME)
03745                                 {
03746                                         LLVector3 frame_at_axis = mFrameAgent.getAtAxis();
03747                                         frame_at_axis -= projected_vec(frame_at_axis, getReferenceUpVector());
03748                                         frame_at_axis.normVec();
03749 
03750                                         
03751                                         F32 u = (time_in_air - GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME) / GROUND_TO_AIR_CAMERA_TRANSITION_TIME;
03752                                         u = llclamp(u, 0.f, 1.f);
03753 
03754                                         lag_interp *= u;
03755 
03756                                         if (gViewerWindow->getLeftMouseDown() && gLastHitObjectID == mAvatarObject->getID())
03757                                         {
03758                                                 
03759                                                 target_lag.clearVec();
03760                                         }
03761                                         else
03762                                         {
03763                                                 target_lag = vel * gSavedSettings.getF32("DynamicCameraStrength") / 30.f;
03764                                         }
03765 
03766                                         mCameraLag = lerp(mCameraLag, target_lag, lag_interp);
03767 
03768                                         F32 lag_dist = mCameraLag.magVec();
03769                                         if (lag_dist > MAX_CAMERA_LAG)
03770                                         {
03771                                                 mCameraLag = mCameraLag * MAX_CAMERA_LAG / lag_dist;
03772                                         }
03773 
03774                                         
03775                                         F32 dot = (mCameraLag - (frame_at_axis * (MIN_CAMERA_LAG * u))) * frame_at_axis;
03776                                         if (dot < -(MIN_CAMERA_LAG * u))
03777                                         {
03778                                                 mCameraLag -= (dot + (MIN_CAMERA_LAG * u)) * frame_at_axis;
03779                                         }
03780                                 }
03781                                 else
03782                                 {
03783                                         mCameraLag = lerp(mCameraLag, LLVector3::zero, LLCriticalDamp::getInterpolant(0.15f));
03784                                 }
03785 
03786                                 camera_lag_d.setVec(mCameraLag);
03787                                 camera_position_global = camera_position_global - camera_lag_d;
03788                         }
03789                 }
03790         }
03791         else
03792         {
03793                 LLVector3d focusPosGlobal = calcFocusPositionTargetGlobal();
03794                 
03795                 camera_position_global = focusPosGlobal + mCameraFocusOffset;
03796         }
03797 
03798         if (!gSavedSettings.getBOOL("DisableCameraConstraints") && !gAgent.isGodlike())
03799         {
03800                 LLViewerRegion* regionp = gWorldPointer->getRegionFromPosGlobal(
03801                         camera_position_global);
03802                 bool constrain = true;
03803                 if(regionp && regionp->canManageEstate())
03804                 {
03805                         constrain = false;
03806                 }
03807                 if(constrain)
03808                 {
03809                         F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ?
03810                                 APPEARANCE_MAX_ZOOM : MAX_CAMERA_DISTANCE_FROM_AGENT;
03811 
03812                         LLVector3d camera_offset = camera_position_global
03813                                 - gAgent.getPositionGlobal();
03814                         F32 camera_distance = (F32)camera_offset.magVec();
03815 
03816                         if(camera_distance > max_dist)
03817                         {
03818                                 camera_position_global = gAgent.getPositionGlobal() + 
03819                                         (max_dist / camera_distance) * camera_offset;
03820                                 isConstrained = TRUE;
03821                         }
03822                 }
03823 
03824 
03825 
03826 
03827 
03828 
03829 
03830 
03831 
03832 
03833         }
03834 
03835         
03836         F32 camera_min_off_ground = getCameraMinOffGround();
03837 
03838         if (gWorldPointer)
03839         {
03840                 camera_land_height = gWorldPointer->resolveLandHeightGlobal(camera_position_global);
03841         }
03842         else
03843         {
03844                 camera_land_height = 0.f;
03845         }
03846 
03847         if (camera_position_global.mdV[VZ] < camera_land_height + camera_min_off_ground)
03848         {
03849                 camera_position_global.mdV[VZ] = camera_land_height + camera_min_off_ground;
03850                 isConstrained = TRUE;
03851         }
03852 
03853 
03854         if (hit_limit)
03855         {
03856                 *hit_limit = isConstrained;
03857         }
03858 
03859         return camera_position_global;
03860 }
03861 
03862 
03863 
03864 
03865 
03866 void LLAgent::handleScrollWheel(S32 clicks)
03867 {
03868         if ( mCameraMode == CAMERA_MODE_FOLLOW && gAgent.getFocusOnAvatar())
03869         {
03870                 if ( ! mFollowCam.getPositionLocked() ) 
03871                 {
03872                         mFollowCam.zoom( clicks ); 
03873                         if ( mFollowCam.isZoomedToMinimumDistance() )
03874                         {
03875                                 changeCameraToMouselook(FALSE);
03876                         }
03877                 }
03878         }
03879         else
03880         {
03881                 LLObjectSelectionHandle selection = gSelectMgr->getSelection();
03882                 const F32 ROOT_ROOT_TWO = sqrt(F_SQRT2);
03883 
03884                 
03885                 if (mCameraAnimating)
03886                 {
03887                         return;
03888                 }
03889 
03890                 if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
03891                 {
03892                         F32 zoom_factor = (F32)pow(0.8, -clicks);
03893                         cameraZoomIn(zoom_factor);
03894                 }
03895                 else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
03896                 {
03897                         F32 current_zoom_fraction = mTargetCameraDistance / mCameraOffsetDefault.magVec();
03898                         current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
03899                         
03900                         cameraOrbitIn(current_zoom_fraction * mCameraOffsetDefault.magVec());
03901                 }
03902                 else
03903                 {
03904                         F32 current_zoom_fraction = (F32)mCameraFocusOffsetTarget.magVec();
03905                         cameraOrbitIn(current_zoom_fraction * (1.f - pow(ROOT_ROOT_TWO, clicks)));
03906                 }
03907         }
03908 }
03909 
03910 
03911 
03912 
03913 
03914 F32 LLAgent::getCameraMinOffGround()
03915 {
03916         if (mCameraMode == CAMERA_MODE_MOUSELOOK)
03917         {
03918                 return 0.f;
03919         }
03920         else
03921         {
03922                 if (gSavedSettings.getBOOL("DisableCameraConstraints"))
03923                 {
03924                         return -1000.f;
03925                 }
03926                 else
03927                 {
03928                         return 0.5f;
03929                 }
03930         }
03931 }
03932 
03933 
03934 
03935 
03936 
03937 void LLAgent::resetCamera()
03938 {
03939         
03940         LLVector3 at = mFrameAgent.getAtAxis();
03941         at.mV[VZ] = 0.f;
03942         at.normVec();
03943         gAgent.resetAxes(at);
03944         
03945         mCameraFOVZoomFactor = 0.f;
03946 
03947         updateCamera();
03948 }
03949 
03950 
03951 
03952 
03953 void LLAgent::changeCameraToMouselook(BOOL animate)
03954 {
03955         
03956         gViewerWindow->getWindow()->resetBusyCount();
03957 
03958         
03959         mPauseRequest = NULL;
03960 
03961         gToolMgr->setCurrentToolset(gMouselookToolset);
03962 
03963         gSavedSettings.setBOOL("FirstPersonBtnState",   FALSE);
03964         gSavedSettings.setBOOL("MouselookBtnState",             TRUE);
03965         gSavedSettings.setBOOL("ThirdPersonBtnState",   FALSE);
03966         gSavedSettings.setBOOL("BuildBtnState",                 FALSE);
03967 
03968         if (mAvatarObject)
03969         {
03970                 mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
03971                 mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
03972         }
03973 
03974         
03975         gSelectMgr->deselectAll();
03976         gViewerWindow->hideCursor();
03977         gViewerWindow->moveCursorToCenter();
03978 
03979         if( mCameraMode != CAMERA_MODE_MOUSELOOK )
03980         {
03981                 gViewerWindow->setKeyboardFocus( NULL, NULL );
03982                 
03983                 mLastCameraMode = mCameraMode;
03984                 mCameraMode = CAMERA_MODE_MOUSELOOK;
03985                 U32 old_flags = mControlFlags;
03986                 setControlFlags(AGENT_CONTROL_MOUSELOOK);
03987                 if (old_flags != mControlFlags)
03988                 {
03989                         mbFlagsDirty = TRUE;
03990                 }
03991 
03992                 if (animate)
03993                 {
03994                         startCameraAnimation();
03995                 }
03996                 else
03997                 {
03998                         mCameraAnimating = FALSE;
03999                         endAnimationUpdateUI();
04000                 }
04001         }
04002 }
04003 
04004 
04005 
04006 
04007 
04008 void LLAgent::changeCameraToDefault()
04009 {
04010         if (LLFollowCamMgr::getActiveFollowCamParams())
04011         {
04012                 changeCameraToFollow();
04013         }
04014         else
04015         {
04016                 changeCameraToThirdPerson();
04017         }
04018 }
04019 
04020 
04021 
04022 
04023 
04024 
04025 void LLAgent::changeCameraToFollow(BOOL animate)
04026 {
04027         if( mCameraMode != CAMERA_MODE_FOLLOW )
04028         {
04029                 if (mCameraMode == CAMERA_MODE_MOUSELOOK)
04030                 {
04031                         animate = FALSE;
04032                 }
04033                 startCameraAnimation();
04034 
04035                 mLastCameraMode = mCameraMode;
04036                 mCameraMode = CAMERA_MODE_FOLLOW;
04037 
04038                 
04039                 mFollowCam.reset( mCameraPositionAgent, gCamera->getPointOfInterest(), LLVector3::z_axis );
04040                 
04041                 if (gBasicToolset)
04042                 {
04043                         gToolMgr->setCurrentToolset(gBasicToolset);
04044                 }
04045 
04046                 if (mAvatarObject)
04047                 {
04048                         mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
04049                         mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
04050                         mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
04051                 }
04052 
04053                 gSavedSettings.setBOOL("FirstPersonBtnState",   FALSE);
04054                 gSavedSettings.setBOOL("MouselookBtnState",             FALSE);
04055                 gSavedSettings.setBOOL("ThirdPersonBtnState",   TRUE);
04056                 gSavedSettings.setBOOL("BuildBtnState",                 FALSE);
04057 
04058                 
04059                 mPauseRequest = NULL;
04060 
04061                 U32 old_flags = mControlFlags;
04062                 clearControlFlags(AGENT_CONTROL_MOUSELOOK);
04063                 if (old_flags != mControlFlags)
04064                 {
04065                         mbFlagsDirty = TRUE;
04066                 }
04067 
04068                 if (animate)
04069                 {
04070                         startCameraAnimation();
04071                 }
04072                 else
04073                 {
04074                         mCameraAnimating = FALSE;
04075                         endAnimationUpdateUI();
04076                 }
04077         }
04078 }
04079 
04080 
04081 
04082 
04083 void LLAgent::changeCameraToThirdPerson(BOOL animate)
04084 {
04085 
04086 
04087         gViewerWindow->getWindow()->resetBusyCount();
04088 
04089         mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
04090 
04091         if (mAvatarObject)
04092         {
04093                 mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
04094                 mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
04095                 mAvatarObject->startMotion( ANIM_AGENT_BREATHE_ROT );
04096         }
04097 
04098         gSavedSettings.setBOOL("FirstPersonBtnState",   FALSE);
04099         gSavedSettings.setBOOL("MouselookBtnState",             FALSE);
04100         gSavedSettings.setBOOL("ThirdPersonBtnState",   TRUE);
04101         gSavedSettings.setBOOL("BuildBtnState",                 FALSE);
04102 
04103         LLVector3 at_axis;
04104 
04105         
04106         mPauseRequest = NULL;
04107 
04108         if( mCameraMode != CAMERA_MODE_THIRD_PERSON )
04109         {
04110                 if (gBasicToolset)
04111                 {
04112                         gToolMgr->setCurrentToolset(gBasicToolset);
04113                 }
04114 
04115                 mCameraLag.clearVec();
04116                 if (mCameraMode == CAMERA_MODE_MOUSELOOK)
04117                 {
04118                         mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
04119                         mTargetCameraDistance = MIN_CAMERA_DISTANCE;
04120                         animate = FALSE;
04121                 }
04122                 mLastCameraMode = mCameraMode;
04123                 mCameraMode = CAMERA_MODE_THIRD_PERSON;
04124                 U32 old_flags = mControlFlags;
04125                 clearControlFlags(AGENT_CONTROL_MOUSELOOK);
04126                 if (old_flags != mControlFlags)
04127                 {
04128                         mbFlagsDirty = TRUE;
04129                 }
04130 
04131         }
04132 
04133         
04134         if (!mAvatarObject.isNull() && mAvatarObject->getParent())
04135         {
04136                 LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
04137                 at_axis = gCamera->getAtAxis();
04138                 at_axis.mV[VZ] = 0.f;
04139                 at_axis.normVec();
04140                 resetAxes(at_axis * ~obj_rot);
04141         }
04142         else
04143         {
04144                 at_axis = mFrameAgent.getAtAxis();
04145                 at_axis.mV[VZ] = 0.f;
04146                 at_axis.normVec();
04147                 resetAxes(at_axis);
04148         }
04149 
04150 
04151         if (animate)
04152         {
04153                 startCameraAnimation();
04154         }
04155         else
04156         {
04157                 mCameraAnimating = FALSE;
04158                 endAnimationUpdateUI();
04159         }
04160 }
04161 
04162 
04163 
04164 
04165 void LLAgent::changeCameraToCustomizeAvatar(BOOL animate)
04166 {
04167         setControlFlags(AGENT_CONTROL_STAND_UP); 
04168         gViewerWindow->getWindow()->resetBusyCount();
04169 
04170         if (gFaceEditToolset)
04171         {
04172                 gToolMgr->setCurrentToolset(gFaceEditToolset);
04173         }
04174 
04175         gSavedSettings.setBOOL("FirstPersonBtnState", FALSE);
04176         gSavedSettings.setBOOL("MouselookBtnState", FALSE);
04177         gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE);
04178         gSavedSettings.setBOOL("BuildBtnState", FALSE);
04179 
04180         if (animate)
04181         {
04182                 startCameraAnimation();
04183         }
04184 
04185         
04186         LLVector3 at = mFrameAgent.getAtAxis();
04187         at.mV[VZ] = 0.f;
04188         at.normVec();
04189         gAgent.resetAxes(at);
04190 
04191         if( mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR )
04192         {
04193                 mLastCameraMode = mCameraMode;
04194                 mCameraMode = CAMERA_MODE_CUSTOMIZE_AVATAR;
04195                 U32 old_flags = mControlFlags;
04196                 clearControlFlags(AGENT_CONTROL_MOUSELOOK);
04197                 if (old_flags != mControlFlags)
04198                 {
04199                         mbFlagsDirty = TRUE;
04200                 }
04201 
04202                 gViewerWindow->setKeyboardFocus( NULL, NULL );
04203                 gViewerWindow->setMouseCapture( NULL );
04204 
04205                 LLVOAvatar::onCustomizeStart();
04206         }
04207 
04208         if (animate && !mAvatarObject.isNull())
04209         {
04210                 sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
04211                 mAvatarObject->startMotion(ANIM_AGENT_CUSTOMIZE);
04212                 LLMotion* turn_motion = mAvatarObject->findMotion(ANIM_AGENT_CUSTOMIZE);
04213 
04214                 if (turn_motion)
04215                 {
04216                         mAnimationDuration = turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP;
04217 
04218                 }
04219                 else
04220                 {
04221                         mAnimationDuration = gSavedSettings.getF32("ZoomTime");
04222                 }
04223 
04224 
04225 
04226 
04227                 gAgent.setFocusGlobal(LLVector3d::zero);
04228         }
04229         else
04230         {
04231                 mCameraAnimating = FALSE;
04232                 endAnimationUpdateUI();
04233         }
04234 
04235 }
04236 
04237 
04238 
04239 
04240 
04241 
04242 
04243 
04244 
04245 void LLAgent::startCameraAnimation()
04246 {
04247         mAnimationCameraStartGlobal = getCameraPositionGlobal();
04248         mAnimationFocusStartGlobal = mFocusGlobal;
04249         mAnimationTimer.reset();
04250         mCameraAnimating = TRUE;
04251         mAnimationDuration = gSavedSettings.getF32("ZoomTime");
04252 }
04253 
04254 
04255 
04256 
04257 void LLAgent::stopCameraAnimation()
04258 {
04259         mCameraAnimating = FALSE;
04260 }
04261 
04262 void LLAgent::clearFocusObject()
04263 {
04264         if (mFocusObject.notNull())
04265         {
04266                 startCameraAnimation();
04267 
04268                 setFocusObject(NULL);
04269                 mFocusObjectOffset.clearVec();
04270         }
04271 }
04272 
04273 void LLAgent::setFocusObject(LLViewerObject* object)
04274 {
04275         if (mFocusObject.notNull() && 
04276                 mFocusObject->mDrawable.notNull() && 
04277                 mFocusObject->getPCode() == LL_PCODE_VOLUME &&
04278                 mFocusObject != object)
04279         {
04280                 LLPointer<LLViewerObject> fade_object_ptr(mFocusObject);
04281 
04282                 if (fade_object_ptr.notNull() && mFadeObjects.find(fade_object_ptr) == mFadeObjects.end())
04283                 {
04284                         mFadeObjects.insert(fade_object_ptr);
04285                 }
04286         }
04287 
04288         mFocusObject = object;
04289 }
04290 
04291 
04292 
04293 
04294 
04295 void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
04296 {
04297         setFocusObject(gObjectList.findObject(object_id));
04298         LLVector3d old_focus = mFocusTargetGlobal;
04299         LLViewerObject *focus_obj = mFocusObject;
04300 
04301         
04302         if (old_focus != focus)
04303         {
04304                 if (focus.isExactlyZero())
04305                 {
04306                         if (!mAvatarObject.isNull())
04307                         {
04308                                 mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
04309                         }
04310                         else
04311                         {
04312                                 mFocusTargetGlobal = getPositionGlobal();
04313                         }
04314                         mCameraFocusOffsetTarget = getCameraPositionGlobal() - mFocusTargetGlobal;
04315                         mCameraFocusOffset = mCameraFocusOffsetTarget;
04316                         setLookAt(LOOKAT_TARGET_CLEAR);
04317                 }
04318                 else
04319                 {
04320                         mFocusTargetGlobal = focus;
04321                         if (!focus_obj)
04322                         {
04323                                 mCameraFOVZoomFactor = 0.f;
04324                         }
04325 
04326                         mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(mCameraVirtualPositionAgent) - mFocusTargetGlobal;
04327 
04328                         startCameraAnimation();
04329 
04330                         if (focus_obj)
04331                         {
04332                                 if (focus_obj->isAvatar())
04333                                 {
04334                                         setLookAt(LOOKAT_TARGET_FOCUS, focus_obj);
04335                                 }
04336                                 else
04337                                 {
04338                                         setLookAt(LOOKAT_TARGET_FOCUS, focus_obj, (getPosAgentFromGlobal(focus) - focus_obj->getRenderPosition()) * ~focus_obj->getRenderRotation());
04339                                 }
04340                         }
04341                         else
04342                         {
04343                                 setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal));
04344                         }
04345                 }
04346         }
04347         else 
04348         {
04349                 if (focus.isExactlyZero())
04350                 {
04351                         if (!mAvatarObject.isNull())
04352                         {
04353                                 mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
04354                         }
04355                         else
04356                         {
04357                                 mFocusTargetGlobal = getPositionGlobal();
04358                         }
04359                 }
04360                 mCameraFocusOffsetTarget = (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor);;
04361                 mCameraFocusOffset = mCameraFocusOffsetTarget;
04362         }
04363 
04364         if (mFocusObject.notNull())
04365         {
04366                 
04367                 if (mFocusObject->isAttachment())
04368                 {
04369                         while (!mFocusObject->isAvatar())
04370                         {
04371                                 mFocusObject = (LLViewerObject*) mFocusObject->getParent();
04372                         }
04373                         setFocusObject((LLViewerObject*)mFocusObject);
04374                 }
04375                 updateFocusOffset();
04376         }
04377 }
04378 
04379 
04380 
04381 
04382 
04383 void LLAgent::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, const LLVector3d& focus, const LLUUID &object_id)
04384 {
04385         LLVector3d old_focus = mFocusTargetGlobal;
04386 
04387         F64 focus_delta_squared = (old_focus - focus).magVecSquared();
04388         const F64 ANIM_EPSILON_SQUARED = 0.0001;
04389         if( focus_delta_squared > ANIM_EPSILON_SQUARED )
04390         {
04391                 startCameraAnimation();
04392 
04393                 if( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) 
04394                 {
04395                         
04396                         mAnimationCameraStartGlobal -= LLVector3d(gCamera->getLeftAxis() * calcCustomizeAvatarUIOffset( mAnimationCameraStartGlobal ));
04397                 }
04398         }
04399         
04400         
04401         setFocusObject(gObjectList.findObject(object_id));
04402         mFocusTargetGlobal = focus;
04403         mCameraFocusOffsetTarget = camera_pos - focus;
04404         mCameraFocusOffset = mCameraFocusOffsetTarget;
04405 
04406         if (mFocusObject)
04407         {
04408                 if (mFocusObject->isAvatar())
04409                 {
04410                         setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject);
04411                 }
04412                 else
04413                 {
04414                         setLookAt(LOOKAT_TARGET_FOCUS, mFocusObject, (getPosAgentFromGlobal(focus) - mFocusObject->getRenderPosition()) * ~mFocusObject->getRenderRotation());
04415                 }
04416         }
04417         else
04418         {
04419                 setLookAt(LOOKAT_TARGET_FOCUS, NULL, getPosAgentFromGlobal(mFocusTargetGlobal));
04420         }
04421 
04422         if( mCameraAnimating )
04423         {
04424                 const F64 ANIM_METERS_PER_SECOND = 10.0;
04425                 const F64 MIN_ANIM_SECONDS = 0.5;
04426                 F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
04427                 setAnimationDuration( (F32)anim_duration );
04428         }
04429 
04430         updateFocusOffset();
04431 }
04432 
04433 
04434 
04435 
04436 void LLAgent::setSitCamera(const LLUUID &object_id, const LLVector3 &camera_pos, const LLVector3 &camera_focus)
04437 {
04438         BOOL camera_enabled = !object_id.isNull();
04439 
04440         if (camera_enabled)
04441         {
04442                 LLViewerObject *reference_object = gObjectList.findObject(object_id);
04443                 if (reference_object)
04444                 {
04445                         
04446                         mSitCameraPos = camera_pos;
04447                         mSitCameraFocus = camera_focus;
04448                         mSitCameraReferenceObject = reference_object;
04449                         mSitCameraEnabled = TRUE;
04450                 }
04451         }
04452         else
04453         {
04454                 mSitCameraPos.clearVec();
04455                 mSitCameraFocus.clearVec();
04456                 mSitCameraReferenceObject = NULL;
04457                 mSitCameraEnabled = FALSE;
04458         }
04459 }
04460 
04461 
04462 
04463 
04464 void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
04465 {
04466         if (focus_on_avatar != mFocusOnAvatar)
04467         {
04468                 if (animate)
04469                 {
04470                         startCameraAnimation();
04471                 }
04472                 else
04473                 {
04474                         stopCameraAnimation();
04475                 }
04476         }
04477         
04478         
04479         
04480         
04481         if (focus_on_avatar && !mFocusOnAvatar)
04482         {
04483                 setFocusGlobal(LLVector3d::zero);
04484                 mCameraFOVZoomFactor = 0.f;
04485                 if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
04486                 {
04487                         LLVector3 at_axis;
04488                         if (!mAvatarObject.isNull() && mAvatarObject->getParent())
04489                         {
04490                                 LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
04491                                 at_axis = gCamera->getAtAxis();
04492                                 at_axis.mV[VZ] = 0.f;
04493                                 at_axis.normVec();
04494                                 resetAxes(at_axis * ~obj_rot);
04495                         }
04496                         else
04497                         {
04498                                 at_axis = gCamera->getAtAxis();
04499                                 at_axis.mV[VZ] = 0.f;
04500                                 at_axis.normVec();
04501                                 resetAxes(at_axis);
04502                         }
04503                 }
04504         }
04505         
04506         mFocusOnAvatar = focus_on_avatar;
04507 }
04508 
04509 
04510 
04511 
04512 void LLAgent::heardChat(const LLUUID& id)
04513 {
04514         
04515         
04516         gLocalSpeakerMgr->speakerChatted(id);
04517 
04518         
04519         if (id == getID()) return;
04520         
04521         if (ll_rand(2) == 0) 
04522         {
04523                 LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
04524                 setLookAt(LOOKAT_TARGET_AUTO_LISTEN, chatter, LLVector3::zero);
04525         }                       
04526 
04527         mLastChatterID = id;
04528         mChatTimer.reset();
04529 }
04530 
04531 
04532 void LLAgent::lookAtLastChat()
04533 {
04534         lookAtObject(mLastChatterID, CAMERA_POSITION_SELF);
04535 }
04536 
04537 
04538 
04539 
04540 void LLAgent::lookAtObject(LLUUID object_id, ECameraPosition camera_pos)
04541 {
04542         
04543         if (mCameraAnimating || !cameraThirdPerson())
04544         {
04545                 return;
04546         }
04547 
04548         LLViewerObject *chatter = gObjectList.findObject(object_id);
04549         if (chatter)
04550         {
04551                 LLVector3 delta_pos;
04552                 if (chatter->isAvatar())
04553                 {
04554                         LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
04555                         if (!mAvatarObject.isNull() && chatter_av->mHeadp)
04556                         {
04557                                 delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
04558                         }
04559                         else
04560                         {
04561                                 delta_pos = chatter->getPositionAgent() - getPositionAgent();
04562                         }
04563                         delta_pos.normVec();
04564 
04565                         setControlFlags(AGENT_CONTROL_STOP);
04566 
04567                         changeCameraToThirdPerson();
04568 
04569                         LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
04570                         LLVector3 left = delta_pos % LLVector3::z_axis;
04571                         left.normVec();
04572                         LLVector3 up = left % delta_pos;
04573                         up.normVec();
04574                         new_camera_pos -= delta_pos * 0.4f;
04575                         new_camera_pos += left * 0.3f;
04576                         new_camera_pos += up * 0.2f;
04577 
04578                         F32 radius = chatter_av->getVObjRadius();
04579                         LLVector3d view_dist(radius, radius, 0.0f);
04580 
04581                         if (chatter_av->mHeadp)
04582                         {
04583                                 setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), object_id);
04584                                 mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
04585 
04586                                 switch(camera_pos)
04587                                 {
04588                                         case CAMERA_POSITION_SELF:
04589                                                 mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
04590                                                 break;
04591                                         case CAMERA_POSITION_OBJECT:
04592                                                 mCameraFocusOffsetTarget =  view_dist;
04593                                                 break;
04594                                 }
04595                         }
04596                         else
04597                         {
04598                                 setFocusGlobal(chatter->getPositionGlobal(), object_id);
04599                                 mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
04600 
04601                                 switch(camera_pos)
04602                                 {
04603                                         case CAMERA_POSITION_SELF:
04604                                                 mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
04605                                                 break;
04606                                         case CAMERA_POSITION_OBJECT:
04607                                                 mCameraFocusOffsetTarget = view_dist;
04608                                                 break;
04609                                 }
04610                         }
04611                         setFocusOnAvatar(FALSE, TRUE);
04612                 }
04613                 else
04614                 {
04615                         delta_pos = chatter->getRenderPosition() - getPositionAgent();
04616                         delta_pos.normVec();
04617 
04618                         setControlFlags(AGENT_CONTROL_STOP);
04619 
04620                         changeCameraToThirdPerson();
04621 
04622                         LLVector3 new_camera_pos = mAvatarObject->mHeadp->getWorldPosition();
04623                         LLVector3 left = delta_pos % LLVector3::z_axis;
04624                         left.normVec();
04625                         LLVector3 up = left % delta_pos;
04626                         up.normVec();
04627                         new_camera_pos -= delta_pos * 0.4f;
04628                         new_camera_pos += left * 0.3f;
04629                         new_camera_pos += up * 0.2f;
04630 
04631                         setFocusGlobal(chatter->getPositionGlobal(), object_id);
04632 
04633                         switch(camera_pos)
04634                         {
04635                                 case CAMERA_POSITION_SELF:
04636                                         mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
04637                                         break;
04638                                 case CAMERA_POSITION_OBJECT:
04639                                         F32 radius = chatter->getVObjRadius();
04640                                         LLVector3d view_dist(radius, radius, 0.0f);
04641                                         mCameraFocusOffsetTarget = view_dist;
04642                                         break;
04643                         }
04644 
04645                         setFocusOnAvatar(FALSE, TRUE);
04646                 }
04647         }
04648 }
04649 
04650 const F32 SIT_POINT_EXTENTS = 0.2f;
04651 
04652 
04653 void LLAgent::setStartPosition(U32 location_id)
04654 {
04655         LLViewerObject          *object;
04656 
04657         if ( !(gAgentID == LLUUID::null) )
04658         {
04659                 
04660                 object = gObjectList.findObject(gAgentID);
04661                 if (object)
04662                 {
04663                         
04664                         
04665                         
04666                         
04667                         const F32 INSET = 0.5f; 
04668                         const F32 REGION_WIDTH = gWorldPointer->getRegionWidthInMeters();
04669 
04670                         LLVector3 agent_pos = getPositionAgent();
04671 
04672                         if (mAvatarObject)
04673                         {
04674                                 
04675                                 agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ];
04676                         }
04677 
04678                         agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET );
04679                         agent_pos.mV[VY] = llclamp( agent_pos.mV[VY], INSET, REGION_WIDTH - INSET );
04680 
04681                         
04682                         agent_pos.mV[VZ] = llclamp( agent_pos.mV[VZ], 
04683                                 mRegionp->getLandHeightRegion( agent_pos ), 
04684                                 gWorldPointer->getRegionMaxHeight() );
04685 
04686                         LLMessageSystem* msg = gMessageSystem;
04687                         msg->newMessageFast(_PREHASH_SetStartLocationRequest);
04688                         msg->nextBlockFast( _PREHASH_AgentData);
04689                         msg->addUUIDFast(_PREHASH_AgentID, getID());
04690                         msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
04691                         msg->nextBlockFast( _PREHASH_StartLocationData);
04692                         
04693                         msg->addStringFast(_PREHASH_SimName, "");
04694                         msg->addU32Fast(_PREHASH_LocationID, location_id);
04695                         msg->addVector3Fast(_PREHASH_LocationPos, agent_pos);
04696                         msg->addVector3Fast(_PREHASH_LocationLookAt,mFrameAgent.getAtAxis());
04697 
04698                         
04699                         
04700                         
04701                         msg->sendReliable(mRegionp->getHost());
04702 
04703                         const U32 HOME_INDEX = 1;
04704                         if( HOME_INDEX == location_id )
04705                         {
04706                                 setHomePosRegion( mRegionp->getHandle(), getPositionAgent() );
04707                         }
04708                 }
04709                 else
04710                 {
04711                         llinfos << "setStartPosition - Can't find agent viewerobject id " << gAgentID << llendl;
04712                 }
04713         }
04714 }
04715 
04716 void LLAgent::requestStopMotion( LLMotion* motion )
04717 {
04718         
04719         
04720         LLUUID anim_state = motion->getID();
04721         onAnimStop(motion->getID());
04722 
04723         
04724         
04725 
04726         sendAnimationRequest( anim_state, ANIM_REQUEST_STOP );
04727 }
04728 
04729 void LLAgent::onAnimStop(const LLUUID& id)
04730 {
04731         
04732         if (id == ANIM_AGENT_STAND)
04733         {
04734                 stopFidget();
04735         }
04736         else if (id == ANIM_AGENT_AWAY)
04737         {
04738                 clearAFK();
04739         }
04740         else if (id == ANIM_AGENT_STANDUP)
04741         {
04742                 
04743                 setControlFlags(AGENT_CONTROL_FINISH_ANIM);
04744 
04745                 
04746                 if (mAvatarObject.notNull() && !mAvatarObject->mBelowWater && rand() % 3 == 0)
04747                         sendAnimationRequest( ANIM_AGENT_BRUSH, ANIM_REQUEST_START );
04748         }
04749         else if (id == ANIM_AGENT_PRE_JUMP || id == ANIM_AGENT_LAND || id == ANIM_AGENT_MEDIUM_LAND)
04750         {
04751                 setControlFlags(AGENT_CONTROL_FINISH_ANIM);
04752         }
04753 }
04754 
04755 BOOL LLAgent::isGodlike() const
04756 {
04757 #ifdef HACKED_GODLIKE_VIEWER
04758         return TRUE;
04759 #else
04760         if(mAdminOverride) return TRUE;
04761         return mGodLevel > GOD_NOT;
04762 #endif
04763 }
04764 
04765 U8 LLAgent::getGodLevel() const
04766 {
04767 #ifdef HACKED_GODLIKE_VIEWER
04768         return GOD_MAINTENANCE;
04769 #else
04770         if(mAdminOverride) return GOD_FULL;
04771         return mGodLevel;
04772 #endif
04773 }
04774 
04775 bool LLAgent::isTeen() const
04776 {
04777         return mAccess < SIM_ACCESS_MATURE;
04778 }
04779 
04780 void LLAgent::setTeen(bool teen)
04781 {
04782         if (teen)
04783         {
04784                 mAccess = SIM_ACCESS_PG;
04785         }
04786         else
04787         {
04788                 mAccess = SIM_ACCESS_MATURE;
04789         }
04790 }
04791 
04792 void LLAgent::buildFullname(std::string& name) const
04793 {
04794         if (mAvatarObject)
04795         {
04796                 name = mAvatarObject->getFullname();
04797         }
04798 }
04799 
04800 void LLAgent::buildFullnameAndTitle(std::string& name) const
04801 {
04802         if (isGroupMember())
04803         {
04804                 name = mGroupTitle;
04805                 name += ' ';
04806         }
04807         else
04808         {
04809                 name.erase(0, name.length());
04810         }
04811 
04812         if (mAvatarObject)
04813         {
04814                 name += mAvatarObject->getFullname();
04815         }
04816 }
04817 
04818 BOOL LLAgent::isInGroup(const LLUUID& group_id) const
04819 {
04820         S32 count = mGroups.count();
04821         for(S32 i = 0; i < count; ++i)
04822         {
04823                 if(mGroups.get(i).mID == group_id)
04824                 {
04825                         return TRUE;
04826                 }
04827         }
04828         return FALSE;
04829 }
04830 
04831 
04832 BOOL LLAgent::hasPowerInGroup(const LLUUID& group_id, U64 power) const
04833 {
04834         
04835         if (GP_NO_POWERS == power) return FALSE;
04836 
04837         S32 count = mGroups.count();
04838         for(S32 i = 0; i < count; ++i)
04839         {
04840                 if(mGroups.get(i).mID == group_id)
04841                 {
04842                         return (BOOL)((mGroups.get(i).mPowers & power) > 0);
04843                 }
04844         }
04845         return FALSE;
04846 }
04847 
04848 BOOL LLAgent::hasPowerInActiveGroup(U64 power) const
04849 {
04850         return (mGroupID.notNull() && (hasPowerInGroup(mGroupID, power)));
04851 }
04852 
04853 U64 LLAgent::getPowerInGroup(const LLUUID& group_id) const
04854 {
04855         S32 count = mGroups.count();
04856         for(S32 i = 0; i < count; ++i)
04857         {
04858                 if(mGroups.get(i).mID == group_id)
04859                 {
04860                         return (mGroups.get(i).mPowers);
04861                 }
04862         }
04863 
04864         return GP_NO_POWERS;
04865 }
04866 
04867 BOOL LLAgent::getGroupData(const LLUUID& group_id, LLGroupData& data) const
04868 {
04869         S32 count = mGroups.count();
04870         for(S32 i = 0; i < count; ++i)
04871         {
04872                 if(mGroups.get(i).mID == group_id)
04873                 {
04874                         data = mGroups.get(i);
04875                         return TRUE;
04876                 }
04877         }
04878         return FALSE;
04879 }
04880 
04881 S32 LLAgent::getGroupContribution(const LLUUID& group_id) const
04882 {
04883         S32 count = mGroups.count();
04884         for(S32 i = 0; i < count; ++i)
04885         {
04886                 if(mGroups.get(i).mID == group_id)
04887                 {
04888                         S32 contribution = mGroups.get(i).mContribution;
04889                         return contribution;
04890                 }
04891         }
04892         return 0;
04893 }
04894 
04895 BOOL LLAgent::setGroupContribution(const LLUUID& group_id, S32 contribution)
04896 {
04897         S32 count = mGroups.count();
04898         for(S32 i = 0; i < count; ++i)
04899         {
04900                 if(mGroups.get(i).mID == group_id)
04901                 {
04902                         mGroups.get(i).mContribution = contribution;
04903                         LLMessageSystem* msg = gMessageSystem;
04904                         msg->newMessage("SetGroupContribution");
04905                         msg->nextBlock("AgentData");
04906                         msg->addUUID("AgentID", gAgentID);
04907                         msg->addUUID("SessionID", gAgentSessionID);
04908                         msg->nextBlock("Data");
04909                         msg->addUUID("GroupID", group_id);
04910                         msg->addS32("Contribution", contribution);
04911                         sendReliableMessage();
04912                         return TRUE;
04913                 }
04914         }
04915         return FALSE;
04916 }
04917 
04918 BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOOL list_in_profile)
04919 {
04920         S32 count = mGroups.count();
04921         for(S32 i = 0; i < count; ++i)
04922         {
04923                 if(mGroups.get(i).mID == group_id)
04924                 {
04925                         mGroups.get(i).mAcceptNotices = accept_notices;
04926                         mGroups.get(i).mListInProfile = list_in_profile;
04927                         LLMessageSystem* msg = gMessageSystem;
04928                         msg->newMessage("SetGroupAcceptNotices");
04929                         msg->nextBlock("AgentData");
04930                         msg->addUUID("AgentID", gAgentID);
04931                         msg->addUUID("SessionID", gAgentSessionID);
04932                         msg->nextBlock("Data");
04933                         msg->addUUID("GroupID", group_id);
04934                         msg->addBOOL("AcceptNotices", accept_notices);
04935                         msg->nextBlock("NewData");
04936                         msg->addBOOL("ListInProfile", list_in_profile);
04937                         sendReliableMessage();
04938                         return TRUE;
04939                 }
04940         }
04941         return FALSE;
04942 }
04943 
04944 
04945 void LLAgent::buildLocationString(std::string& str)
04946 {
04947         const LLVector3& agent_pos_region = getPositionAgent();
04948         S32 pos_x = S32(agent_pos_region.mV[VX]);
04949         S32 pos_y = S32(agent_pos_region.mV[VY]);
04950         S32 pos_z = S32(agent_pos_region.mV[VZ]);
04951 
04952         
04953         LLVector3 agent_velocity = getVelocity();
04954         F32 velocity_mag_sq = agent_velocity.magVecSquared();
04955 
04956         const F32 FLY_CUTOFF = 6.f;             
04957         const F32 FLY_CUTOFF_SQ = FLY_CUTOFF * FLY_CUTOFF;
04958         const F32 WALK_CUTOFF = 1.5f;   
04959         const F32 WALK_CUTOFF_SQ = WALK_CUTOFF * WALK_CUTOFF;
04960 
04961         if (velocity_mag_sq > FLY_CUTOFF_SQ)
04962         {
04963                 pos_x -= pos_x % 4;
04964                 pos_y -= pos_y % 4;
04965         }
04966         else if (velocity_mag_sq > WALK_CUTOFF_SQ)
04967         {
04968                 pos_x -= pos_x % 2;
04969                 pos_y -= pos_y % 2;
04970         }
04971 
04972         
04973         std::string buffer;
04974         if( gParcelMgr->getAgentParcelName().empty() )
04975         {
04976                 
04977                 buffer = llformat("%.32s (%d, %d, %d)",
04978                                                   getRegion()->getName().c_str(),
04979                                                   pos_x, pos_y, pos_z);
04980         }
04981         else
04982         {
04983                 
04984                 buffer = llformat("%.32s, %.32s (%d, %d, %d)",
04985                                                   gParcelMgr->getAgentParcelName().c_str(),
04986                                                   getRegion()->getName().c_str(),
04987                                                   pos_x, pos_y, pos_z);
04988         }
04989         str = buffer;
04990 }
04991 
04992 LLQuaternion LLAgent::getHeadRotation()
04993 {
04994         if (mAvatarObject.isNull() || !mAvatarObject->mPelvisp || !mAvatarObject->mHeadp)
04995         {
04996                 return LLQuaternion::DEFAULT;
04997         }
04998 
04999         if (!gAgent.cameraMouselook())
05000         {
05001                 return mAvatarObject->getRotation();
05002         }
05003 
05004         
05005         LLVector3 look_dir( gCamera->getAtAxis() );
05006         LLVector3 up = look_dir % mFrameAgent.getLeftAxis();
05007         LLVector3 left = up % look_dir;
05008 
05009         LLQuaternion rot(look_dir, left, up);
05010         if (mAvatarObject->getParent())
05011         {
05012                 rot = rot * ~mAvatarObject->getParent()->getRotation();
05013         }
05014 
05015         return rot;
05016 }
05017 
05018 void LLAgent::sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimRequest request)
05019 {
05020         if (gAgentID.isNull())
05021         {
05022                 return;
05023         }
05024 
05025         S32 num_valid_anims = 0;
05026 
05027         LLMessageSystem* msg = gMessageSystem;
05028         msg->newMessageFast(_PREHASH_AgentAnimation);
05029         msg->nextBlockFast(_PREHASH_AgentData);
05030         msg->addUUIDFast(_PREHASH_AgentID, getID());
05031         msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05032 
05033         for (S32 i = 0; i < anim_ids.count(); i++)
05034         {
05035                 if (anim_ids[i].isNull())
05036                 {
05037                         continue;
05038                 }
05039                 msg->nextBlockFast(_PREHASH_AnimationList);
05040                 msg->addUUIDFast(_PREHASH_AnimID, (anim_ids[i]) );
05041                 msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
05042                 num_valid_anims++;
05043         }
05044 
05045         msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
05046         msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
05047         if (num_valid_anims)
05048         {
05049                 sendReliableMessage();
05050         }
05051 }
05052 
05053 void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
05054 {
05055         if (gAgentID.isNull() || anim_id.isNull() || !mRegionp)
05056         {
05057                 return;
05058         }
05059 
05060         LLMessageSystem* msg = gMessageSystem;
05061         msg->newMessageFast(_PREHASH_AgentAnimation);
05062         msg->nextBlockFast(_PREHASH_AgentData);
05063         msg->addUUIDFast(_PREHASH_AgentID, getID());
05064         msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05065 
05066         msg->nextBlockFast(_PREHASH_AnimationList);
05067         msg->addUUIDFast(_PREHASH_AnimID, (anim_id) );
05068         msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
05069 
05070         msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
05071         msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
05072         sendReliableMessage();
05073 }
05074 
05075 void LLAgent::friendsChanged()
05076 {
05077         LLCollectProxyBuddies collector;
05078         LLAvatarTracker::instance().applyFunctor(collector);
05079         mProxyForAgents = collector.mProxy;
05080 }
05081 
05082 BOOL LLAgent::isGrantedProxy(const LLPermissions& perm)
05083 {
05084         return (mProxyForAgents.count(perm.getOwner()) > 0);
05085 }
05086 
05087 BOOL LLAgent::allowOperation(PermissionBit op,
05088                                                          const LLPermissions& perm,
05089                                                          U64 group_proxy_power,
05090                                                          U8 god_minimum)
05091 {
05092         
05093         if (getGodLevel() >= god_minimum) return TRUE;
05094 
05095         if (!perm.isOwned()) return FALSE;
05096 
05097         
05098         BOOL is_group_owned;
05099         LLUUID owner_id;
05100         perm.getOwnership(owner_id, is_group_owned);
05101         LLUUID group_id(perm.getGroup());
05102         LLUUID agent_proxy(getID());
05103 
05104         if (is_group_owned)
05105         {
05106                 if (hasPowerInGroup(group_id, group_proxy_power))
05107                 {
05108                         
05109                         agent_proxy = owner_id;
05110                 }
05111         }
05112         else
05113         {
05114                 
05115                 if ((PERM_OWNER != op) && isGrantedProxy(perm))
05116                 {
05117                         agent_proxy = owner_id;
05118                 }
05119         }
05120 
05121         
05122         
05123         LLUUID group_proxy = LLUUID::null;
05124         if (group_id.notNull() && isInGroup(group_id))
05125         {
05126                 group_proxy = group_id;
05127         }
05128 
05129         
05130         if (PERM_OWNER == op)
05131         {
05132                 
05133                 return (agent_proxy == owner_id);
05134         }
05135 
05136         return perm.allowOperationBy(op, agent_proxy, group_proxy);
05137 }
05138 
05139 
05140 void LLAgent::getName(LLString& name)
05141 {
05142         
05143         name.clear();
05144 
05145         if (mAvatarObject)
05146         {
05147                 LLNameValue *first_nv = mAvatarObject->getNVPair("FirstName");
05148                 LLNameValue *last_nv = mAvatarObject->getNVPair("LastName");
05149                 if (first_nv && last_nv)
05150                 {
05151                         name = first_nv->printData() + " " + last_nv->printData();
05152                 }
05153                 else
05154                 {
05155                         llwarns << "Agent is missing FirstName and/or LastName nv pair." << llendl;
05156                 }
05157         }
05158         else
05159         {
05160                 name = gSavedSettings.getString("FirstName") + " " + gSavedSettings.getString("LastName");
05161         }
05162 }
05163 
05164 const LLColor4 &LLAgent::getEffectColor()
05165 {
05166         return mEffectColor;
05167 }
05168 
05169 void LLAgent::setEffectColor(const LLColor4 &color)
05170 {
05171         mEffectColor = color;
05172 }
05173 
05174 void LLAgent::initOriginGlobal(const LLVector3d &origin_global)
05175 {
05176         mAgentOriginGlobal = origin_global;
05177 }
05178 
05179 void update_group_floaters(const LLUUID& group_id)
05180 {
05181         LLFloaterGroupInfo::refreshGroup(group_id);
05182 
05183         
05184         LLFloaterAvatarInfo* fa = LLFloaterAvatarInfo::getInstance(gAgent.getID());
05185         if(fa)
05186         {
05187                 fa->resetGroupList();
05188         }
05189 
05190         if (gIMMgr)
05191         {
05192                 
05193                 gIMMgr->refresh();
05194         }
05195 
05196         gAgent.fireEvent(new LLEvent(&gAgent, "new group"), "");
05197 }
05198 
05199 
05200 void LLAgent::processAgentDropGroup(LLMessageSystem *msg, void **)
05201 {
05202         LLUUID  agent_id;
05203         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
05204 
05205         if (agent_id != gAgentID)
05206         {
05207                 llwarns << "processAgentDropGroup for agent other than me" << llendl;
05208                 return;
05209         }
05210 
05211         LLUUID  group_id;
05212         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_GroupID, group_id );
05213 
05214         
05215         LLGroupData gd;
05216         gd.mID = group_id;
05217         S32 index = gAgent.mGroups.find(gd);
05218         if (index != -1)
05219         {
05220                 gAgent.mGroups.remove(index);
05221                 if (gAgent.getGroupID() == group_id)
05222                 {
05223                         gAgent.mGroupID.setNull();
05224                         gAgent.mGroupPowers = 0;
05225                         gAgent.mGroupName[0] = '\0';
05226                         gAgent.mGroupTitle[0] = '\0';
05227                 }
05228                 
05229                 
05230                 gAgent.sendAgentDataUpdateRequest();
05231 
05232                 gGroupMgr->clearGroupData(group_id);
05233                 
05234                 LLFloaterGroupInfo::closeGroup(group_id);
05235                 
05236                 LLFloaterDirectory::refreshGroup(group_id);
05237         }
05238         else
05239         {
05240                 llwarns << "processAgentDropGroup, agent is not part of group " << group_id << llendl;
05241         }
05242 }
05243 
05244 
05245 void LLAgent::processAgentGroupDataUpdate(LLMessageSystem *msg, void **)
05246 {
05247         LLUUID  agent_id;
05248 
05249         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
05250 
05251         if (agent_id != gAgentID)
05252         {
05253                 llwarns << "processAgentGroupDataUpdate for agent other than me" << llendl;
05254                 return;
05255         }       
05256         
05257         S32 count = msg->getNumberOfBlocksFast(_PREHASH_GroupData);
05258         LLGroupData group;
05259         S32 index = -1;
05260         bool need_floater_update = false;
05261         char group_name[DB_GROUP_NAME_BUF_SIZE];                
05262         for(S32 i = 0; i < count; ++i)
05263         {
05264                 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupID, group.mID, i);
05265                 msg->getUUIDFast(_PREHASH_GroupData, _PREHASH_GroupInsigniaID, group.mInsigniaID, i);
05266                 msg->getU64(_PREHASH_GroupData, "GroupPowers", group.mPowers, i);
05267                 msg->getBOOL(_PREHASH_GroupData, "AcceptNotices", group.mAcceptNotices, i);
05268                 msg->getS32(_PREHASH_GroupData, "Contribution", group.mContribution, i);
05269                 msg->getStringFast(_PREHASH_GroupData, _PREHASH_GroupName, DB_GROUP_NAME_BUF_SIZE, group_name, i);
05270                 group.mName.assign(group_name);
05271                 
05272                 if(group.mID.notNull())
05273                 {
05274                         need_floater_update = true;
05275                         
05276                         index = gAgent.mGroups.find(group);
05277                         if (index != -1)
05278                         {
05279                                 gAgent.mGroups.remove(index);
05280                         }
05281                         gAgent.mGroups.put(group);
05282                 }
05283                 if (need_floater_update)
05284                 {
05285                         update_group_floaters(group.mID);
05286                 }
05287         }
05288 
05289 }
05290 
05291 class LLAgentGroupDataUpdateViewerNode : public LLHTTPNode
05292 {
05293         virtual void post(
05294                 LLHTTPNode::ResponsePtr response,
05295                 const LLSD& context,
05296                 const LLSD& input) const
05297         {
05298                 LLSD body = input["body"];
05299                 if(body.has("body"))
05300                         body = body["body"];
05301                 LLUUID agent_id = body["AgentData"][0]["AgentID"].asUUID();
05302 
05303                 if (agent_id != gAgentID)
05304                 {
05305                         llwarns << "processAgentGroupDataUpdate for agent other than me" << llendl;
05306                         return;
05307                 }       
05308 
05309                 LLSD group_data = body["GroupData"];
05310 
05311                 LLSD::array_iterator iter_group =
05312                         group_data.beginArray();
05313                 LLSD::array_iterator end_group =
05314                         group_data.endArray();
05315                 int group_index = 0;
05316                 for(; iter_group != end_group; ++iter_group)
05317                 {
05318 
05319                         LLGroupData group;
05320                         S32 index = -1;
05321                         bool need_floater_update = false;
05322 
05323                         group.mID = (*iter_group)["GroupID"].asUUID();
05324                         group.mPowers = ll_U64_from_sd((*iter_group)["GroupPowers"]);
05325                         group.mAcceptNotices = (*iter_group)["AcceptNotices"].asBoolean();
05326                         group.mListInProfile = body["NewGroupData"][group_index]["ListInProfile"].asBoolean();
05327                         group.mInsigniaID = (*iter_group)["GroupInsigniaID"].asUUID();
05328                         group.mName = (*iter_group)["GroupName"].asString();
05329                         group.mContribution = (*iter_group)["Contribution"].asInteger();
05330 
05331                         group_index++;
05332 
05333                         if(group.mID.notNull())
05334                         {
05335                                 need_floater_update = true;
05336                                 
05337                                 index = gAgent.mGroups.find(group);
05338                                 if (index != -1)
05339                                 {
05340                                         gAgent.mGroups.remove(index);
05341                                 }
05342                                 gAgent.mGroups.put(group);
05343                         }
05344                         if (need_floater_update)
05345                         {
05346                                 update_group_floaters(group.mID);
05347                         }
05348                 }
05349         }
05350 };
05351 
05352 LLHTTPRegistration<LLAgentGroupDataUpdateViewerNode >
05353         gHTTPRegistrationAgentGroupDataUpdateViewerNode ("/message/AgentGroupDataUpdate"); 
05354 
05355 
05356 void LLAgent::processAgentDataUpdate(LLMessageSystem *msg, void **)
05357 {
05358         LLUUID  agent_id;
05359 
05360         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
05361 
05362         if (agent_id != gAgentID)
05363         {
05364                 llwarns << "processAgentDataUpdate for agent other than me" << llendl;
05365                 return;
05366         }
05367 
05368         msg->getStringFast(_PREHASH_AgentData, _PREHASH_GroupTitle, DB_GROUP_TITLE_BUF_SIZE, gAgent.mGroupTitle);
05369         LLUUID active_id;
05370         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_ActiveGroupID, active_id);
05371 
05372 
05373         if(active_id.notNull())
05374         {
05375                 gAgent.mGroupID = active_id;
05376                 msg->getU64(_PREHASH_AgentData, "GroupPowers", gAgent.mGroupPowers);
05377                 msg->getString(_PREHASH_AgentData, _PREHASH_GroupName, DB_GROUP_NAME_BUF_SIZE, gAgent.mGroupName);
05378         }
05379         else
05380         {
05381                 gAgent.mGroupID.setNull();
05382                 gAgent.mGroupPowers = 0;
05383                 gAgent.mGroupName[0] = '\0';
05384         }               
05385 
05386         update_group_floaters(active_id);
05387 }
05388 
05389 
05390 void LLAgent::processScriptControlChange(LLMessageSystem *msg, void **)
05391 {
05392         S32 block_count = msg->getNumberOfBlocks("Data");
05393         for (S32 block_index = 0; block_index < block_count; block_index++)
05394         {
05395                 BOOL take_controls;
05396                 U32     controls;
05397                 BOOL passon;
05398                 U32 i;
05399                 msg->getBOOL("Data", "TakeControls", take_controls, block_index);
05400                 if (take_controls)
05401                 {
05402                         
05403                         msg->getU32("Data", "Controls", controls, block_index );
05404                         msg->getBOOL("Data", "PassToAgent", passon, block_index );
05405                         U32 total_count = 0;
05406                         for (i = 0; i < TOTAL_CONTROLS; i++)
05407                         {
05408                                 if (controls & ( 1 << i))
05409                                 {
05410                                         if (passon)
05411                                         {
05412                                                 gAgent.mControlsTakenPassedOnCount[i]++;
05413                                         }
05414                                         else
05415                                         {
05416                                                 gAgent.mControlsTakenCount[i]++;
05417                                         }
05418                                         total_count++;
05419                                 }
05420                         }
05421                 
05422                         
05423                         if (total_count > 0)
05424                         {
05425                                 LLFirstUse::useOverrideKeys();
05426                         }
05427                 }
05428                 else
05429                 {
05430                         
05431                         msg->getU32("Data", "Controls", controls, block_index );
05432                         msg->getBOOL("Data", "PassToAgent", passon, block_index );
05433                         for (i = 0; i < TOTAL_CONTROLS; i++)
05434                         {
05435                                 if (controls & ( 1 << i))
05436                                 {
05437                                         if (passon)
05438                                         {
05439                                                 gAgent.mControlsTakenPassedOnCount[i]--;
05440                                                 if (gAgent.mControlsTakenPassedOnCount[i] < 0)
05441                                                 {
05442                                                         gAgent.mControlsTakenPassedOnCount[i] = 0;
05443                                                 }
05444                                         }
05445                                         else
05446                                         {
05447                                                 gAgent.mControlsTakenCount[i]--;
05448                                                 if (gAgent.mControlsTakenCount[i] < 0)
05449                                                 {
05450                                                         gAgent.mControlsTakenCount[i] = 0;
05451                                                 }
05452                                         }
05453                                 }
05454                         }
05455                 }
05456         }
05457 }
05458 
05459 
05460 
05461 
05462 
05463 
05464 
05465 
05466 
05467 
05468 
05469 
05470 
05471 
05472 
05473 
05474 
05475 
05476 
05477 
05478 
05479 
05480 
05481 
05482 
05483 
05484 
05485 
05486 
05487 
05488 
05489 
05490 
05491 
05492 
05493 
05494 
05495 
05496 
05497 
05498 
05499 
05500 
05501 
05502 
05503 
05504 
05505 
05506 
05507 
05508 
05509 
05510 
05511 
05512 
05513 
05514 
05515 
05516 
05517 
05518 
05519 
05520 
05521 
05522 
05523 
05524 
05525 
05526 
05527 
05528 void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void **user_data)
05529 {
05530         gAgent.mNumPendingQueries--;
05531 
05532         LLVOAvatar* avatarp = gAgent.getAvatarObject();
05533         if (!avatarp || avatarp->isDead())
05534         {
05535                 llwarns << "No avatar for user in cached texture update!" << llendl;
05536                 return;
05537         }
05538 
05539         if (gAgent.cameraCustomizeAvatar())
05540         {
05541                 
05542                 return;
05543         }
05544 
05545         S32 query_id;
05546         mesgsys->getS32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, query_id);
05547 
05548         S32 num_texture_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_WearableData);
05549 
05550 
05551         S32 num_results = 0;
05552         for (S32 texture_block = 0; texture_block < num_texture_blocks; texture_block++)
05553         {
05554                 LLUUID texture_id;
05555                 U8 texture_index;
05556 
05557                 mesgsys->getUUIDFast(_PREHASH_WearableData, _PREHASH_TextureID, texture_id, texture_block);
05558                 mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);
05559 
05560                 if (texture_id.notNull() 
05561                         && (S32)texture_index < BAKED_TEXTURE_COUNT 
05562                         && gAgent.mActiveCacheQueries[ texture_index ] == query_id)
05563                 {
05564                         
05565                         avatarp->setCachedBakedTexture((LLVOAvatar::ETextureIndex)LLVOAvatar::sBakedTextureIndices[texture_index], texture_id);
05566                         
05567                         gAgent.mActiveCacheQueries[ texture_index ] = 0;
05568                         num_results++;
05569                 }
05570         }
05571 
05572         llinfos << "Received cached texture response for " << num_results << " textures." << llendl;
05573 
05574         avatarp->updateMeshTextures();
05575 
05576         if (gAgent.mNumPendingQueries == 0)
05577         {
05578                 
05579                 avatarp->setCompositeUpdatesEnabled(TRUE);
05580                 gAgent.sendAgentSetAppearance();
05581         }
05582 }
05583 
05584 BOOL LLAgent::anyControlGrabbed() const
05585 {
05586         U32 i;
05587         for (i = 0; i < TOTAL_CONTROLS; i++)
05588         {
05589                 if (gAgent.mControlsTakenCount[i] > 0)
05590                         return TRUE;
05591                 if (gAgent.mControlsTakenPassedOnCount[i] > 0)
05592                         return TRUE;
05593         }
05594         return FALSE;
05595 }
05596 
05597 BOOL LLAgent::isControlGrabbed(S32 control_index) const
05598 {
05599         return mControlsTakenCount[control_index] > 0;
05600 }
05601 
05602 void LLAgent::forceReleaseControls()
05603 {
05604         gMessageSystem->newMessage("ForceScriptControlRelease");
05605         gMessageSystem->nextBlock("AgentData");
05606         gMessageSystem->addUUID("AgentID", getID());
05607         gMessageSystem->addUUID("SessionID", getSessionID());
05608         sendReliableMessage();
05609 }
05610 
05611 void LLAgent::setHomePosRegion( const U64& region_handle, const LLVector3& pos_region)
05612 {
05613         mHaveHomePosition = TRUE;
05614         mHomeRegionHandle = region_handle;
05615         mHomePosRegion = pos_region;
05616 }
05617 
05618 BOOL LLAgent::getHomePosGlobal( LLVector3d* pos_global )
05619 {
05620         if(!mHaveHomePosition)
05621         {
05622                 return FALSE;
05623         }
05624         F32 x = 0;
05625         F32 y = 0;
05626         from_region_handle( mHomeRegionHandle, &x, &y);
05627         pos_global->setVec( x + mHomePosRegion.mV[VX], y + mHomePosRegion.mV[VY], mHomePosRegion.mV[VZ] );
05628         return TRUE;
05629 }
05630 
05631 void LLAgent::clearVisualParams(void *data)
05632 {
05633         LLVOAvatar* avatarp = gAgent.getAvatarObject();
05634         if (avatarp)
05635         {
05636                 avatarp->clearVisualParamWeights();
05637                 avatarp->updateVisualParams();
05638         }
05639 }
05640 
05641 
05642 
05643 
05644 
05645 
05646 
05647 bool LLAgent::teleportCore(bool is_local)
05648 {
05649         if(TELEPORT_NONE != mTeleportState)
05650         {
05651                 llwarns << "Attempt to teleport when already teleporting." << llendl;
05652                 return false;
05653         }
05654 
05655         
05656         
05657         
05658 
05659         
05660         LLFloaterWorldMap::hide(NULL);
05661         LLFloaterDirectory::hide(NULL);
05662 
05663         gParcelMgr->deselectLand();
05664 
05665         
05666         
05667         resetView(FALSE);
05668 
05669         
05670         gViewerStats->incStat(LLViewerStats::ST_TELEPORT_COUNT);
05671         if (!is_local)
05672         {
05673                 gTeleportDisplay = TRUE;
05674                 gAgent.setTeleportState( LLAgent::TELEPORT_START );
05675         }
05676         make_ui_sound("UISndTeleportOut");
05677         
05678         
05679         
05680 
05681         
05682         return true;
05683 }
05684 
05685 void LLAgent::teleportRequest(
05686         const U64& region_handle,
05687         const LLVector3& pos_local)
05688 {
05689         LLViewerRegion* regionp = getRegion();
05690         if(regionp && teleportCore())
05691         {
05692                 llinfos << "TeleportRequest: '" << region_handle << "':" << pos_local
05693                                 << llendl;
05694                 LLMessageSystem* msg = gMessageSystem;
05695                 msg->newMessage("TeleportLocationRequest");
05696                 msg->nextBlockFast(_PREHASH_AgentData);
05697                 msg->addUUIDFast(_PREHASH_AgentID, getID());
05698                 msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05699                 msg->nextBlockFast(_PREHASH_Info);
05700                 msg->addU64("RegionHandle", region_handle);
05701                 msg->addVector3("Position", pos_local);
05702                 LLVector3 look_at(0,1,0);
05703                 msg->addVector3("LookAt", look_at);
05704                 sendReliableMessage();
05705         }
05706 }
05707 
05708 
05709 void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
05710 {
05711         LLViewerRegion *regionp = getRegion();
05712         if(regionp && teleportCore())
05713         {
05714                 LLMessageSystem* msg = gMessageSystem;
05715                 msg->newMessageFast(_PREHASH_TeleportLandmarkRequest);
05716                 msg->nextBlockFast(_PREHASH_Info);
05717                 msg->addUUIDFast(_PREHASH_AgentID, getID());
05718                 msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05719                 msg->addUUIDFast(_PREHASH_LandmarkID, landmark_asset_id);
05720                 sendReliableMessage();
05721         }
05722 }
05723 
05724 void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike)
05725 {
05726         LLViewerRegion* regionp = getRegion();
05727         if(regionp && teleportCore())
05728         {
05729                 U32 teleport_flags = 0x0;
05730                 if (godlike)
05731                 {
05732                         teleport_flags |= TELEPORT_FLAGS_VIA_GODLIKE_LURE;
05733                         teleport_flags |= TELEPORT_FLAGS_DISABLE_CANCEL;
05734                 }
05735                 else
05736                 {
05737                         teleport_flags |= TELEPORT_FLAGS_VIA_LURE;
05738                 }
05739 
05740                 
05741                 LLMessageSystem* msg = gMessageSystem;
05742                 msg->newMessageFast(_PREHASH_TeleportLureRequest);
05743                 msg->nextBlockFast(_PREHASH_Info);
05744                 msg->addUUIDFast(_PREHASH_AgentID, getID());
05745                 msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05746                 msg->addUUIDFast(_PREHASH_LureID, lure_id);
05747                 msg->addU32("TeleportFlags", teleport_flags);
05748                 sendReliableMessage();
05749         }       
05750 }
05751 
05752 
05753 
05754 void LLAgent::teleportCancel()
05755 {
05756         LLViewerRegion* regionp = getRegion();
05757         if(regionp)
05758         {
05759                 
05760                 LLMessageSystem* msg = gMessageSystem;
05761                 msg->newMessage("TeleportCancel");
05762                 msg->nextBlockFast(_PREHASH_Info);
05763                 msg->addUUIDFast(_PREHASH_AgentID, getID());
05764                 msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05765                 sendReliableMessage();
05766         }       
05767         gTeleportDisplay = FALSE;
05768         gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
05769 }
05770 
05771 
05772 void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
05773 {
05774         LLViewerRegion* regionp = getRegion();
05775         LLSimInfo* info = gWorldMap->simInfoFromPosGlobal(pos_global);
05776         if(regionp && info)
05777         {
05778                 U32 x_pos;
05779                 U32 y_pos;
05780                 from_region_handle(info->mHandle, &x_pos, &y_pos);
05781                 LLVector3 pos_local(
05782                         (F32)(pos_global.mdV[VX] - x_pos),
05783                         (F32)(pos_global.mdV[VY] - y_pos),
05784                         (F32)(pos_global.mdV[VZ]));
05785                 teleportRequest(info->mHandle, pos_local);
05786         }
05787         else if(regionp && 
05788                 teleportCore(regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY])))
05789         {
05790                 llwarns << "Using deprecated teleportlocationrequest." << llendl; 
05791                 
05792                 LLMessageSystem* msg = gMessageSystem;
05793                 msg->newMessageFast(_PREHASH_TeleportLocationRequest);
05794                 msg->nextBlockFast(_PREHASH_AgentData);
05795                 msg->addUUIDFast(_PREHASH_AgentID, getID());
05796                 msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05797 
05798                 msg->nextBlockFast(_PREHASH_Info);
05799                 F32 width = regionp->getWidth();
05800                 LLVector3 pos(fmod((F32)pos_global.mdV[VX], width),
05801                                           fmod((F32)pos_global.mdV[VY], width),
05802                                           (F32)pos_global.mdV[VZ]);
05803                 F32 region_x = (F32)(pos_global.mdV[VX]);
05804                 F32 region_y = (F32)(pos_global.mdV[VY]);
05805                 U64 region_handle = to_region_handle_global(region_x, region_y);
05806                 msg->addU64Fast(_PREHASH_RegionHandle, region_handle);
05807                 msg->addVector3Fast(_PREHASH_Position, pos);
05808                 pos.mV[VX] += 1;
05809                 msg->addVector3Fast(_PREHASH_LookAt, pos);
05810                 sendReliableMessage();
05811         }
05812 }
05813 
05814 void LLAgent::setTeleportState(ETeleportState state)
05815 {
05816         mTeleportState = state;
05817         if (mTeleportState > TELEPORT_NONE && gSavedSettings.getBOOL("FreezeTime"))
05818         {
05819                 LLFloaterSnapshot::hide(0);
05820         }
05821 }
05822 
05823 void LLAgent::sendChat(const LLString &text, S32 channel, EChatType type, bool animate)
05824 {
05825 
05826         
05827         if (animate && (channel == 0))
05828         {
05829                 if (type == CHAT_TYPE_WHISPER)
05830                 {
05831                         lldebugs << "You whisper " << text << llendl;
05832                         sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
05833                 }
05834                 else if (type == CHAT_TYPE_NORMAL)
05835                 {
05836                         lldebugs << "You say " << text << llendl;
05837                         sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
05838                 }
05839                 else if (type == CHAT_TYPE_SHOUT)
05840                 {
05841                         lldebugs << "You shout " << text << llendl;
05842                         sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
05843                 }
05844                 else
05845                 {
05846                         llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
05847                         return;
05848                 }
05849         }
05850         else
05851         {
05852                 if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
05853                 {
05854                         lldebugs << "Channel chat: " << text << llendl;
05855                 }
05856         }
05857 
05858         LLMessageSystem* msg = gMessageSystem;
05859 
05860         msg->newMessageFast(_PREHASH_ChatFromViewer);
05861         msg->nextBlockFast(_PREHASH_AgentData);
05862         msg->addUUIDFast(_PREHASH_AgentID, getID());
05863         msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
05864         msg->nextBlockFast(_PREHASH_ChatData);
05865         msg->addStringFast(_PREHASH_Message, text);
05866         msg->addU8Fast(_PREHASH_Type, type);
05867         msg->addS32("Channel", channel);
05868 
05869         gAgent.sendReliableMessage();
05870 
05871         gViewerStats->incStat(LLViewerStats::ST_CHAT_COUNT);
05872 }
05873 
05874 void LLAgent::fidget()
05875 {
05876         if (!getAFK())
05877         {
05878                 F32 curTime = mFidgetTimer.getElapsedTimeF32();
05879                 if (curTime > mNextFidgetTime)
05880                 {
05881                         
05882                         S32 oldFidget = mCurrentFidget;
05883 
05884                         mCurrentFidget = ll_rand(NUM_AGENT_STAND_ANIMS);
05885 
05886                         if (mCurrentFidget != oldFidget)
05887                         {
05888                                 LLAgent::stopFidget();
05889 
05890                                 
05891                                 switch(mCurrentFidget)
05892                                 {
05893                                 case 0:
05894                                         mCurrentFidget = 0;
05895                                         break;
05896                                 case 1:
05897                                         sendAnimationRequest(ANIM_AGENT_STAND_1, ANIM_REQUEST_START);
05898                                         mCurrentFidget = 1;
05899                                         break;
05900                                 case 2:
05901                                         sendAnimationRequest(ANIM_AGENT_STAND_2, ANIM_REQUEST_START);
05902                                         mCurrentFidget = 2;
05903                                         break;
05904                                 case 3:
05905                                         sendAnimationRequest(ANIM_AGENT_STAND_3, ANIM_REQUEST_START);
05906                                         mCurrentFidget = 3;
05907                                         break;
05908                                 case 4:
05909                                         sendAnimationRequest(ANIM_AGENT_STAND_4, ANIM_REQUEST_START);
05910                                         mCurrentFidget = 4;
05911                                         break;
05912                                 }
05913                         }
05914 
05915                         
05916                         mNextFidgetTime = curTime + ll_frand(MAX_FIDGET_TIME - MIN_FIDGET_TIME) + MIN_FIDGET_TIME;
05917                 }
05918         }
05919 }
05920 
05921 void LLAgent::stopFidget()
05922 {
05923         LLDynamicArray<LLUUID> anims;
05924         anims.put(ANIM_AGENT_STAND_1);
05925         anims.put(ANIM_AGENT_STAND_2);
05926         anims.put(ANIM_AGENT_STAND_3);
05927         anims.put(ANIM_AGENT_STAND_4);
05928 
05929         gAgent.sendAnimationRequests(anims, ANIM_REQUEST_STOP);
05930 }
05931 
05932 
05933 void LLAgent::requestEnterGodMode()
05934 {
05935         LLMessageSystem* msg = gMessageSystem;
05936         msg->newMessageFast(_PREHASH_RequestGodlikePowers);
05937         msg->nextBlockFast(_PREHASH_AgentData);
05938         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
05939         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
05940         msg->nextBlockFast(_PREHASH_RequestBlock);
05941         msg->addBOOLFast(_PREHASH_Godlike, TRUE);
05942         msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
05943 
05944         
05945         sendReliableMessage();
05946 }
05947 
05948 void LLAgent::requestLeaveGodMode()
05949 {
05950         LLMessageSystem* msg = gMessageSystem;
05951         msg->newMessageFast(_PREHASH_RequestGodlikePowers);
05952         msg->nextBlockFast(_PREHASH_AgentData);
05953         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
05954         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
05955         msg->nextBlockFast(_PREHASH_RequestBlock);
05956         msg->addBOOLFast(_PREHASH_Godlike, FALSE);
05957         msg->addUUIDFast(_PREHASH_Token, LLUUID::null);
05958 
05959         
05960         sendReliableMessage();
05961 }
05962 
05963 
05964 LLAgent::createStandardWearablesAllDoneCallback::~createStandardWearablesAllDoneCallback()
05965 {
05966         gAgent.createStandardWearablesAllDone();
05967 }
05968 
05969 LLAgent::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCallback()
05970 {
05971         gAgent.sendAgentWearablesUpdate();
05972 }
05973 
05974 LLAgent::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
05975         LLPointer<LLRefCount> cb, S32 index, LLWearable* wearable, U32 todo) :
05976         mIndex(index),
05977         mWearable(wearable),
05978         mTodo(todo),
05979         mCB(cb)
05980 {
05981 }
05982 
05983 void LLAgent::addWearableToAgentInventoryCallback::fire(const LLUUID& inv_item)
05984 {
05985         if (inv_item.isNull())
05986                 return;
05987 
05988         gAgent.addWearabletoAgentInventoryDone(mIndex, inv_item, mWearable);
05989 
05990         if (mTodo & CALL_UPDATE)
05991         {
05992                 gAgent.sendAgentWearablesUpdate();
05993         }
05994         if (mTodo & CALL_RECOVERDONE)
05995         {
05996                 gAgent.recoverMissingWearableDone();
05997         }
05998         
05999 
06000 
06001         if (mTodo & CALL_CREATESTANDARDDONE)
06002         {
06003                 gAgent.createStandardWearablesDone(mIndex);
06004         }
06005         if (mTodo & CALL_MAKENEWOUTFITDONE)
06006         {
06007                 gAgent.makeNewOutfitDone(mIndex);
06008         }
06009 }
06010 
06011 void LLAgent::addWearabletoAgentInventoryDone(
06012         S32 index,
06013         const LLUUID& item_id,
06014         LLWearable* wearable)
06015 {
06016         if (item_id.isNull())
06017                 return;
06018 
06019         LLUUID old_item_id = mWearableEntry[index].mItemID;
06020         mWearableEntry[index].mItemID = item_id;
06021         mWearableEntry[index].mWearable = wearable;
06022         if (old_item_id.notNull())
06023                 gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
06024         gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
06025         LLViewerInventoryItem* item = gInventory.getItem(item_id);
06026         if(item && wearable)
06027         {
06028                 
06029                 
06030                 
06031                 item->setAssetUUID(wearable->getID());
06032                 item->setTransactionID(wearable->getTransactionID());
06033                 gInventory.addChangedMask(LLInventoryObserver::INTERNAL, item_id);
06034                 item->updateServer(FALSE);
06035         }
06036         gInventory.notifyObservers();
06037 }
06038 
06039 void LLAgent::sendAgentWearablesUpdate()
06040 {
06041         
06042         S32 i;
06043         for(i=0; i < WT_COUNT; ++i)
06044         {
06045                 LLWearable* wearable = mWearableEntry[ i ].mWearable;
06046                 if (wearable)
06047                 {
06048                         if( mWearableEntry[ i ].mItemID.isNull() )
06049                         {
06050                                 LLPointer<LLInventoryCallback> cb =
06051                                         new addWearableToAgentInventoryCallback(
06052                                                 LLPointer<LLRefCount>(NULL),
06053                                                 i,
06054                                                 wearable,
06055                                                 addWearableToAgentInventoryCallback::CALL_NONE);
06056                                 addWearableToAgentInventory(cb, wearable);
06057                         }
06058                         else
06059                         {
06060                                 gInventory.addChangedMask( LLInventoryObserver::LABEL,
06061                                                 mWearableEntry[i].mItemID );
06062                         }
06063                 }
06064         }
06065 
06066         
06067         gInventory.notifyObservers();
06068 
06069         
06070         gMessageSystem->newMessageFast(_PREHASH_AgentIsNowWearing);
06071 
06072         gMessageSystem->nextBlockFast(_PREHASH_AgentData);
06073         gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
06074         gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
06075 
06076         lldebugs << "sendAgentWearablesUpdate()" << llendl;
06077         for(i=0; i < WT_COUNT; ++i)
06078         {
06079                 gMessageSystem->nextBlockFast(_PREHASH_WearableData);
06080 
06081                 U8 type_u8 = (U8)i;
06082                 gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8 );
06083 
06084                 LLWearable* wearable = mWearableEntry[ i ].mWearable;
06085                 if( wearable )
06086                 {
06087                         
06088                         gMessageSystem->addUUIDFast(_PREHASH_ItemID, mWearableEntry[ i ].mItemID );
06089                 }
06090                 else
06091                 {
06092                         
06093                         gMessageSystem->addUUIDFast(_PREHASH_ItemID, LLUUID::null );
06094                 }
06095 
06096                 lldebugs << "       " << LLWearable::typeToTypeLabel((EWearableType)i) << ": " << (wearable ? wearable->getID() : LLUUID::null) << llendl;
06097         }
06098         gAgent.sendReliableMessage();
06099 }
06100 
06101 void LLAgent::saveWearable( EWearableType type, BOOL send_update )
06102 {
06103         LLWearable* old_wearable = mWearableEntry[(S32)type].mWearable;
06104         if( old_wearable && (old_wearable->isDirty() || old_wearable->isOldVersion()) )
06105         {
06106                 LLWearable* new_wearable = gWearableList.createCopyFromAvatar( old_wearable );
06107                 mWearableEntry[(S32)type].mWearable = new_wearable;
06108 
06109                 LLInventoryItem* item = gInventory.getItem(mWearableEntry[(S32)type].mItemID);
06110                 if( item )
06111                 {
06112                         
06113                         LLPointer<LLViewerInventoryItem> template_item =
06114                                 new LLViewerInventoryItem(item->getUUID(),
06115                                                                                   item->getParentUUID(),
06116                                                                                   item->getPermissions(),
06117                                                                                   new_wearable->getID(),
06118                                                                                   new_wearable->getAssetType(),
06119                                                                                   item->getInventoryType(),
06120                                                                                   item->getName(),
06121                                                                                   item->getDescription(),
06122                                                                                   item->getSaleInfo(),
06123                                                                                   item->getFlags(),
06124                                                                                   item->getCreationDate());
06125                         template_item->setTransactionID(new_wearable->getTransactionID());
06126                         template_item->updateServer(FALSE);
06127                         gInventory.updateItem(template_item);
06128                 }
06129                 else
06130                 {
06131                         
06132                         U32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
06133                         if (send_update)
06134                         {
06135                                 todo |= addWearableToAgentInventoryCallback::CALL_UPDATE;
06136                         }
06137                         LLPointer<LLInventoryCallback> cb =
06138                                 new addWearableToAgentInventoryCallback(
06139                                         LLPointer<LLRefCount>(NULL),
06140                                         (S32)type,
06141                                         new_wearable,
06142                                         todo);
06143                         addWearableToAgentInventory(cb, new_wearable);
06144                         return;
06145                 }
06146 
06147                 if( send_update )
06148                 {
06149                         sendAgentWearablesUpdate();
06150                 }
06151         }
06152 }
06153 
06154 void LLAgent::saveWearableAs(
06155         EWearableType type,
06156         const std::string& new_name,
06157         BOOL save_in_lost_and_found)
06158 {
06159         if(!isWearableCopyable(type))
06160         {
06161                 llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
06162                 return;
06163         }
06164         LLWearable* old_wearable = getWearable(type);
06165         if(!old_wearable)
06166         {
06167                 llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
06168                 return;
06169         }
06170         LLInventoryItem* item = gInventory.getItem(mWearableEntry[type].mItemID);
06171         if(!item)
06172         {
06173                 llwarns << "LLAgent::saveWearableAs() no inventory item." << llendl;
06174                 return;
06175         }
06176         std::string trunc_name(new_name);
06177         LLString::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
06178         LLWearable* new_wearable = gWearableList.createCopyFromAvatar(
06179                 old_wearable,
06180                 trunc_name);
06181         LLPointer<LLInventoryCallback> cb =
06182                 new addWearableToAgentInventoryCallback(
06183                         LLPointer<LLRefCount>(NULL),
06184                         type,
06185                         new_wearable,
06186                         addWearableToAgentInventoryCallback::CALL_UPDATE);
06187         LLUUID category_id;
06188         if (save_in_lost_and_found)
06189         {
06190                 category_id = gInventory.findCategoryUUIDForType(
06191                         LLAssetType::AT_LOST_AND_FOUND);
06192         }
06193         else
06194         {
06195                 
06196                 category_id = item->getParentUUID();
06197         }
06198 
06199         copy_inventory_item(
06200                 gAgent.getID(),
06201                 item->getPermissions().getOwner(),
06202                 item->getUUID(),
06203                 category_id,
06204                 new_name,
06205                 cb);
06206 
06207 
06208 
06209 
06210 
06211 
06212 
06213 
06214 
06215 
06216 
06217 
06218 
06219 
06220 
06221 
06222 
06223 
06224 
06225 
06226 
06227 
06228 
06229 
06230 
06231 
06232 
06233 
06234 
06235 
06236 
06237 
06238 
06239 
06240 
06241 
06242 
06243 
06244 
06245 
06246 }
06247 
06248 void LLAgent::revertWearable( EWearableType type )
06249 {
06250         LLWearable* wearable = mWearableEntry[(S32)type].mWearable;
06251         if( wearable )
06252         {
06253                 wearable->writeToAvatar( TRUE );
06254         }
06255         sendAgentSetAppearance();
06256 }
06257 
06258 void LLAgent::revertAllWearables()
06259 {
06260         for( S32 i=0; i < WT_COUNT; i++ )
06261         {
06262                 revertWearable( (EWearableType)i );
06263         }
06264 }
06265 
06266 void LLAgent::saveAllWearables()
06267 {
06268         
06269         
06270         
06271         
06272 
06273         for( S32 i=0; i < WT_COUNT; i++ )
06274         {
06275                 saveWearable( (EWearableType)i, FALSE );
06276         }
06277         sendAgentWearablesUpdate();
06278 }
06279 
06280 
06281 void LLAgent::setWearableName( const LLUUID& item_id, const std::string& new_name )
06282 {
06283         for( S32 i=0; i < WT_COUNT; i++ )
06284         {
06285                 if( mWearableEntry[i].mItemID == item_id )
06286                 {
06287                         LLWearable* old_wearable = mWearableEntry[i].mWearable;
06288                         llassert( old_wearable );
06289 
06290                         LLString old_name = old_wearable->getName();
06291                         old_wearable->setName( new_name );
06292                         LLWearable* new_wearable = gWearableList.createCopy( old_wearable );
06293                         LLInventoryItem* item = gInventory.getItem(item_id);
06294                         if(item)
06295                         {
06296                                 new_wearable->setPermissions(item->getPermissions());
06297                         }
06298                         old_wearable->setName( old_name );
06299 
06300                         mWearableEntry[i].mWearable = new_wearable;
06301                         sendAgentWearablesUpdate();
06302                         break;
06303                 }
06304         }
06305 }
06306 
06307 
06308 BOOL LLAgent::isWearableModifiable(EWearableType type)
06309 {
06310         LLUUID item_id = getWearableItem(type);
06311         if(!item_id.isNull())
06312         {
06313                 LLInventoryItem* item = gInventory.getItem(item_id);
06314                 if(item && item->getPermissions().allowModifyBy(gAgent.getID(),
06315                                                                                                                 gAgent.getGroupID()))
06316                 {
06317                         return TRUE;
06318                 }
06319         }
06320         return FALSE;
06321 }
06322 
06323 BOOL LLAgent::isWearableCopyable(EWearableType type)
06324 {
06325         LLUUID item_id = getWearableItem(type);
06326         if(!item_id.isNull())
06327         {
06328                 LLInventoryItem* item = gInventory.getItem(item_id);
06329                 if(item && item->getPermissions().allowCopyBy(gAgent.getID(),
06330                                                                                                           gAgent.getGroupID()))
06331                 {
06332                         return TRUE;
06333                 }
06334         }
06335         return FALSE;
06336 }
06337 
06338 U32 LLAgent::getWearablePermMask(EWearableType type)
06339 {
06340         LLUUID item_id = getWearableItem(type);
06341         if(!item_id.isNull())
06342         {
06343                 LLInventoryItem* item = gInventory.getItem(item_id);
06344                 if(item)
06345                 {
06346                         return item->getPermissions().getMaskOwner();
06347                 }
06348         }
06349         return PERM_NONE;
06350 }
06351 
06352 LLInventoryItem* LLAgent::getWearableInventoryItem(EWearableType type)
06353 {
06354         LLUUID item_id = getWearableItem(type);
06355         LLInventoryItem* item = NULL;
06356         if(item_id.notNull())
06357         {
06358                  item = gInventory.getItem(item_id);
06359         }
06360         return item;
06361 }
06362 
06363 LLWearable* LLAgent::getWearableFromWearableItem( const LLUUID& item_id )
06364 {
06365         for( S32 i=0; i < WT_COUNT; i++ )
06366         {
06367                 if( mWearableEntry[i].mItemID == item_id )
06368                 {
06369                         return mWearableEntry[i].mWearable;
06370                 }
06371         }
06372         return NULL;
06373 }
06374 
06375 
06376 void LLAgent::sendAgentWearablesRequest()
06377 {
06378         gMessageSystem->newMessageFast(_PREHASH_AgentWearablesRequest);
06379         gMessageSystem->nextBlockFast(_PREHASH_AgentData);
06380         gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
06381         gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
06382         sendReliableMessage();
06383 }
06384 
06385 
06386 
06387 BOOL LLAgent::selfHasWearable( void* userdata )
06388 {
06389         EWearableType type = (EWearableType)(intptr_t)userdata;
06390         return gAgent.getWearable( type ) != NULL;
06391 }
06392 
06393 BOOL LLAgent::isWearingItem( const LLUUID& item_id )
06394 {
06395         return (getWearableFromWearableItem( item_id ) != NULL);
06396 }
06397 
06398 
06399 
06400 void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data )
06401 {
06402         
06403         
06404         static BOOL first = TRUE;
06405         if( first )
06406         {
06407                 first = FALSE;
06408         }
06409         else
06410         {
06411                 return;
06412         }
06413         
06414         if (gNoRender)
06415         {
06416                 return;
06417         }
06418 
06419         LLUUID agent_id;
06420         gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
06421 
06422         LLVOAvatar* avatar = gAgent.getAvatarObject();
06423         if( avatar && (agent_id == avatar->getID()) )
06424         {
06425                 gMessageSystem->getU32Fast(_PREHASH_AgentData, _PREHASH_SerialNum, gAgent.mAgentWearablesUpdateSerialNum );
06426                 
06427                 S32 num_wearables = gMessageSystem->getNumberOfBlocksFast(_PREHASH_WearableData);
06428                 if( num_wearables < 4 )
06429                 {
06430                         
06431                         
06432                         
06433                         
06434                         
06435 
06436                         
06437                         
06438                         gAgent.setGenderChosen(FALSE);
06439                         return;
06440                 }
06441 
06442                 
06443                 
06444                 LLUUID asset_id_array[ WT_COUNT ];
06445                 S32 i;
06446                 for( i=0; i < num_wearables; i++ )
06447                 {
06448                         U8 type_u8 = 0;
06449                         gMessageSystem->getU8Fast(_PREHASH_WearableData, _PREHASH_WearableType, type_u8, i );
06450                         if( type_u8 >= WT_COUNT )
06451                         {
06452                                 continue;
06453                         }
06454                         EWearableType type = (EWearableType) type_u8;
06455 
06456                         LLUUID item_id;
06457                         gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_ItemID, item_id, i );
06458 
06459                         LLUUID asset_id;
06460                         gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i );
06461                         if( asset_id.isNull() )
06462                         {
06463                                 LLWearable::removeFromAvatar( type, FALSE );
06464                         }
06465                         else
06466                         {
06467                                 LLAssetType::EType asset_type = LLWearable::typeToAssetType( type );
06468                                 if( asset_type == LLAssetType::AT_NONE )
06469                                 {
06470                                         continue;
06471                                 }
06472 
06473                                 gAgent.mWearableEntry[type].mItemID = item_id;
06474                                 asset_id_array[type] = asset_id;
06475                         }
06476 
06477                         lldebugs << "       " << LLWearable::typeToTypeLabel(type) << llendl;
06478                 }
06479 
06480                 
06481                 for( i = 0; i < WT_COUNT; i++ )
06482                 {
06483                         if( !gAgent.mWearableEntry[i].mItemID.isNull() )
06484                         {
06485                                 gWearableList.getAsset( 
06486                                         asset_id_array[i],
06487                                         LLString::null,
06488                                         LLWearable::typeToAssetType( (EWearableType) i ), 
06489                                         LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i );
06490                         }
06491                 }
06492         }
06493 }
06494 
06495 
06496 
06497 void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdata )
06498 {
06499         EWearableType type = (EWearableType)(intptr_t)userdata;
06500 
06501         LLVOAvatar* avatar = gAgent.getAvatarObject();
06502         if( !avatar )
06503         {
06504                 return;
06505         }
06506 
06507         if( wearable )
06508         {
06509                 llassert( type == wearable->getType() );
06510                 gAgent.mWearableEntry[ type ].mWearable = wearable;
06511 
06512                 
06513                 avatar->setupComposites();
06514                 gAgent.queryWearableCache();
06515 
06516                 wearable->writeToAvatar( FALSE );
06517                 avatar->setCompositeUpdatesEnabled(TRUE);
06518                 gInventory.addChangedMask( LLInventoryObserver::LABEL, gAgent.mWearableEntry[type].mItemID );
06519         }
06520         else
06521         {
06522                 
06523                 gAgent.recoverMissingWearable( type );
06524         }
06525 
06526         gInventory.notifyObservers();
06527 
06528         
06529         if( !gAgent.mWearablesLoaded )
06530         {
06531                 gAgent.mWearablesLoaded = TRUE;
06532                 for( S32 i = 0; i < WT_COUNT; i++ )
06533                 {
06534                         if( !gAgent.mWearableEntry[i].mItemID.isNull() && !gAgent.mWearableEntry[i].mWearable )
06535                         {
06536                                 gAgent.mWearablesLoaded = FALSE;
06537                                 break;
06538                         }
06539                 }
06540         }
06541 
06542         if( gAgent.mWearablesLoaded )
06543         {
06544                 
06545                 gAgent.sendAgentSetAppearance();
06546 
06547                 
06548                 
06549                 if( !gAgent.cameraCustomizeAvatar() )
06550                 {
06551                         avatar->requestLayerSetUploads();
06552                 }
06553         }
06554 }
06555 
06556 
06557 
06558 
06559 void LLAgent::recoverMissingWearable( EWearableType type )
06560 {
06561         
06562         LLNotifyBox::showXml("ReplacedMissingWearable");
06563         lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
06564         LLWearable* new_wearable = gWearableList.createNewWearable(type);
06565 
06566         S32 type_s32 = (S32) type;
06567         mWearableEntry[type_s32].mWearable = new_wearable;
06568         new_wearable->writeToAvatar( TRUE );
06569 
06570         
06571         
06572         
06573         LLUUID lost_and_found_id = 
06574                 gInventory.findCategoryUUIDForType(LLAssetType::AT_LOST_AND_FOUND);
06575         LLPointer<LLInventoryCallback> cb =
06576                 new addWearableToAgentInventoryCallback(
06577                         LLPointer<LLRefCount>(NULL),
06578                         type_s32,
06579                         new_wearable,
06580                         addWearableToAgentInventoryCallback::CALL_RECOVERDONE);
06581         addWearableToAgentInventory( cb, new_wearable, lost_and_found_id, TRUE);
06582 }
06583 
06584 void LLAgent::recoverMissingWearableDone()
06585 {
06586         
06587         mWearablesLoaded = TRUE;
06588         for( S32 i = 0; i < WT_COUNT; i++ )
06589         {
06590                 if( !mWearableEntry[i].mItemID.isNull() && !mWearableEntry[i].mWearable )
06591                 {
06592                         mWearablesLoaded = FALSE;
06593                         break;
06594                 }
06595         }
06596 
06597         if( mWearablesLoaded )
06598         {
06599                 
06600                 sendAgentSetAppearance();
06601         }
06602         else
06603         {
06604                 gInventory.addChangedMask( LLInventoryObserver::LABEL, LLUUID::null );
06605                 gInventory.notifyObservers();
06606         }
06607 }
06608 
06609 void LLAgent::createStandardWearables(BOOL female)
06610 {
06611         llwarns << "Creating Standard " << (female ? "female" : "male" )
06612                         << " Wearables" << llendl;
06613 
06614         if (mAvatarObject.isNull())
06615         {
06616                 return;
06617         }
06618 
06619         if(female) mAvatarObject->setSex(SEX_FEMALE);
06620         else mAvatarObject->setSex(SEX_MALE);
06621 
06622         BOOL create[WT_COUNT] = 
06623         {
06624                 TRUE,  
06625                 TRUE,  
06626                 TRUE,  
06627                 TRUE,  
06628                 TRUE,  
06629                 TRUE,  
06630                 TRUE,  
06631                 TRUE,  
06632                 FALSE, 
06633                 FALSE, 
06634                 TRUE,  
06635                 TRUE,  
06636                 FALSE  
06637         };
06638 
06639         for( S32 i=0; i < WT_COUNT; i++ )
06640         {
06641                 bool once = false;
06642                 LLPointer<LLRefCount> donecb = NULL;
06643                 if( create[i] )
06644                 {
06645                         if (!once)
06646                         {
06647                                 once = true;
06648                                 donecb = new createStandardWearablesAllDoneCallback;
06649                         }
06650                         llassert( mWearableEntry[i].mWearable == NULL );
06651                         LLWearable* wearable = gWearableList.createNewWearable((EWearableType)i);
06652                         mWearableEntry[i].mWearable = wearable;
06653                         
06654                         LLPointer<LLInventoryCallback> cb =
06655                                 new addWearableToAgentInventoryCallback(
06656                                         donecb,
06657                                         i,
06658                                         wearable,
06659                                         addWearableToAgentInventoryCallback::CALL_CREATESTANDARDDONE);
06660                         addWearableToAgentInventory(cb, wearable, LLUUID::null, FALSE);
06661                 }
06662         }
06663 }
06664 void LLAgent::createStandardWearablesDone(S32 index)
06665 {
06666         LLWearable* wearable = mWearableEntry[index].mWearable;
06667 
06668         if (wearable)
06669         {
06670                 wearable->writeToAvatar(TRUE);
06671         }
06672 }
06673 
06674 void LLAgent::createStandardWearablesAllDone()
06675 {
06676         
06677         
06678         mWearablesLoaded = TRUE; 
06679         sendAgentWearablesUpdate();
06680         sendAgentSetAppearance();
06681 
06682         
06683         mAvatarObject->onFirstTEMessageReceived();
06684 }
06685 
06686 void LLAgent::makeNewOutfit( 
06687         const std::string& new_folder_name,
06688         const LLDynamicArray<S32>& wearables_to_include,
06689         const LLDynamicArray<S32>& attachments_to_include,
06690         BOOL rename_clothing)
06691 {
06692         if (mAvatarObject.isNull())
06693         {
06694                 return;
06695         }
06696 
06697         
06698         LLUUID folder_id = gInventory.createNewCategory(
06699                 gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING),
06700                 LLAssetType::AT_NONE,
06701                 new_folder_name);
06702 
06703         bool found_first_item = false;
06704 
06706         
06707 
06708         if( wearables_to_include.count() )
06709         {
06710                 
06711                 S32 i;
06712                 S32 count = wearables_to_include.count();
06713                 LLDynamicArray<LLUUID> delete_items;
06714                 LLPointer<LLRefCount> cbdone = NULL;
06715                 for( i = 0; i < count; ++i )
06716                 {
06717                         S32 index = wearables_to_include[i];
06718                         LLWearable* old_wearable = mWearableEntry[ index ].mWearable;
06719                         if( old_wearable )
06720                         {
06721                                 std::string new_name;
06722                                 LLWearable* new_wearable;
06723                                 new_wearable = gWearableList.createCopy(old_wearable);
06724                                 if (rename_clothing)
06725                                 {
06726                                         new_name = new_folder_name;
06727                                         new_name.append(" ");
06728                                         new_name.append(old_wearable->getTypeLabel());
06729                                         LLString::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
06730                                         new_wearable->setName(new_name);
06731                                 }
06732 
06733                                 LLViewerInventoryItem* item = gInventory.getItem(mWearableEntry[index].mItemID);
06734                                 S32 todo = addWearableToAgentInventoryCallback::CALL_NONE;
06735                                 if (!found_first_item)
06736                                 {
06737                                         found_first_item = true;
06738                                         
06739                                         todo |= addWearableToAgentInventoryCallback::CALL_MAKENEWOUTFITDONE;
06740                                         
06741                                         cbdone = new sendAgentWearablesUpdateCallback;
06742                                 }
06743                                 LLPointer<LLInventoryCallback> cb =
06744                                         new addWearableToAgentInventoryCallback(
06745                                                 cbdone,
06746                                                 index,
06747                                                 new_wearable,
06748                                                 todo);
06749                                 if (isWearableCopyable((EWearableType)index))
06750                                 {
06751                                         copy_inventory_item(
06752                                                 gAgent.getID(),
06753                                                 item->getPermissions().getOwner(),
06754                                                 item->getUUID(),
06755                                                 folder_id,
06756                                                 new_name,
06757                                                 cb);
06758                                 }
06759                                 else
06760                                 {
06761                                         move_inventory_item(
06762                                                 gAgent.getID(),
06763                                                 gAgent.getSessionID(),
06764                                                 item->getUUID(),
06765                                                 folder_id,
06766                                                 new_name,
06767                                                 cb);
06768                                 }
06769                         }
06770                 }
06771                 gInventory.notifyObservers();
06772         }
06773 
06774 
06776         
06777 
06778         if( attachments_to_include.count() )
06779         {
06780                 BOOL msg_started = FALSE;
06781                 LLMessageSystem* msg = gMessageSystem;
06782                 S32 i;
06783                 for( i = 0; i < attachments_to_include.count(); i++ )
06784                 {
06785                         S32 attachment_pt = attachments_to_include[i];
06786                         LLViewerJointAttachment* attachment = mAvatarObject->mAttachmentPoints.getIfThere( attachment_pt );
06787                         if(!attachment) continue;
06788                         LLViewerObject* attached_object = attachment->getObject();
06789                         if(!attached_object) continue;
06790                         const LLUUID& item_id = attachment->getItemID();
06791                         if(item_id.isNull()) continue;
06792                         LLInventoryItem* item = gInventory.getItem(item_id);
06793                         if(!item) continue;
06794                         if(!msg_started)
06795                         {
06796                                 msg_started = TRUE;
06797                                 msg->newMessage("CreateNewOutfitAttachments");
06798                                 msg->nextBlock("AgentData");
06799                                 msg->addUUID("AgentID", getID());
06800                                 msg->addUUID("SessionID", getSessionID());
06801                                 msg->nextBlock("HeaderData");
06802                                 msg->addUUID("NewFolderID", folder_id);
06803                         }
06804                         msg->nextBlock("ObjectData");
06805                         msg->addUUID("OldItemID", item_id);
06806                         msg->addUUID("OldFolderID", item->getParentUUID());
06807                 }
06808 
06809                 if( msg_started )
06810                 {
06811                         sendReliableMessage();
06812                 }
06813 
06814         } 
06815 }
06816 
06817 void LLAgent::makeNewOutfitDone(S32 index)
06818 {
06819         LLUUID first_item_id = mWearableEntry[index].mItemID;
06820         
06821         if( first_item_id.notNull() )
06822         {
06823                 LLInventoryView* view = LLInventoryView::getActiveInventory();
06824                 if(view)
06825                 {
06826                         view->getPanel()->setSelection(first_item_id, TAKE_FOCUS_NO);
06827                 }
06828         }
06829 }
06830 
06831 
06832 void LLAgent::addWearableToAgentInventory(
06833         LLPointer<LLInventoryCallback> cb,
06834         LLWearable* wearable,
06835         const LLUUID& category_id,
06836         BOOL notify)
06837 {
06838         create_inventory_item(
06839                 gAgent.getID(),
06840                 gAgent.getSessionID(),
06841                 category_id,
06842                 wearable->getTransactionID(),
06843                 wearable->getName(),
06844                 wearable->getDescription(),
06845                 wearable->getAssetType(),
06846                 LLInventoryType::IT_WEARABLE,
06847                 wearable->getType(),
06848                 wearable->getPermissions().getMaskNextOwner(),
06849                 cb);
06850 }
06851 
06852 
06853 
06854 
06855 void LLAgent::sendAgentSetAppearance()
06856 {
06857         if (mAvatarObject.isNull()) return;
06858 
06859         if (mNumPendingQueries > 0 && !gAgent.cameraCustomizeAvatar()) 
06860         {
06861                 return;
06862         }
06863 
06864         llinfos << "TAT: Sent AgentSetAppearance: " <<
06865                 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "HEAD " : "head " ) <<
06866                 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "UPPER " : "upper " ) <<
06867                 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "LOWER " : "lower " ) <<
06868                 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR )  ? "EYES" : "eyes" ) << llendl;
06869         
06870 
06871         LLMessageSystem* msg = gMessageSystem;
06872         msg->newMessageFast(_PREHASH_AgentSetAppearance);
06873         msg->nextBlockFast(_PREHASH_AgentData);
06874         msg->addUUIDFast(_PREHASH_AgentID, getID());
06875         msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
06876 
06877         
06878         
06879         
06880         
06881         
06882         LLVector3 body_size = mAvatarObject->mBodySize;
06883         msg->addVector3Fast(_PREHASH_Size, body_size);  
06884 
06885         
06886         
06887         mAppearanceSerialNum++;
06888         msg->addU32Fast(_PREHASH_SerialNum, mAppearanceSerialNum );
06889 
06890         
06891         
06892         BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded;
06893 
06894         S32 baked_texture_index;
06895         for( baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++ )
06896         {
06897                 S32 tex_index = LLVOAvatar::sBakedTextureIndices[baked_texture_index];
06898 
06899                 
06900                 if (tex_index == LLVOAvatar::TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT))
06901                 {
06902                         continue;
06903                 }
06904 
06905                 
06906                 if (mAvatarObject->getTEImage( tex_index)->getID() == IMG_DEFAULT_AVATAR)
06907                 {
06908                         textures_current = FALSE;
06909                         break;
06910                 }
06911         }
06912 
06913         
06914         if (textures_current)
06915         {
06916                 llinfos << "TAT: Sending cached texture data" << llendl;
06917                 for (baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++)
06918                 {
06919                         LLUUID hash;
06920 
06921                         for( S32 wearable_num = 0; wearable_num < MAX_WEARABLES_PER_LAYERSET; wearable_num++ )
06922                         {
06923                                 EWearableType wearable_type = WEARABLE_BAKE_TEXTURE_MAP[baked_texture_index][wearable_num];
06924 
06925                                 LLWearable* wearable = getWearable( wearable_type );
06926                                 if (wearable)
06927                                 {
06928                                         hash ^= wearable->getID();
06929                                 }
06930                         }
06931 
06932                         if (hash.notNull())
06933                         {
06934                                 hash ^= BAKED_TEXTURE_HASH[baked_texture_index];
06935                         }
06936 
06937                         S32 tex_index = LLVOAvatar::sBakedTextureIndices[baked_texture_index];
06938 
06939                         msg->nextBlockFast(_PREHASH_WearableData);
06940                         msg->addUUIDFast(_PREHASH_CacheID, hash);
06941                         msg->addU8Fast(_PREHASH_TextureIndex, (U8)tex_index);
06942                 }
06943         }
06944 
06945         msg->nextBlockFast(_PREHASH_ObjectData);
06946         mAvatarObject->packTEMessage( gMessageSystem );
06947 
06948         S32 transmitted_params = 0;
06949         for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam();
06950                  param;
06951                  param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam())
06952         {
06953                 F32 param_value = param->getWeight();
06954         
06955                 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
06956                 {
06957                         msg->nextBlockFast(_PREHASH_VisualParam );
06958                         
06959                         
06960                         U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight());
06961                         msg->addU8Fast(_PREHASH_ParamValue, new_weight );
06962                         transmitted_params++;
06963                 }
06964         }
06965 
06966 
06967         sendReliableMessage();
06968 }
06969 
06970 void LLAgent::sendAgentDataUpdateRequest()
06971 {
06972         gMessageSystem->newMessageFast(_PREHASH_AgentDataUpdateRequest);
06973         gMessageSystem->nextBlockFast(_PREHASH_AgentData);
06974         gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
06975         gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
06976         sendReliableMessage();
06977 }
06978 
06979 void LLAgent::removeWearable( EWearableType type )
06980 {
06981         LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
06982 
06983         if ( (gAgent.isTeen())
06984                  && (type == WT_UNDERSHIRT || type == WT_UNDERPANTS))
06985         {
06986                 
06987                 return;
06988         }
06989 
06990         if( old_wearable )
06991         {
06992                 if( old_wearable->isDirty() )
06993                 {
06994                         
06995                         gViewerWindow->alertXml("WearableSave", LLAgent::onRemoveWearableDialog, (void*)type );
06996                         return;
06997                 }
06998                 else
06999                 {
07000                         removeWearableFinal( type );
07001                 }
07002         }
07003 }
07004 
07005 
07006 void LLAgent::onRemoveWearableDialog( S32 option, void* userdata )
07007 {
07008         EWearableType type = (EWearableType)(intptr_t)userdata;
07009         switch( option )
07010         {
07011         case 0:  
07012                 gAgent.saveWearable( type );
07013                 gAgent.removeWearableFinal( type );
07014                 break;
07015 
07016         case 1:  
07017                 gAgent.removeWearableFinal( type );
07018                 break;
07019 
07020         case 2: 
07021                 break;
07022 
07023         default:
07024                 llassert(0);
07025                 break;
07026         }
07027 }
07028 
07029 
07030 void LLAgent::removeWearableFinal( EWearableType type )
07031 {
07032         LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
07033 
07034         gInventory.addChangedMask( LLInventoryObserver::LABEL, mWearableEntry[type].mItemID );
07035 
07036         mWearableEntry[ type ].mWearable = NULL;
07037         mWearableEntry[ type ].mItemID.setNull();
07038 
07039         queryWearableCache();
07040 
07041         if( old_wearable )
07042         {
07043                 old_wearable->removeFromAvatar( TRUE );
07044         }
07045 
07046         
07047         sendAgentWearablesUpdate(); 
07048         sendAgentSetAppearance();
07049         gInventory.notifyObservers();
07050 }
07051 
07052 void LLAgent::copyWearableToInventory( EWearableType type )
07053 {
07054         LLWearable* wearable = mWearableEntry[ type ].mWearable;
07055         if( wearable )
07056         {
07057                 
07058                 if( wearable->isDirty() )
07059                 {
07060                         wearable = gWearableList.createCopyFromAvatar( wearable );
07061                         mWearableEntry[ type ].mWearable = wearable;
07062                 }
07063 
07064                 
07065                 LLUUID category_id;
07066                 LLInventoryItem* item = gInventory.getItem( mWearableEntry[ type ].mItemID );
07067                 if( item )
07068                 {
07069                         category_id = item->getParentUUID();
07070                         wearable->setPermissions(item->getPermissions());
07071                 }
07072                 LLPointer<LLInventoryCallback> cb =
07073                         new addWearableToAgentInventoryCallback(
07074                                 LLPointer<LLRefCount>(NULL),
07075                                 type,
07076                                 wearable);
07077                 addWearableToAgentInventory(cb, wearable, category_id);
07078         }
07079 }
07080 
07081 
07082 
07083 struct LLSetWearableData
07084 {
07085         LLSetWearableData( const LLUUID& new_item_id, LLWearable* new_wearable ) :
07086                 mNewItemID( new_item_id ), mNewWearable( new_wearable ) {}
07087         LLUUID                          mNewItemID;
07088         LLWearable*                     mNewWearable;
07089 };
07090 
07091 BOOL LLAgent::needsReplacement(EWearableType  wearableType, S32 remove)
07092 {
07093         return TRUE;
07094         
07095 
07096 
07097 }
07098 
07099 
07100 void LLAgent::setWearableOutfit( 
07101         const LLInventoryItem::item_array_t& items,
07102         const LLDynamicArray< LLWearable* >& wearables,
07103         BOOL remove )
07104 {
07105         lldebugs << "setWearableOutfit() start" << llendl;
07106 
07107         BOOL wearables_to_remove[WT_COUNT];
07108         wearables_to_remove[WT_SHAPE]           = FALSE;
07109         wearables_to_remove[WT_SKIN]            = FALSE;
07110         wearables_to_remove[WT_HAIR]            = FALSE;
07111         wearables_to_remove[WT_EYES]            = FALSE;
07112         wearables_to_remove[WT_SHIRT]           = remove;
07113         wearables_to_remove[WT_PANTS]           = remove;
07114         wearables_to_remove[WT_SHOES]           = remove;
07115         wearables_to_remove[WT_SOCKS]           = remove;
07116         wearables_to_remove[WT_JACKET]          = remove;
07117         wearables_to_remove[WT_GLOVES]          = remove;
07118         wearables_to_remove[WT_UNDERSHIRT]      = (!gAgent.isTeen()) & remove;
07119         wearables_to_remove[WT_UNDERPANTS]      = (!gAgent.isTeen()) & remove;
07120         wearables_to_remove[WT_SKIRT]           = remove;
07121 
07122         S32 count = wearables.count();
07123         llassert( items.count() == count );
07124 
07125         S32 i;
07126         for( i = 0; i < count; i++ )
07127         {
07128                 LLWearable* new_wearable = wearables[i];
07129                 LLPointer<LLInventoryItem> new_item = items[i];
07130 
07131                 EWearableType type = new_wearable->getType();
07132                 wearables_to_remove[type] = FALSE;
07133 
07134                 LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
07135                 if( old_wearable )
07136                 {
07137                         const LLUUID& old_item_id = mWearableEntry[ type ].mItemID;
07138                         if( (old_wearable->getID() == new_wearable->getID()) &&
07139                                 (old_item_id == new_item->getUUID()) )
07140                         {
07141                                 lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl;
07142                                 continue;
07143                         }
07144 
07145                         gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
07146 
07147                         
07148                         if( old_wearable->isDirty() )
07149                         {
07150                                 llassert(0);
07151                                 continue;
07152                         }
07153                 }
07154 
07155                 mWearableEntry[ type ].mItemID = new_item->getUUID();
07156                 mWearableEntry[ type ].mWearable = new_wearable;
07157         }
07158 
07159         std::vector<LLWearable*> wearables_being_removed;
07160 
07161         for( i = 0; i < WT_COUNT; i++ )
07162         {
07163                 if( wearables_to_remove[i] )
07164                 {
07165                         wearables_being_removed.push_back(mWearableEntry[ i ].mWearable);
07166                         mWearableEntry[ i ].mWearable = NULL;
07167                         
07168                         gInventory.addChangedMask(LLInventoryObserver::LABEL, mWearableEntry[ i ].mItemID);
07169                         mWearableEntry[ i ].mItemID.setNull();
07170                 }
07171         }
07172 
07173         gInventory.notifyObservers();
07174 
07175         queryWearableCache();
07176 
07177         std::vector<LLWearable*>::iterator wearable_iter;
07178 
07179         for( wearable_iter = wearables_being_removed.begin(); 
07180                 wearable_iter != wearables_being_removed.end();
07181                 ++wearable_iter)
07182         {
07183                 LLWearable* wearablep = *wearable_iter;
07184                 if (wearablep)
07185                 {
07186                         wearablep->removeFromAvatar( TRUE );
07187                 }
07188         }
07189 
07190         for( i = 0; i < count; i++ )
07191         {
07192                 wearables[i]->writeToAvatar( TRUE );
07193         }
07194 
07195         LLFloaterCustomize::setCurrentWearableType( WT_SHAPE );
07196 
07197         
07198         mWearablesLoaded = TRUE; 
07199         sendAgentWearablesUpdate();
07200         sendAgentSetAppearance();
07201 
07202         lldebugs << "setWearableOutfit() end" << llendl;
07203 }
07204 
07205 
07206 
07207 void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
07208 {
07209         EWearableType type = new_wearable->getType();
07210 
07211         LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
07212         if( old_wearable )
07213         {
07214                 const LLUUID& old_item_id = mWearableEntry[ type ].mItemID;
07215                 if( (old_wearable->getID() == new_wearable->getID()) &&
07216                         (old_item_id == new_item->getUUID()) )
07217                 {
07218                         lldebugs << "No change to wearable asset and item: " << LLWearable::typeToTypeName( type ) << llendl;
07219                         return;
07220                 }
07221 
07222                 if( old_wearable->isDirty() )
07223                 {
07224                         
07225                         gViewerWindow->alertXml( "WearableSave", LLAgent::onSetWearableDialog,
07226                                 new LLSetWearableData( new_item->getUUID(), new_wearable ));
07227                         return;
07228                 }
07229         }
07230 
07231         setWearableFinal( new_item, new_wearable );
07232 }
07233 
07234 
07235 void LLAgent::onSetWearableDialog( S32 option, void* userdata )
07236 {
07237         LLSetWearableData* data = (LLSetWearableData*)userdata;
07238         LLInventoryItem* new_item = gInventory.getItem( data->mNewItemID );
07239         if( !new_item )
07240         {
07241                 delete data;
07242                 return;
07243         }
07244 
07245         switch( option )
07246         {
07247         case 0:  
07248                 gAgent.saveWearable( data->mNewWearable->getType() );
07249                 gAgent.setWearableFinal( new_item, data->mNewWearable );
07250                 break;
07251 
07252         case 1:  
07253                 gAgent.setWearableFinal( new_item, data->mNewWearable );
07254                 break;
07255 
07256         case 2: 
07257                 break;
07258 
07259         default:
07260                 llassert(0);
07261                 break;
07262         }
07263 
07264         delete data;
07265 }
07266 
07267 
07268 void LLAgent::setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable )
07269 {
07270         EWearableType type = new_wearable->getType();
07271 
07272         
07273         llassert( new_item->getAssetUUID() == new_wearable->getID() );
07274         LLUUID old_item_id = mWearableEntry[ type ].mItemID;
07275         mWearableEntry[ type ].mItemID = new_item->getUUID();
07276         mWearableEntry[ type ].mWearable = new_wearable;
07277 
07278         if (old_item_id.notNull())
07279         {
07280                 gInventory.addChangedMask( LLInventoryObserver::LABEL, old_item_id );
07281                 gInventory.notifyObservers();
07282         }
07283 
07284         
07285         queryWearableCache();
07286         new_wearable->writeToAvatar( TRUE );
07287 
07288         
07289         sendAgentWearablesUpdate();
07290         sendAgentSetAppearance();
07291 }
07292 
07293 void LLAgent::queryWearableCache()
07294 {
07295         if (!mWearablesLoaded)
07296         {
07297                 return;
07298         }
07299 
07300         
07301         
07302         
07303         
07304         
07305         
07306         
07307         
07308 
07309         gMessageSystem->newMessageFast(_PREHASH_AgentCachedTexture);
07310         gMessageSystem->nextBlockFast(_PREHASH_AgentData);
07311         gMessageSystem->addUUIDFast(_PREHASH_AgentID, getID());
07312         gMessageSystem->addUUIDFast(_PREHASH_SessionID, getSessionID());
07313         gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID);
07314 
07315         S32 num_queries = 0;
07316         for (S32 baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++)
07317         {
07318                 LLUUID hash;
07319                 for (S32 wearable_num = 0; wearable_num < MAX_WEARABLES_PER_LAYERSET; wearable_num++)
07320                 {
07321                         EWearableType wearable_type = WEARABLE_BAKE_TEXTURE_MAP[baked_texture_index][wearable_num];
07322                                 
07323                         LLWearable* wearable = getWearable( wearable_type );
07324                         if (wearable)
07325                         {
07326                                 hash ^= wearable->getID();
07327                         }
07328                 }
07329                 if (hash.notNull())
07330                 {
07331                         hash ^= BAKED_TEXTURE_HASH[baked_texture_index];
07332                         num_queries++;
07333                         
07334 
07335                         
07336                         gMessageSystem->nextBlockFast(_PREHASH_WearableData);
07337                         gMessageSystem->addUUIDFast(_PREHASH_ID, hash);
07338                         gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_texture_index);
07339                 }
07340 
07341                 mActiveCacheQueries[ baked_texture_index ] = mTextureCacheQueryID;
07342         }
07343 
07344         llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
07345         gMessageSystem->sendReliable(getRegion()->getHost());
07346         mNumPendingQueries++;
07347         mTextureCacheQueryID++;
07348 }
07349 
07350 
07351 
07352 void LLAgent::userRemoveWearable( void* userdata )
07353 {
07354         EWearableType type = (EWearableType)(intptr_t)userdata;
07355         
07356         if( !(type==WT_SHAPE || type==WT_SKIN || type==WT_HAIR ) ) 
07358         {
07359                 gAgent.removeWearable( type );
07360         }
07361 }
07362 
07363 void LLAgent::userRemoveAllClothes( void* userdata )
07364 {
07365         
07366         if( gFloaterCustomize )
07367         {
07368                 gFloaterCustomize->askToSaveAllIfDirty( LLAgent::userRemoveAllClothesStep2, NULL );
07369         }
07370         else
07371         {
07372                 LLAgent::userRemoveAllClothesStep2( TRUE, NULL );
07373         }
07374 }
07375 
07376 void LLAgent::userRemoveAllClothesStep2( BOOL proceed, void* userdata )
07377 {
07378         if( proceed )
07379         {
07380                 gAgent.removeWearable( WT_SHIRT );
07381                 gAgent.removeWearable( WT_PANTS );
07382                 gAgent.removeWearable( WT_SHOES );
07383                 gAgent.removeWearable( WT_SOCKS );
07384                 gAgent.removeWearable( WT_JACKET );
07385                 gAgent.removeWearable( WT_GLOVES );
07386                 gAgent.removeWearable( WT_UNDERSHIRT );
07387                 gAgent.removeWearable( WT_UNDERPANTS );
07388                 gAgent.removeWearable( WT_SKIRT );
07389         }
07390 }
07391 
07392 void LLAgent::userRemoveAllAttachments( void* userdata )
07393 {
07394         LLVOAvatar* avatarp = gAgent.getAvatarObject();
07395         if(!avatarp)
07396         {
07397                 llwarns << "No avatar found." << llendl;
07398                 return;
07399         }
07400 
07401         gMessageSystem->newMessage("ObjectDetach");
07402         gMessageSystem->nextBlockFast(_PREHASH_AgentData);
07403         gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
07404         gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
07405 
07406         LLViewerJointAttachment* attachment;
07407         for (attachment = avatarp->mAttachmentPoints.getFirstData();
07408                  attachment;
07409                  attachment = avatarp->mAttachmentPoints.getNextData())
07410         {
07411                 LLViewerObject* objectp = attachment->getObject();
07412                 if (objectp)
07413                 {
07414                         gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
07415                         gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID());
07416                 }
07417         }
07418         gMessageSystem->sendReliable( gAgent.getRegionHost() );
07419 }
07420 
07421 bool LLAgent::LLHideGroupTitleListener::handleEvent(LLPointer<LLEvent> event, const LLSD &userdata)
07422 {
07423         gAgent.setHideGroupTitle(event->getValue());
07424         return true;
07425 
07426 }
07427 
07428 bool LLAgent::LLEffectColorListener::handleEvent(LLPointer<LLEvent> event, const LLSD &userdata)
07429 {
07430         gAgent.setEffectColor(LLColor4(event->getValue()));
07431         return true;
07432 }
07433 
07434 void LLAgent::observeFriends()
07435 {
07436         if(!mFriendObserver)
07437         {
07438                 mFriendObserver = new LLAgentFriendObserver;
07439                 LLAvatarTracker::instance().addObserver(mFriendObserver);
07440                 friendsChanged();
07441         }
07442 }
07443 
07444 void LLAgent::parseTeleportMessages(const LLString& xml_filename)
07445 {
07446         LLXMLNodePtr root;
07447         BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
07448 
07449         if (!success || !root || !root->hasName( "teleport_messages" ))
07450         {
07451                 llerrs << "Problem reading teleport string XML file: " 
07452                            << xml_filename << llendl;
07453                 return;
07454         }
07455 
07456         for (LLXMLNode* message_set = root->getFirstChild();
07457                  message_set != NULL;
07458                  message_set = message_set->getNextSibling())
07459         {
07460                 if ( !message_set->hasName("message_set") ) continue;
07461 
07462                 std::map<LLString, LLString> *teleport_msg_map = NULL;
07463                 LLString message_set_name;
07464 
07465                 if ( message_set->getAttributeString("name", message_set_name) )
07466                 {
07467                         
07468                         
07469                         if ( message_set_name == "errors" )
07470                         {
07471                                 teleport_msg_map = &sTeleportErrorMessages;
07472                         }
07473                         else if ( message_set_name == "progress" )
07474                         {
07475                                 teleport_msg_map = &sTeleportProgressMessages;
07476                         }
07477                 }
07478 
07479                 if ( !teleport_msg_map ) continue;
07480 
07481                 LLString message_name;
07482                 for (LLXMLNode* message_node = message_set->getFirstChild();
07483                          message_node != NULL;
07484                          message_node = message_node->getNextSibling())
07485                 {
07486                         if ( message_node->hasName("message") && 
07487                                  message_node->getAttributeString("name", message_name) )
07488                         {
07489                                 (*teleport_msg_map)[message_name] =
07490                                         message_node->getTextContents();
07491                         } 
07492                 } 
07493         }
07494 }
07495 
07496