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