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