aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llagent.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-11-19 04:19:06 -0600
committerJacek Antonelli2009-11-19 04:19:06 -0600
commit1d443b7a94ed6f9ef1d408caef72fcbc0b1ee427 (patch)
treee09ccbc010e326a48fd91ba15b58afd7fb836b3f /linden/indra/newview/llagent.cpp
parentFixed minor formatting issue in MANIFESTO.txt. (diff)
parentFixed CMake setting errors (diff)
downloadmeta-impy-1d443b7a94ed6f9ef1d408caef72fcbc0b1ee427.zip
meta-impy-1d443b7a94ed6f9ef1d408caef72fcbc0b1ee427.tar.gz
meta-impy-1d443b7a94ed6f9ef1d408caef72fcbc0b1ee427.tar.bz2
meta-impy-1d443b7a94ed6f9ef1d408caef72fcbc0b1ee427.tar.xz
Merge remote branch 'mccabe/1.3.0-next' into next
Conflicts: linden/indra/cmake/00-Common.cmake linden/indra/newview/skins/default/xui/de/floater_about.xml linden/indra/newview/skins/default/xui/fr/floater_about.xml linden/indra/newview/skins/default/xui/ja/floater_about.xml linden/indra/newview/skins/default/xui/ko/floater_about.xml linden/indra/newview/skins/default/xui/zh/floater_about.xml linden/install.xml
Diffstat (limited to 'linden/indra/newview/llagent.cpp')
-rw-r--r--linden/indra/newview/llagent.cpp772
1 files changed, 452 insertions, 320 deletions
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index a0ab4ab..800264d 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -36,6 +37,7 @@
36 37
37#include "llagent.h" 38#include "llagent.h"
38 39
40#include "llcamera.h"
39#include "llcoordframe.h" 41#include "llcoordframe.h"
40#include "indra_constants.h" 42#include "indra_constants.h"
41#include "llmath.h" 43#include "llmath.h"
@@ -99,6 +101,7 @@
99#include "llstartup.h" 101#include "llstartup.h"
100#include "llimview.h" 102#include "llimview.h"
101#include "lltool.h" 103#include "lltool.h"
104#include "lltoolcomp.h"
102#include "lltoolfocus.h" 105#include "lltoolfocus.h"
103#include "lltoolgrab.h" 106#include "lltoolgrab.h"
104#include "lltoolmgr.h" 107#include "lltoolmgr.h"
@@ -131,6 +134,8 @@
131#include "llviewerjoystick.h" 134#include "llviewerjoystick.h"
132#include "llfollowcam.h" 135#include "llfollowcam.h"
133 136
137using namespace LLVOAvatarDefines;
138
134extern LLMenuBarGL* gMenuBarView; 139extern LLMenuBarGL* gMenuBarView;
135 140
136//drone wandering constants 141//drone wandering constants
@@ -207,33 +212,12 @@ const F32 MIN_RADIUS_ALPHA_SIZZLE = 0.5f;
207 212
208const F64 CHAT_AGE_FAST_RATE = 3.0; 213const F64 CHAT_AGE_FAST_RATE = 3.0;
209 214
210const S32 MAX_WEARABLES_PER_LAYERSET = 7;
211
212const EWearableType WEARABLE_BAKE_TEXTURE_MAP[BAKED_TEXTURE_COUNT][MAX_WEARABLES_PER_LAYERSET] =
213{
214 { WT_SHAPE, WT_SKIN, WT_HAIR, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID }, // TEX_HEAD_BAKED
215 { WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT, WT_INVALID }, // TEX_UPPER_BAKED
216 { WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS }, // TEX_LOWER_BAKED
217 { WT_EYES, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID }, // TEX_EYES_BAKED
218 { WT_SKIRT, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID, WT_INVALID } // TEX_SKIRT_BAKED
219};
220
221const LLUUID BAKED_TEXTURE_HASH[BAKED_TEXTURE_COUNT] =
222{
223 LLUUID("18ded8d6-bcfc-e415-8539-944c0f5ea7a6"),
224 LLUUID("338c29e3-3024-4dbb-998d-7c04cf4fa88f"),
225 LLUUID("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f"),
226 LLUUID("b2cf28af-b840-1071-3c6a-78085d8128b5"),
227 LLUUID("ea800387-ea1a-14e0-56cb-24f2022f969a")
228};
229
230// The agent instance. 215// The agent instance.
231LLAgent gAgent; 216LLAgent gAgent;
232 217
233// 218//
234// Statics 219// Statics
235// 220//
236BOOL LLAgent::sDebugDisplayTarget = FALSE;
237BOOL LLAgent::sPhantom = FALSE; 221BOOL LLAgent::sPhantom = FALSE;
238 222
239const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; 223const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
@@ -273,35 +257,42 @@ void LLAgentFriendObserver::changed(U32 mask)
273//----------------------------------------------------------------------------- 257//-----------------------------------------------------------------------------
274// LLAgent() 258// LLAgent()
275//----------------------------------------------------------------------------- 259//-----------------------------------------------------------------------------
276LLAgent::LLAgent() 260LLAgent::LLAgent() :
277: mDrawDistance( DEFAULT_FAR_PLANE ), 261 mDrawDistance( DEFAULT_FAR_PLANE ),
278
279 mDoubleTapRunTimer(),
280 mDoubleTapRunMode(DOUBLETAP_NONE),
281
282 mbAlwaysRun(false),
283 mbRunning(false),
284 262
285 mAccess(SIM_ACCESS_PG),
286 mGroupPowers(0), 263 mGroupPowers(0),
264 mHideGroupTitle(FALSE),
287 mGroupID(), 265 mGroupID(),
288 //mGroupInsigniaID(), 266
289 mMapOriginX(0), 267 mMapOriginX(0.F),
290 mMapOriginY(0), 268 mMapOriginY(0.F),
291 mMapWidth(0), 269 mMapWidth(0),
292 mMapHeight(0), 270 mMapHeight(0),
271
293 mLookAt(NULL), 272 mLookAt(NULL),
294 mPointAt(NULL), 273 mPointAt(NULL),
274
275 mHUDTargetZoom(1.f),
276 mHUDCurZoom(1.f),
295 mInitialized(FALSE), 277 mInitialized(FALSE),
296 mNumPendingQueries(0), 278 mNumPendingQueries(0),
279 mActiveCacheQueries(NULL),
297 mForceMouselook(FALSE), 280 mForceMouselook(FALSE),
281
282 mDoubleTapRunTimer(),
283 mDoubleTapRunMode(DOUBLETAP_NONE),
284
285 mbAlwaysRun(false),
286 mbRunning(false),
287
288 mAgentAccess(gSavedSettings),
298 mTeleportState( TELEPORT_NONE ), 289 mTeleportState( TELEPORT_NONE ),
299 mRegionp(NULL), 290 mRegionp(NULL),
300 291
301 mAgentOriginGlobal(), 292 mAgentOriginGlobal(),
302 mPositionGlobal(), 293 mPositionGlobal(),
303 294
304 mDistanceTraveled(0), 295 mDistanceTraveled(0.F),
305 mLastPositionGlobal(LLVector3d::zero), 296 mLastPositionGlobal(LLVector3d::zero),
306 297
307 mAvatarObject(NULL), 298 mAvatarObject(NULL),
@@ -313,43 +304,67 @@ LLAgent::LLAgent()
313 mLastCameraMode( CAMERA_MODE_THIRD_PERSON ), 304 mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
314 mViewsPushed(FALSE), 305 mViewsPushed(FALSE),
315 306
307 mCustomAnim(FALSE),
316 mShowAvatar(TRUE), 308 mShowAvatar(TRUE),
317
318 mCameraAnimating( FALSE ), 309 mCameraAnimating( FALSE ),
319 mAnimationCameraStartGlobal(), 310 mAnimationCameraStartGlobal(),
320 mAnimationFocusStartGlobal(), 311 mAnimationFocusStartGlobal(),
321 mAnimationTimer(), 312 mAnimationTimer(),
322 mAnimationDuration(0.33f), 313 mAnimationDuration(0.33f),
314
323 mCameraFOVZoomFactor(0.f), 315 mCameraFOVZoomFactor(0.f),
324 mCameraCurrentFOVZoomFactor(0.f), 316 mCameraCurrentFOVZoomFactor(0.f),
325 mCameraFocusOffset(), 317 mCameraFocusOffset(),
318 mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
319
326 mCameraOffsetDefault(), 320 mCameraOffsetDefault(),
327// mCameraOffsetNorm(),
328 mCameraCollidePlane(), 321 mCameraCollidePlane(),
322
329 mCurrentCameraDistance(2.f), // meters, set in init() 323 mCurrentCameraDistance(2.f), // meters, set in init()
330 mTargetCameraDistance(2.f), 324 mTargetCameraDistance(2.f),
331 mCameraZoomFraction(1.f), // deprecated 325 mCameraZoomFraction(1.f), // deprecated
332 mThirdPersonHeadOffset(0.f, 0.f, 1.f), 326 mThirdPersonHeadOffset(0.f, 0.f, 1.f),
333 mSitCameraEnabled(FALSE), 327 mSitCameraEnabled(FALSE),
334 mHUDTargetZoom(1.f), 328 mCameraSmoothingLastPositionGlobal(),
335 mHUDCurZoom(1.f), 329 mCameraSmoothingLastPositionAgent(),
330 mCameraSmoothingStop(FALSE),
331
332 mCameraUpVector(LLVector3::z_axis), // default is straight up
333
336 mFocusOnAvatar(TRUE), 334 mFocusOnAvatar(TRUE),
337 mFocusGlobal(), 335 mFocusGlobal(),
338 mFocusTargetGlobal(), 336 mFocusTargetGlobal(),
339 mFocusObject(NULL), 337 mFocusObject(NULL),
338 mFocusObjectDist(0.f),
340 mFocusObjectOffset(), 339 mFocusObjectOffset(),
341 mFocusDotRadius( 0.1f ), // meters 340 mFocusDotRadius( 0.1f ), // meters
342 mTrackFocusObject(TRUE), 341 mTrackFocusObject(TRUE),
343 mCameraSmoothingLastPositionGlobal(), 342 mUIOffset(0.f),
344 mCameraSmoothingLastPositionAgent(),
345 mCameraSmoothingStop(FALSE),
346 343
347 mFrameAgent(), 344 mFrameAgent(),
348 345
349 mCrouching(FALSE),
350 mIsBusy(FALSE), 346 mIsBusy(FALSE),
351 347
352 // movement keys below 348 mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
349 mWalkKey(0), // like AtKey, but causes less forward thrust
350 mLeftKey(0),
351 mUpKey(0),
352 mYawKey(0.f),
353 mPitchKey(0),
354
355 mOrbitLeftKey(0.f),
356 mOrbitRightKey(0.f),
357 mOrbitUpKey(0.f),
358 mOrbitDownKey(0.f),
359 mOrbitInKey(0.f),
360 mOrbitOutKey(0.f),
361
362 mPanUpKey(0.f),
363 mPanDownKey(0.f),
364 mPanLeftKey(0.f),
365 mPanRightKey(0.f),
366 mPanInKey(0.f),
367 mPanOutKey(0.f),
353 368
354 mControlFlags(0x00000000), 369 mControlFlags(0x00000000),
355 mbFlagsDirty(FALSE), 370 mbFlagsDirty(FALSE),
@@ -364,27 +379,27 @@ LLAgent::LLAgent()
364 mAutoPilotUseRotation(FALSE), 379 mAutoPilotUseRotation(FALSE),
365 mAutoPilotTargetFacing(LLVector3::zero), 380 mAutoPilotTargetFacing(LLVector3::zero),
366 mAutoPilotTargetDist(0.f), 381 mAutoPilotTargetDist(0.f),
382 mAutoPilotNoProgressFrameCount(0),
383 mAutoPilotRotationThreshold(0.f),
367 mAutoPilotFinishedCallback(NULL), 384 mAutoPilotFinishedCallback(NULL),
368 mAutoPilotCallbackData(NULL), 385 mAutoPilotCallbackData(NULL),
369 386
370
371 mEffectColor(0.f, 1.f, 1.f, 1.f), 387 mEffectColor(0.f, 1.f, 1.f, 1.f),
388
372 mHaveHomePosition(FALSE), 389 mHaveHomePosition(FALSE),
373 mHomeRegionHandle( 0 ), 390 mHomeRegionHandle( 0 ),
374 mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f), 391 mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f),
375 mGodLevel( GOD_NOT ),
376
377 392
378 mNextFidgetTime(0.f), 393 mNextFidgetTime(0.f),
379 mCurrentFidget(0), 394 mCurrentFidget(0),
380 mFirstLogin(FALSE), 395 mFirstLogin(FALSE),
381 mGenderChosen(FALSE), 396 mGenderChosen(FALSE),
397
382 mAgentWearablesUpdateSerialNum(0), 398 mAgentWearablesUpdateSerialNum(0),
383 mWearablesLoaded(FALSE), 399 mWearablesLoaded(FALSE),
384 mTextureCacheQueryID(0), 400 mTextureCacheQueryID(0),
385 mAppearanceSerialNum(0) 401 mAppearanceSerialNum(0)
386{ 402{
387
388 U32 i; 403 U32 i;
389 for (i = 0; i < TOTAL_CONTROLS; i++) 404 for (i = 0; i < TOTAL_CONTROLS; i++)
390 { 405 {
@@ -392,40 +407,13 @@ LLAgent::LLAgent()
392 mControlsTakenPassedOnCount[i] = 0; 407 mControlsTakenPassedOnCount[i] = 0;
393 } 408 }
394 409
395 // Initialize movement keys 410 mActiveCacheQueries = new S32[BAKED_NUM_INDICES];
396 mAtKey = 0; // Either 1, 0, or -1... indicates that movement-key is pressed 411 for (i = 0; i < (U32)BAKED_NUM_INDICES; i++)
397 mWalkKey = 0; // like AtKey, but causes less forward thrust
398 mLeftKey = 0;
399 mUpKey = 0;
400 mYawKey = 0.f;
401 mPitchKey = 0;
402
403 mOrbitLeftKey = 0.f;
404 mOrbitRightKey = 0.f;
405 mOrbitUpKey = 0.f;
406 mOrbitDownKey = 0.f;
407 mOrbitInKey = 0.f;
408 mOrbitOutKey = 0.f;
409
410 mPanUpKey = 0.f;
411 mPanDownKey = 0.f;
412 mPanLeftKey = 0.f;
413 mPanRightKey = 0.f;
414 mPanInKey = 0.f;
415 mPanOutKey = 0.f;
416
417 mActiveCacheQueries = new S32[BAKED_TEXTURE_COUNT];
418 for (i = 0; i < (U32)BAKED_TEXTURE_COUNT; i++)
419 { 412 {
420 mActiveCacheQueries[i] = 0; 413 mActiveCacheQueries[i] = 0;
421 } 414 }
422 415
423 //Ventrella
424 mCameraUpVector = LLVector3::z_axis;// default is straight up
425 mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT ); 416 mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
426 //end ventrella
427
428 mCustomAnim = FALSE ;
429} 417}
430 418
431// Requires gSavedSettings to be initialized. 419// Requires gSavedSettings to be initialized.
@@ -449,10 +437,8 @@ void LLAgent::init()
449 437
450 mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild")); 438 mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
451 mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault"); 439 mCameraOffsetDefault = gSavedSettings.getVector3("CameraOffsetDefault");
452// mCameraOffsetNorm = mCameraOffsetDefault;
453// mCameraOffsetNorm.normalize();
454 mCameraCollidePlane.clearVec(); 440 mCameraCollidePlane.clearVec();
455 mCurrentCameraDistance = mCameraOffsetDefault.magVec(); 441 mCurrentCameraDistance = mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale");
456 mTargetCameraDistance = mCurrentCameraDistance; 442 mTargetCameraDistance = mCurrentCameraDistance;
457 mCameraZoomFraction = 1.f; 443 mCameraZoomFraction = 1.f;
458 mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject"); 444 mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
@@ -475,8 +461,16 @@ void LLAgent::cleanup()
475 461
476 setSitCamera(LLUUID::null); 462 setSitCamera(LLUUID::null);
477 mAvatarObject = NULL; 463 mAvatarObject = NULL;
478 mLookAt = NULL; 464 if(mLookAt)
479 mPointAt = NULL; 465 {
466 mLookAt->markDead() ;
467 mLookAt = NULL;
468 }
469 if(mPointAt)
470 {
471 mPointAt->markDead() ;
472 mPointAt = NULL;
473 }
480 mRegionp = NULL; 474 mRegionp = NULL;
481 setFocusObject(NULL); 475 setFocusObject(NULL);
482} 476}
@@ -582,7 +576,7 @@ void LLAgent::onAppFocusGained()
582 576
583void LLAgent::ageChat() 577void LLAgent::ageChat()
584{ 578{
585 if (mAvatarObject) 579 if (mAvatarObject.notNull())
586 { 580 {
587 // get amount of time since I last chatted 581 // get amount of time since I last chatted
588 F64 elapsed_time = (F64)mAvatarObject->mChatTimer.getElapsedTimeF32(); 582 F64 elapsed_time = (F64)mAvatarObject->mChatTimer.getElapsedTimeF32();
@@ -599,7 +593,7 @@ void LLAgent::unlockView()
599{ 593{
600 if (getFocusOnAvatar()) 594 if (getFocusOnAvatar())
601 { 595 {
602 if (mAvatarObject) 596 if (mAvatarObject.notNull())
603 { 597 {
604 setFocusGlobal( LLVector3d::zero, mAvatarObject->mID ); 598 setFocusGlobal( LLVector3d::zero, mAvatarObject->mID );
605 } 599 }
@@ -1055,7 +1049,7 @@ void LLAgent::sendReliableMessage()
1055//----------------------------------------------------------------------------- 1049//-----------------------------------------------------------------------------
1056LLVector3 LLAgent::getVelocity() const 1050LLVector3 LLAgent::getVelocity() const
1057{ 1051{
1058 if (mAvatarObject) 1052 if (mAvatarObject.notNull())
1059 { 1053 {
1060 return mAvatarObject->getVelocity(); 1054 return mAvatarObject->getVelocity();
1061 } 1055 }
@@ -1076,7 +1070,7 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
1076 llerrs << "setPositionAgent is not a number" << llendl; 1070 llerrs << "setPositionAgent is not a number" << llendl;
1077 } 1071 }
1078 1072
1079 if (!mAvatarObject.isNull() && mAvatarObject->getParent()) 1073 if (mAvatarObject.notNull() && mAvatarObject->getParent())
1080 { 1074 {
1081 LLVector3 pos_agent_sitting; 1075 LLVector3 pos_agent_sitting;
1082 LLVector3d pos_agent_d; 1076 LLVector3d pos_agent_d;
@@ -1114,7 +1108,7 @@ void LLAgent::slamLookAt(const LLVector3 &look_at)
1114//----------------------------------------------------------------------------- 1108//-----------------------------------------------------------------------------
1115const LLVector3d &LLAgent::getPositionGlobal() const 1109const LLVector3d &LLAgent::getPositionGlobal() const
1116{ 1110{
1117 if (!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull()) 1111 if (mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
1118 { 1112 {
1119 mPositionGlobal = getPosGlobalFromAgent(mAvatarObject->getRenderPosition()); 1113 mPositionGlobal = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());
1120 } 1114 }
@@ -1131,7 +1125,7 @@ const LLVector3d &LLAgent::getPositionGlobal() const
1131//----------------------------------------------------------------------------- 1125//-----------------------------------------------------------------------------
1132const LLVector3 &LLAgent::getPositionAgent() 1126const LLVector3 &LLAgent::getPositionAgent()
1133{ 1127{
1134 if(!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull()) 1128 if(mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
1135 { 1129 {
1136 mFrameAgent.setOrigin(mAvatarObject->getRenderPosition()); 1130 mFrameAgent.setOrigin(mAvatarObject->getRenderPosition());
1137 } 1131 }
@@ -1366,167 +1360,171 @@ LLQuaternion LLAgent::getQuat() const
1366//----------------------------------------------------------------------------- 1360//-----------------------------------------------------------------------------
1367// calcFocusOffset() 1361// calcFocusOffset()
1368//----------------------------------------------------------------------------- 1362//-----------------------------------------------------------------------------
1369LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, LLVector3 pos_agent, S32 x, S32 y) 1363LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y)
1370{ 1364{
1371 // calculate offset based on view direction 1365 LLMatrix4 obj_matrix = object->getRenderMatrix();
1372 BOOL is_avatar = object->isAvatar(); 1366 LLQuaternion obj_rot = object->getRenderRotation();
1373 LLMatrix4 obj_matrix = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldMatrix() : object->getRenderMatrix(); 1367 LLVector3 obj_pos = object->getRenderPosition();
1374 LLQuaternion obj_rot = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldRotation() : object->getRenderRotation();
1375 LLVector3 obj_pos = is_avatar ? ((LLVOAvatar*)object)->mPelvisp->getWorldPosition() : object->getRenderPosition();
1376 LLQuaternion inv_obj_rot = ~obj_rot;
1377 1368
1378 LLVector3 obj_dir_abs = obj_pos - LLViewerCamera::getInstance()->getOrigin(); 1369 BOOL is_avatar = object->isAvatar();
1379 obj_dir_abs.rotVec(inv_obj_rot); 1370 // if is avatar - don't do any funk heuristics to position the focal point
1380 obj_dir_abs.normalize(); 1371 // see DEV-30589
1381 obj_dir_abs.abs(); 1372 if (is_avatar)
1373 {
1374 return original_focus_point - obj_pos;
1375 }
1382 1376
1377
1378 LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
1383 LLVector3 object_extents = object->getScale(); 1379 LLVector3 object_extents = object->getScale();
1384 // make sure they object extents are non-zero 1380 // make sure they object extents are non-zero
1385 object_extents.clamp(0.001f, F32_MAX); 1381 object_extents.clamp(0.001f, F32_MAX);
1386 LLVector3 object_half_extents = object_extents * 0.5f;
1387 1382
1388 obj_dir_abs.mV[VX] = obj_dir_abs.mV[VX] / object_extents.mV[VX]; 1383 // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object
1389 obj_dir_abs.mV[VY] = obj_dir_abs.mV[VY] / object_extents.mV[VY]; 1384 LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin();
1390 obj_dir_abs.mV[VZ] = obj_dir_abs.mV[VZ] / object_extents.mV[VZ]; 1385 obj_to_cam_ray.rotVec(inv_obj_rot);
1386 obj_to_cam_ray.normalize();
1391 1387
1392 LLVector3 normal; 1388 // obj_to_cam_ray_proportions are the (positive) ratios of
1393 if (obj_dir_abs.mV[VX] > obj_dir_abs.mV[VY] && obj_dir_abs.mV[VX] > obj_dir_abs.mV[VZ]) 1389 // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions.
1390 LLVector3 obj_to_cam_ray_proportions;
1391 obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]);
1392 obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]);
1393 obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]);
1394
1395 // find the largest ratio stored in obj_to_cam_ray_proportions
1396 // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera
1397 LLVector3 longest_object_axis;
1398 // is x-axis longest?
1399 if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY]
1400 && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ])
1394 { 1401 {
1395 normal.setVec(obj_matrix.getFwdRow4()); 1402 // then grab it
1403 longest_object_axis.setVec(obj_matrix.getFwdRow4());
1396 } 1404 }
1397 else if (obj_dir_abs.mV[VY] > obj_dir_abs.mV[VZ]) 1405 // is y-axis longest?
1406 else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ])
1398 { 1407 {
1399 normal.setVec(obj_matrix.getLeftRow4()); 1408 // then grab it
1409 longest_object_axis.setVec(obj_matrix.getLeftRow4());
1400 } 1410 }
1411 // otherwise, use z axis
1401 else 1412 else
1402 { 1413 {
1403 normal.setVec(obj_matrix.getUpRow4()); 1414 longest_object_axis.setVec(obj_matrix.getUpRow4());
1404 } 1415 }
1405 normal.normalize(); 1416
1417 // Use this axis as the normal to project mouse click on to plane with that normal, at the object center.
1418 // This generates a point behind the mouse cursor that is approximately in the middle of the object in
1419 // terms of depth.
1420 // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera.
1421 // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable
1422 // eccentricity to the object orientation
1423 LLVector3 focus_plane_normal(longest_object_axis);
1424 focus_plane_normal.normalize();
1406 1425
1407 LLVector3d focus_pt_global; 1426 LLVector3d focus_pt_global;
1408 // RN: should we check return value for valid pick? 1427 gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal);
1409 gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), normal);
1410 LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global); 1428 LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global);
1411 // find vector from camera to focus point in object coordinates 1429
1412 LLVector3 camera_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin(); 1430 // find vector from camera to focus point in object space
1413 // convert to object-local space 1431 LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin();
1414 camera_focus_vec.rotVec(inv_obj_rot); 1432 camera_to_focus_vec.rotVec(inv_obj_rot);
1415 1433
1416 // find vector from object origin to focus point in object coordinates 1434 // find vector from object origin to focus point in object coordinates
1417 LLVector3 focus_delta = focus_pt - obj_pos; 1435 LLVector3 focus_offset_from_object_center = focus_pt - obj_pos;
1418 // convert to object-local space 1436 // convert to object-local space
1419 focus_delta.rotVec(inv_obj_rot); 1437 focus_offset_from_object_center.rotVec(inv_obj_rot);
1420 1438
1421 // calculate clip percentage needed to get focus offset back in bounds along the camera_focus axis 1439 // We need to project the focus point back into the bounding box of the focused object.
1440 // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis
1422 LLVector3 clip_fraction; 1441 LLVector3 clip_fraction;
1423 1442
1443 // for each axis...
1424 for (U32 axis = VX; axis <= VZ; axis++) 1444 for (U32 axis = VX; axis <= VZ; axis++)
1425 { 1445 {
1426 F32 clip_amt; 1446 //...calculate distance that focus offset sits outside of bounding box along that axis...
1427 if (focus_delta.mV[axis] > 0.f) 1447 //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center
1448 F32 dist_out_of_bounds;
1449 if (focus_offset_from_object_center.mV[axis] > 0.f)
1428 { 1450 {
1429 clip_amt = llmax(0.f, focus_delta.mV[axis] - object_half_extents.mV[axis]); 1451 dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f));
1430 } 1452 }
1431 else 1453 else
1432 { 1454 {
1433 clip_amt = llmin(0.f, focus_delta.mV[axis] + object_half_extents.mV[axis]); 1455 dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f));
1434 } 1456 }
1435 1457
1436 // don't divide by very small nunber 1458 //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis
1437 if (llabs(camera_focus_vec.mV[axis]) < 0.0001f) 1459 if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f)
1438 { 1460 {
1461 // don't divide by very small number
1439 clip_fraction.mV[axis] = 0.f; 1462 clip_fraction.mV[axis] = 0.f;
1440 } 1463 }
1441 else 1464 else
1442 { 1465 {
1443 clip_fraction.mV[axis] = clip_amt / camera_focus_vec.mV[axis]; 1466 clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis];
1444 } 1467 }
1445 } 1468 }
1446 1469
1447 LLVector3 abs_clip_fraction = clip_fraction; 1470 LLVector3 abs_clip_fraction = clip_fraction;
1448 abs_clip_fraction.abs(); 1471 abs_clip_fraction.abs();
1449 1472
1450 // find greatest shrinkage factor and 1473 // find axis of focus offset that is *most* outside the bounding box and use that to
1451 // rescale focus offset to inside object extents 1474 // rescale focus offset to inside object extents
1452 if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY] && 1475 if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY]
1453 abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ]) 1476 && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ])
1454 { 1477 {
1455 focus_delta -= clip_fraction.mV[VX] * camera_focus_vec; 1478 focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec;
1456 } 1479 }
1457 else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ]) 1480 else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ])
1458 { 1481 {
1459 focus_delta -= clip_fraction.mV[VY] * camera_focus_vec; 1482 focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec;
1460 } 1483 }
1461 else 1484 else
1462 { 1485 {
1463 focus_delta -= clip_fraction.mV[VZ] * camera_focus_vec; 1486 focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec;
1464 } 1487 }
1465 1488
1466 // convert back to world space 1489 // convert back to world space
1467 focus_delta.rotVec(obj_rot); 1490 focus_offset_from_object_center.rotVec(obj_rot);
1468 1491
1492 // now, based on distance of camera from object relative to object size
1493 // push the focus point towards the near surface of the object when (relatively) close to the objcet
1494 // or keep the focus point in the object middle when (relatively) far
1495 // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
1496 // is almost always "tumble about middle" and not "spin around surface point"
1469 if (!is_avatar) 1497 if (!is_avatar)
1470 { 1498 {
1471 //unproject relative clicked coordinate from window coordinate using GL 1499 LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
1472 /*GLint viewport[4];
1473 GLdouble modelview[16];
1474 GLdouble projection[16];
1475 GLfloat winX, winY, winZ;
1476 GLdouble posX, posY, posZ;
1477
1478 // convert our matrices to something that has a multiply that works
1479 glh::matrix4f newModel((F32*)LLViewerCamera::getInstance()->getModelview().mMatrix);
1480 glh::matrix4f tmpObjMat((F32*)obj_matrix.mMatrix);
1481 newModel *= tmpObjMat;
1482
1483 for(U32 i = 0; i < 16; ++i)
1484 {
1485 modelview[i] = newModel.m[i];
1486 projection[i] = LLViewerCamera::getInstance()->getProjection().mMatrix[i/4][i%4];
1487 }
1488 glGetIntegerv( GL_VIEWPORT, viewport );
1489
1490 winX = ((F32)x) * gViewerWindow->getDisplayScale().mV[VX];
1491 winY = ((F32)y) * gViewerWindow->getDisplayScale().mV[VY];
1492 glReadPixels( llfloor(winX), llfloor(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
1493
1494 gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);*/
1495
1496 LLVector3 obj_rel = pos_agent - object->getRenderPosition();
1497 1500
1498 LLVector3 obj_center = LLVector3(0, 0, 0) * object->getRenderMatrix();
1499
1500 //now that we have the object relative position, we should bias toward the center of the object 1501 //now that we have the object relative position, we should bias toward the center of the object
1501 //based on the distance of the camera to the focus point vs. the distance of the camera to the focus 1502 //based on the distance of the camera to the focus point vs. the distance of the camera to the focus
1502 1503
1503 F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis()); 1504 F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis());
1504 F32 viewDist = dist_vec(obj_center + obj_rel, LLViewerCamera::getInstance()->getOrigin()); 1505 F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin());
1505 1506
1506 1507
1507 LLBBox obj_bbox = object->getBoundingBoxAgent(); 1508 LLBBox obj_bbox = object->getBoundingBoxAgent();
1508 F32 bias = 0.f; 1509 F32 bias = 0.f;
1509 1510
1511 // virtual_camera_pos is the camera position we are simulating by backing the camera off
1512 // and adjusting the FOV
1510 LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor)); 1513 LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor));
1511 1514
1512 if(obj_bbox.containsPointAgent(virtual_camera_pos)) 1515 // if the camera is inside the object (large, hollow objects, for example)
1513 { 1516 // leave focus point all the way to destination depth, away from object center
1514 // if the camera is inside the object (large, hollow objects, for example) 1517 if(!obj_bbox.containsPointAgent(virtual_camera_pos))
1515 // force focus point all the way to destination depth, away from object center
1516 bias = 1.f;
1517 }
1518 else
1519 { 1518 {
1520 // perform magic number biasing of focus point towards surface vs. planar center 1519 // perform magic number biasing of focus point towards surface vs. planar center
1521 bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f); 1520 bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f);
1521 obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias);
1522 } 1522 }
1523 1523
1524 obj_rel = lerp(focus_delta, obj_rel, bias); 1524 focus_offset_from_object_center = obj_rel;
1525
1526 return LLVector3(obj_rel);
1527 } 1525 }
1528 1526
1529 return LLVector3(focus_delta.mV[VX], focus_delta.mV[VY], focus_delta.mV[VZ]); 1527 return focus_offset_from_object_center;
1530} 1528}
1531 1529
1532//----------------------------------------------------------------------------- 1530//-----------------------------------------------------------------------------
@@ -1947,7 +1945,7 @@ void LLAgent::cameraOrbitIn(const F32 meters)
1947{ 1945{
1948 if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) 1946 if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
1949 { 1947 {
1950 F32 camera_offset_dist = llmax(0.001f, mCameraOffsetDefault.magVec()); 1948 F32 camera_offset_dist = llmax(0.001f, mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"));
1951 1949
1952 mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist; 1950 mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
1953 1951
@@ -2396,11 +2394,11 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)
2396 if (user_cancel && !mAutoPilotBehaviorName.empty()) 2394 if (user_cancel && !mAutoPilotBehaviorName.empty())
2397 { 2395 {
2398 if (mAutoPilotBehaviorName == "Sit") 2396 if (mAutoPilotBehaviorName == "Sit")
2399 LLNotifyBox::showXml("CancelledSit"); 2397 LLNotifications::instance().add("CancelledSit");
2400 else if (mAutoPilotBehaviorName == "Attach") 2398 else if (mAutoPilotBehaviorName == "Attach")
2401 LLNotifyBox::showXml("CancelledAttach"); 2399 LLNotifications::instance().add("CancelledAttach");
2402 else 2400 else
2403 LLNotifyBox::showXml("Cancelled"); 2401 LLNotifications::instance().add("Cancelled");
2404 } 2402 }
2405 } 2403 }
2406} 2404}
@@ -2425,7 +2423,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
2425 mAutoPilotTargetGlobal = object->getPositionGlobal(); 2423 mAutoPilotTargetGlobal = object->getPositionGlobal();
2426 } 2424 }
2427 2425
2428 if (!mAvatarObject) 2426 if (mAvatarObject.isNull())
2429 { 2427 {
2430 return; 2428 return;
2431 } 2429 }
@@ -2506,7 +2504,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
2506 // If we're flying, handle autopilot points above or below you. 2504 // If we're flying, handle autopilot points above or below you.
2507 if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE) 2505 if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE)
2508 { 2506 {
2509 if (mAvatarObject) 2507 if (mAvatarObject.notNull())
2510 { 2508 {
2511 F64 current_height = mAvatarObject->getPositionGlobal().mdV[VZ]; 2509 F64 current_height = mAvatarObject->getPositionGlobal().mdV[VZ];
2512 F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height); 2510 F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height);
@@ -2591,7 +2589,7 @@ void LLAgent::propagate(const F32 dt)
2591 pitch(PITCH_RATE * (F32) mPitchKey * dt); 2589 pitch(PITCH_RATE * (F32) mPitchKey * dt);
2592 2590
2593 // handle auto-land behavior 2591 // handle auto-land behavior
2594 if (mAvatarObject) 2592 if (mAvatarObject.notNull())
2595 { 2593 {
2596 BOOL in_air = mAvatarObject->mInAir; 2594 BOOL in_air = mAvatarObject->mInAir;
2597 LLVector3 land_vel = getVelocity(); 2595 LLVector3 land_vel = getVelocity();
@@ -2642,7 +2640,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
2642 static LLVector3 last_at_axis; 2640 static LLVector3 last_at_axis;
2643 2641
2644 2642
2645 if ( mAvatarObject.isNull() ) 2643 if (mAvatarObject.isNull())
2646 { 2644 {
2647 return; 2645 return;
2648 } 2646 }
@@ -2776,7 +2774,7 @@ BOOL LLAgent::needsRenderAvatar()
2776// TRUE if we need to render your own avatar's head. 2774// TRUE if we need to render your own avatar's head.
2777BOOL LLAgent::needsRenderHead() 2775BOOL LLAgent::needsRenderHead()
2778{ 2776{
2779 return mShowAvatar && !cameraMouselook(); 2777 return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !cameraMouselook());
2780} 2778}
2781 2779
2782//----------------------------------------------------------------------------- 2780//-----------------------------------------------------------------------------
@@ -2915,7 +2913,7 @@ void LLAgent::endAnimationUpdateUI()
2915 } 2913 }
2916 2914
2917 // Disable mouselook-specific animations 2915 // Disable mouselook-specific animations
2918 if (mAvatarObject) 2916 if (mAvatarObject.notNull())
2919 { 2917 {
2920 if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) ) 2918 if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
2921 { 2919 {
@@ -2961,7 +2959,7 @@ void LLAgent::endAnimationUpdateUI()
2961 gMorphView->setVisible( FALSE ); 2959 gMorphView->setVisible( FALSE );
2962 } 2960 }
2963 2961
2964 if (mAvatarObject) 2962 if (mAvatarObject.notNull())
2965 { 2963 {
2966 if(mCustomAnim) 2964 if(mCustomAnim)
2967 { 2965 {
@@ -3004,7 +3002,7 @@ void LLAgent::endAnimationUpdateUI()
3004 gIMMgr->setFloaterOpen( FALSE ); 3002 gIMMgr->setFloaterOpen( FALSE );
3005 gConsole->setVisible( TRUE ); 3003 gConsole->setVisible( TRUE );
3006 3004
3007 if (mAvatarObject) 3005 if (mAvatarObject.notNull())
3008 { 3006 {
3009 // Trigger mouselook-specific animations 3007 // Trigger mouselook-specific animations
3010 if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_HOLD_ANIMS, NUM_AGENT_GUN_HOLD_ANIMS) ) 3008 if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_HOLD_ANIMS, NUM_AGENT_GUN_HOLD_ANIMS) )
@@ -3065,7 +3063,7 @@ void LLAgent::endAnimationUpdateUI()
3065 } 3063 }
3066 3064
3067 // freeze avatar 3065 // freeze avatar
3068 if (mAvatarObject) 3066 if (mAvatarObject.notNull())
3069 { 3067 {
3070 mPauseRequest = mAvatarObject->requestPause(); 3068 mPauseRequest = mAvatarObject->requestPause();
3071 } 3069 }
@@ -3099,7 +3097,7 @@ void LLAgent::updateCamera()
3099 3097
3100 validateFocusObject(); 3098 validateFocusObject();
3101 3099
3102 if (!mAvatarObject.isNull() && 3100 if (mAvatarObject.notNull() &&
3103 mAvatarObject->mIsSitting && 3101 mAvatarObject->mIsSitting &&
3104 camera_mode == CAMERA_MODE_MOUSELOOK) 3102 camera_mode == CAMERA_MODE_MOUSELOOK)
3105 { 3103 {
@@ -3213,7 +3211,7 @@ void LLAgent::updateCamera()
3213 //Ventrella 3211 //Ventrella
3214 if ( mCameraMode == CAMERA_MODE_FOLLOW ) 3212 if ( mCameraMode == CAMERA_MODE_FOLLOW )
3215 { 3213 {
3216 if ( !mAvatarObject.isNull() ) 3214 if ( mAvatarObject.notNull() )
3217 { 3215 {
3218 //-------------------------------------------------------------------------------- 3216 //--------------------------------------------------------------------------------
3219 // this is where the avatar's position and rotation are given to followCam, and 3217 // this is where the avatar's position and rotation are given to followCam, and
@@ -3314,12 +3312,15 @@ void LLAgent::updateCamera()
3314 } 3312 }
3315 3313
3316 // smoothing 3314 // smoothing
3317 if (TRUE) 3315 if (TRUE)
3318 { 3316 {
3319 LLVector3d agent_pos = getPositionGlobal(); 3317 LLVector3d agent_pos = getPositionGlobal();
3320 LLVector3d camera_pos_agent = camera_pos_global - agent_pos; 3318 LLVector3d camera_pos_agent = camera_pos_global - agent_pos;
3319 // Sitting on what you're manipulating can cause camera jitter with smoothing.
3320 // This turns off smoothing while editing. -MG
3321 mCameraSmoothingStop |= (BOOL)LLToolMgr::getInstance()->inBuildMode();
3321 3322
3322 if (cameraThirdPerson() && !mCameraSmoothingStop) // only smooth in third person mode 3323 if (cameraThirdPerson() && !mCameraSmoothingStop)
3323 { 3324 {
3324 const F32 SMOOTHING_HALF_LIFE = 0.02f; 3325 const F32 SMOOTHING_HALF_LIFE = 0.02f;
3325 3326
@@ -3523,7 +3524,7 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal()
3523 { 3524 {
3524 LLVector3d at_axis(1.0, 0.0, 0.0); 3525 LLVector3d at_axis(1.0, 0.0, 0.0);
3525 LLQuaternion agent_rot = mFrameAgent.getQuaternion(); 3526 LLQuaternion agent_rot = mFrameAgent.getQuaternion();
3526 if (!mAvatarObject.isNull() && mAvatarObject->getParent()) 3527 if (mAvatarObject.notNull() && mAvatarObject->getParent())
3527 { 3528 {
3528 LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot(); 3529 LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
3529 if (!root_object->flagCameraDecoupled()) 3530 if (!root_object->flagCameraDecoupled())
@@ -3745,7 +3746,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
3745 } 3746 }
3746 else 3747 else
3747 { 3748 {
3748 local_camera_offset = mCameraZoomFraction * mCameraOffsetDefault; 3749 local_camera_offset = mCameraZoomFraction * mCameraOffsetDefault * gSavedSettings.getF32("CameraOffsetScale");
3749 3750
3750 // are we sitting down? 3751 // are we sitting down?
3751 if (mAvatarObject.notNull() && mAvatarObject->getParent()) 3752 if (mAvatarObject.notNull() && mAvatarObject->getParent())
@@ -3821,7 +3822,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
3821 camera_offset.setVec( local_camera_offset ); 3822 camera_offset.setVec( local_camera_offset );
3822 camera_position_global = frame_center_global + head_offset + camera_offset; 3823 camera_position_global = frame_center_global + head_offset + camera_offset;
3823 3824
3824 if (!mAvatarObject.isNull()) 3825 if (mAvatarObject.notNull())
3825 { 3826 {
3826 LLVector3d camera_lag_d; 3827 LLVector3d camera_lag_d;
3827 F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE); 3828 F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
@@ -3896,7 +3897,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
3896 if(constrain) 3897 if(constrain)
3897 { 3898 {
3898 F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ? 3899 F32 max_dist = ( CAMERA_MODE_CUSTOMIZE_AVATAR == mCameraMode ) ?
3899 APPEARANCE_MAX_ZOOM : MAX_CAMERA_DISTANCE_FROM_AGENT; 3900 APPEARANCE_MAX_ZOOM : mDrawDistance;
3900 3901
3901 LLVector3d camera_offset = camera_position_global 3902 LLVector3d camera_offset = camera_position_global
3902 - gAgent.getPositionGlobal(); 3903 - gAgent.getPositionGlobal();
@@ -3976,10 +3977,10 @@ void LLAgent::handleScrollWheel(S32 clicks)
3976 } 3977 }
3977 else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON) 3978 else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
3978 { 3979 {
3979 F32 current_zoom_fraction = mTargetCameraDistance / mCameraOffsetDefault.magVec(); 3980 F32 current_zoom_fraction = mTargetCameraDistance / (mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"));
3980 current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks); 3981 current_zoom_fraction *= 1.f - pow(ROOT_ROOT_TWO, clicks);
3981 3982
3982 cameraOrbitIn(current_zoom_fraction * mCameraOffsetDefault.magVec()); 3983 cameraOrbitIn(current_zoom_fraction * mCameraOffsetDefault.magVec() * gSavedSettings.getF32("CameraOffsetScale"));
3983 } 3984 }
3984 else 3985 else
3985 { 3986 {
@@ -4052,7 +4053,7 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
4052 gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE); 4053 gSavedSettings.setBOOL("ThirdPersonBtnState", FALSE);
4053 gSavedSettings.setBOOL("BuildBtnState", FALSE); 4054 gSavedSettings.setBOOL("BuildBtnState", FALSE);
4054 4055
4055 if (mAvatarObject) 4056 if (mAvatarObject.notNull())
4056 { 4057 {
4057 mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE ); 4058 mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
4058 mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT ); 4059 mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
@@ -4140,7 +4141,7 @@ void LLAgent::changeCameraToFollow(BOOL animate)
4140 LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); 4141 LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
4141 } 4142 }
4142 4143
4143 if (mAvatarObject) 4144 if (mAvatarObject.notNull())
4144 { 4145 {
4145 mAvatarObject->mPelvisp->setPosition(LLVector3::zero); 4146 mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
4146 mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE ); 4147 mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
@@ -4188,7 +4189,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
4188 4189
4189 mCameraZoomFraction = INITIAL_ZOOM_FRACTION; 4190 mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
4190 4191
4191 if (mAvatarObject) 4192 if (mAvatarObject.notNull())
4192 { 4193 {
4193 if (!mAvatarObject->mIsSitting) 4194 if (!mAvatarObject->mIsSitting)
4194 { 4195 {
@@ -4234,7 +4235,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
4234 } 4235 }
4235 4236
4236 // Remove any pitch from the avatar 4237 // Remove any pitch from the avatar
4237 if (!mAvatarObject.isNull() && mAvatarObject->getParent()) 4238 if (mAvatarObject.notNull() && mAvatarObject->getParent())
4238 { 4239 {
4239 LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation(); 4240 LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
4240 at_axis = LLViewerCamera::getInstance()->getAtAxis(); 4241 at_axis = LLViewerCamera::getInstance()->getAtAxis();
@@ -4320,7 +4321,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
4320 LLVOAvatar::onCustomizeStart(); 4321 LLVOAvatar::onCustomizeStart();
4321 } 4322 }
4322 4323
4323 if (!mAvatarObject.isNull()) 4324 if (mAvatarObject.notNull())
4324 { 4325 {
4325 if(avatar_animate) 4326 if(avatar_animate)
4326 { 4327 {
@@ -4405,7 +4406,19 @@ void LLAgent::setFocusObject(LLViewerObject* object)
4405//----------------------------------------------------------------------------- 4406//-----------------------------------------------------------------------------
4406void LLAgent::setFocusGlobal(const LLPickInfo& pick) 4407void LLAgent::setFocusGlobal(const LLPickInfo& pick)
4407{ 4408{
4408 setFocusGlobal(pick.mPosGlobal, pick.mObjectID); 4409 LLViewerObject* objectp = gObjectList.findObject(pick.mObjectID);
4410
4411 if (objectp)
4412 {
4413 // focus on object plus designated offset
4414 // which may or may not be same as pick.mPosGlobal
4415 setFocusGlobal(objectp->getPositionGlobal() + LLVector3d(pick.mObjectOffset), pick.mObjectID);
4416 }
4417 else
4418 {
4419 // focus directly on point where user clicked
4420 setFocusGlobal(pick.mPosGlobal, pick.mObjectID);
4421 }
4409} 4422}
4410 4423
4411 4424
@@ -4420,7 +4433,7 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
4420 { 4433 {
4421 if (focus.isExactlyZero()) 4434 if (focus.isExactlyZero())
4422 { 4435 {
4423 if (!mAvatarObject.isNull()) 4436 if (mAvatarObject.notNull())
4424 { 4437 {
4425 mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition()); 4438 mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
4426 } 4439 }
@@ -4465,7 +4478,7 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
4465 { 4478 {
4466 if (focus.isExactlyZero()) 4479 if (focus.isExactlyZero())
4467 { 4480 {
4468 if (!mAvatarObject.isNull()) 4481 if (mAvatarObject.notNull())
4469 { 4482 {
4470 mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition()); 4483 mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
4471 } 4484 }
@@ -4483,7 +4496,8 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
4483 // for attachments, make offset relative to avatar, not the attachment 4496 // for attachments, make offset relative to avatar, not the attachment
4484 if (mFocusObject->isAttachment()) 4497 if (mFocusObject->isAttachment())
4485 { 4498 {
4486 while (!mFocusObject->isAvatar()) 4499 while (mFocusObject.notNull() // DEV-29123 - can crash with a messed-up attachment
4500 && !mFocusObject->isAvatar())
4487 { 4501 {
4488 mFocusObject = (LLViewerObject*) mFocusObject->getParent(); 4502 mFocusObject = (LLViewerObject*) mFocusObject->getParent();
4489 } 4503 }
@@ -4602,7 +4616,7 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
4602 if (mCameraMode == CAMERA_MODE_THIRD_PERSON) 4616 if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
4603 { 4617 {
4604 LLVector3 at_axis; 4618 LLVector3 at_axis;
4605 if (!mAvatarObject.isNull() && mAvatarObject->getParent()) 4619 if (mAvatarObject.notNull() && mAvatarObject->getParent())
4606 { 4620 {
4607 LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation(); 4621 LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
4608 at_axis = LLViewerCamera::getInstance()->getAtAxis(); 4622 at_axis = LLViewerCamera::getInstance()->getAtAxis();
@@ -4669,7 +4683,7 @@ void LLAgent::lookAtLastChat()
4669 if (chatter->isAvatar()) 4683 if (chatter->isAvatar())
4670 { 4684 {
4671 LLVOAvatar *chatter_av = (LLVOAvatar*)chatter; 4685 LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
4672 if (!mAvatarObject.isNull() && chatter_av->mHeadp) 4686 if (mAvatarObject.notNull() && chatter_av->mHeadp)
4673 { 4687 {
4674 delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition(); 4688 delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
4675 } 4689 }
@@ -4750,7 +4764,7 @@ void LLAgent::setStartPosition( U32 location_id )
4750 LLVector3 agent_pos = getPositionAgent(); 4764 LLVector3 agent_pos = getPositionAgent();
4751 LLVector3 agent_look_at = mFrameAgent.getAtAxis(); 4765 LLVector3 agent_look_at = mFrameAgent.getAtAxis();
4752 4766
4753 if (mAvatarObject) 4767 if (mAvatarObject.notNull())
4754 { 4768 {
4755 // the z height is at the agent's feet 4769 // the z height is at the agent's feet
4756 agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ]; 4770 agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ];
@@ -4874,70 +4888,165 @@ void LLAgent::onAnimStop(const LLUUID& id)
4874 4888
4875BOOL LLAgent::isGodlike() const 4889BOOL LLAgent::isGodlike() const
4876{ 4890{
4877#ifdef HACKED_GODLIKE_VIEWER 4891 return mAgentAccess.isGodlike();
4878 return TRUE;
4879#else
4880 if(mAdminOverride) return TRUE;
4881 return mGodLevel > GOD_NOT;
4882#endif
4883} 4892}
4884 4893
4885U8 LLAgent::getGodLevel() const 4894U8 LLAgent::getGodLevel() const
4886{ 4895{
4887#ifdef HACKED_GODLIKE_VIEWER 4896 return mAgentAccess.getGodLevel();
4888 return GOD_MAINTENANCE;
4889#else
4890 if(mAdminOverride) return GOD_FULL;
4891 return mGodLevel;
4892#endif
4893} 4897}
4894 4898
4895bool LLAgent::isTeen() const 4899bool LLAgent::wantsPGOnly() const
4896{ 4900{
4897 return mAccess < SIM_ACCESS_MATURE; 4901 return mAgentAccess.wantsPGOnly();
4898} 4902}
4899 4903
4900void LLAgent::setTeen(bool teen) 4904bool LLAgent::canAccessMature() const
4901{ 4905{
4902 if (teen) 4906 return mAgentAccess.canAccessMature();
4903 { 4907}
4904 mAccess = SIM_ACCESS_PG; 4908
4905 } 4909bool LLAgent::canAccessAdult() const
4906 else 4910{
4911 return mAgentAccess.canAccessAdult();
4912}
4913
4914bool LLAgent::canAccessMaturityInRegion( U64 region_handle ) const
4915{
4916 LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle( region_handle );
4917 if( regionp )
4907 { 4918 {
4908 mAccess = SIM_ACCESS_MATURE; 4919 switch( regionp->getSimAccess() )
4920 {
4921 case SIM_ACCESS_MATURE:
4922 if( !canAccessMature() )
4923 return false;
4924 break;
4925 case SIM_ACCESS_ADULT:
4926 if( !canAccessAdult() )
4927 return false;
4928 break;
4929 default:
4930 // Oh, go on and hear the silly noises.
4931 break;
4932 }
4909 } 4933 }
4934
4935 return true;
4936}
4937
4938bool LLAgent::canAccessMaturityAtGlobal( LLVector3d pos_global ) const
4939{
4940 U64 region_handle = to_region_handle_global( pos_global.mdV[0], pos_global.mdV[1] );
4941 return canAccessMaturityInRegion( region_handle );
4942}
4943
4944bool LLAgent::prefersPG() const
4945{
4946 return mAgentAccess.prefersPG();
4947}
4948
4949bool LLAgent::prefersMature() const
4950{
4951 return mAgentAccess.prefersMature();
4952}
4953
4954bool LLAgent::prefersAdult() const
4955{
4956 return mAgentAccess.prefersAdult();
4957}
4958
4959bool LLAgent::isTeen() const
4960{
4961 return mAgentAccess.isTeen();
4962}
4963
4964bool LLAgent::isMature() const
4965{
4966 return mAgentAccess.isMature();
4967}
4968
4969bool LLAgent::isAdult() const
4970{
4971 return mAgentAccess.isAdult();
4972}
4973
4974void LLAgent::setTeen(bool teen)
4975{
4976 mAgentAccess.setTeen(teen);
4910} 4977}
4911 4978
4912//static 4979//static
4913void LLAgent::convertTextToMaturity(char text) // HACK: remove when based on 1.23 4980int LLAgent::convertTextToMaturity(char text)
4914{ 4981{
4915 if ('A' == text) 4982 return LLAgentAccess::convertTextToMaturity(text);
4916 { 4983}
4917 mAccess = SIM_ACCESS_ADULT; 4984
4918 //return SIM_ACCESS_ADULT; 4985bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)
4919 } 4986{
4920 else if ('M'== text) 4987 // Update agent access preference on the server
4921 { 4988 std::string url = getRegion()->getCapability("UpdateAgentInformation");
4922 mAccess = SIM_ACCESS_MATURE; 4989 if (!url.empty())
4923 //return SIM_ACCESS_MATURE;
4924 }
4925 else if ('P'== text)
4926 {
4927 mAccess = SIM_ACCESS_PG;
4928 //return SIM_ACCESS_PG;
4929 }
4930 else
4931 { 4990 {
4932 mAccess = SIM_ACCESS_MIN; 4991 // Set new access preference
4933 //return SIM_ACCESS_MIN; 4992 LLSD access_prefs = LLSD::emptyMap();
4993 if (preferredMaturity == SIM_ACCESS_PG)
4994 {
4995 access_prefs["max"] = "PG";
4996 }
4997 else if (preferredMaturity == SIM_ACCESS_MATURE)
4998 {
4999 access_prefs["max"] = "M";
5000 }
5001 if (preferredMaturity == SIM_ACCESS_ADULT)
5002 {
5003 access_prefs["max"] = "A";
5004 }
5005
5006 LLSD body = LLSD::emptyMap();
5007 body["access_prefs"] = access_prefs;
5008 llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: "
5009 << url << llendl;
5010 LLHTTPClient::post(url, body, new LLHTTPClient::Responder()); // Ignore response
5011 return true;
4934 } 5012 }
4935 gSavedSettings.setU32("PreferredMaturity", mAccess); 5013 return false;
5014}
5015
5016BOOL LLAgent::getAdminOverride() const
5017{
5018 return mAgentAccess.getAdminOverride();
5019}
5020
5021void LLAgent::setMaturity(char text)
5022{
5023 mAgentAccess.setMaturity(text);
5024}
5025
5026void LLAgent::setAdminOverride(BOOL b)
5027{
5028 mAgentAccess.setAdminOverride(b);
5029}
5030
5031void LLAgent::setGodLevel(U8 god_level)
5032{
5033 mAgentAccess.setGodLevel(god_level);
5034}
5035
5036void LLAgent::setAOTransition()
5037{
5038 mAgentAccess.setTransition();
4936} 5039}
4937 5040
5041const LLAgentAccess& LLAgent::getAgentAccess()
5042{
5043 return mAgentAccess;
5044}
5045
5046
4938void LLAgent::buildFullname(std::string& name) const 5047void LLAgent::buildFullname(std::string& name) const
4939{ 5048{
4940 if (mAvatarObject) 5049 if (mAvatarObject.notNull())
4941 { 5050 {
4942 name = mAvatarObject->getFullname(); 5051 name = mAvatarObject->getFullname();
4943 } 5052 }
@@ -4955,7 +5064,7 @@ void LLAgent::buildFullnameAndTitle(std::string& name) const
4955 name.erase(0, name.length()); 5064 name.erase(0, name.length());
4956 } 5065 }
4957 5066
4958 if (mAvatarObject) 5067 if (mAvatarObject.notNull())
4959 { 5068 {
4960 name += mAvatarObject->getFullname(); 5069 name += mAvatarObject->getFullname();
4961 } 5070 }
@@ -5318,7 +5427,7 @@ void LLAgent::getName(std::string& name)
5318{ 5427{
5319 name.clear(); 5428 name.clear();
5320 5429
5321 if (mAvatarObject) 5430 if (mAvatarObject.notNull())
5322 { 5431 {
5323 LLNameValue *first_nv = mAvatarObject->getNVPair("FirstName"); 5432 LLNameValue *first_nv = mAvatarObject->getNVPair("FirstName");
5324 LLNameValue *last_nv = mAvatarObject->getNVPair("LastName"); 5433 LLNameValue *last_nv = mAvatarObject->getNVPair("LastName");
@@ -5828,11 +5937,11 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
5828 mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block); 5937 mesgsys->getU8Fast(_PREHASH_WearableData, _PREHASH_TextureIndex, texture_index, texture_block);
5829 5938
5830 if (texture_id.notNull() 5939 if (texture_id.notNull()
5831 && (S32)texture_index < BAKED_TEXTURE_COUNT 5940 && (S32)texture_index < BAKED_NUM_INDICES
5832 && gAgent.mActiveCacheQueries[ texture_index ] == query_id) 5941 && gAgent.mActiveCacheQueries[ texture_index ] == query_id)
5833 { 5942 {
5834 //llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl; 5943 //llinfos << "Received cached texture " << (U32)texture_index << ": " << texture_id << llendl;
5835 avatarp->setCachedBakedTexture((LLVOAvatar::ETextureIndex)LLVOAvatar::sBakedTextureIndices[texture_index], texture_id); 5944 avatarp->setCachedBakedTexture(getTextureIndex((EBakedTextureIndex)texture_index), texture_id);
5836 //avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id ); 5945 //avatarp->setTETexture( LLVOAvatar::sBakedTextureIndices[texture_index], texture_id );
5837 gAgent.mActiveCacheQueries[ texture_index ] = 0; 5946 gAgent.mActiveCacheQueries[ texture_index ] = 0;
5838 num_results++; 5947 num_results++;
@@ -5922,13 +6031,24 @@ bool LLAgent::teleportCore(bool is_local)
5922 return false; 6031 return false;
5923 } 6032 }
5924 6033
5925 // Cease sitting on the current object, if any. 6034#if 0
5926 LLVOAvatar* avatarp = gAgent.getAvatarObject(); 6035 // This should not exist. It has been added, removed, added, and now removed again.
5927 if (avatarp) 6036 // This change needs to come from the simulator. Otherwise, the agent ends up out of
5928 avatarp->getOffObject(); 6037 // sync with other viewers. Discuss in DEV-14145/VWR-6744 before reenabling.
5929 6038
5930 // Stop all animations before actual teleporting 6039 // Stop all animation before actual teleporting
5931 stopCurrentAnimations(); 6040 LLVOAvatar* avatarp = gAgent.getAvatarObject();
6041 if (avatarp)
6042 {
6043 for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin();
6044 anim_it != avatarp->mPlayingAnimations.end();
6045 ++anim_it)
6046 {
6047 avatarp->stopMotion(anim_it->first);
6048 }
6049 avatarp->processAnimationStateChanges();
6050 }
6051#endif
5932 6052
5933 // Don't call LLFirstUse::useTeleport because we don't know 6053 // Don't call LLFirstUse::useTeleport because we don't know
5934 // yet if the teleport will succeed. Look in 6054 // yet if the teleport will succeed. Look in
@@ -6121,17 +6241,19 @@ void LLAgent::teleportHome()
6121 6241
6122void LLAgent::teleportHomeConfirm() 6242void LLAgent::teleportHomeConfirm()
6123{ 6243{
6124 gViewerWindow->alertXml("ConfirmTeleportHome", LLAgent::teleportHomeCallback, (void *)this); 6244 LLNotifications::instance().add("ConfirmTeleportHome", LLSD(), LLSD(), &LLAgent::teleportHomeCallback);
6125} 6245}
6126 6246
6127// static 6247// static
6128void LLAgent::teleportHomeCallback(S32 option, void *userdata) 6248bool LLAgent::teleportHomeCallback( const LLSD& notification, const LLSD& response )
6129{ 6249{
6250 S32 option = LLNotification::getSelectedOption(notification, response);
6130 if( option == 0 ) 6251 if( option == 0 )
6131 { 6252 {
6132 // They confirmed it. Here we go! 6253 // They confirmed it. Here we go!
6133 ((LLAgent *) userdata)->teleportHome(); 6254 gAgent.teleportHome();
6134 } 6255 }
6256 return false;
6135} 6257}
6136 6258
6137 6259
@@ -6464,6 +6586,8 @@ void LLAgent::saveWearable( EWearableType type, BOOL send_update )
6464 addWearableToAgentInventory(cb, new_wearable); 6586 addWearableToAgentInventory(cb, new_wearable);
6465 return; 6587 return;
6466 } 6588 }
6589
6590 getAvatarObject()->wearableUpdated( type );
6467 6591
6468 if( send_update ) 6592 if( send_update )
6469 { 6593 {
@@ -6886,7 +7010,7 @@ void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdat
6886void LLAgent::recoverMissingWearable( EWearableType type ) 7010void LLAgent::recoverMissingWearable( EWearableType type )
6887{ 7011{
6888 // Try to recover by replacing missing wearable with a new one. 7012 // Try to recover by replacing missing wearable with a new one.
6889 LLNotifyBox::showXml("ReplacedMissingWearable"); 7013 LLNotifications::instance().add("ReplacedMissingWearable");
6890 lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl; 7014 lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded. Replaced inventory item with default wearable." << llendl;
6891 LLWearable* new_wearable = gWearableList.createNewWearable(type); 7015 LLWearable* new_wearable = gWearableList.createNewWearable(type);
6892 7016
@@ -7187,11 +7311,8 @@ void LLAgent::sendAgentSetAppearance()
7187 return; 7311 return;
7188 } 7312 }
7189 7313
7190 llinfos << "TAT: Sent AgentSetAppearance: " << 7314
7191 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "HEAD " : "head " ) << 7315 llinfos << "TAT: Sent AgentSetAppearance: " << mAvatarObject->getBakedStatusForPrintout() << llendl;
7192 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "UPPER " : "upper " ) <<
7193 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "LOWER " : "lower " ) <<
7194 (( mAvatarObject->getTEImage( LLVOAvatar::TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "EYES" : "eyes" ) << llendl;
7195 //dumpAvatarTEs( "sendAgentSetAppearance()" ); 7316 //dumpAvatarTEs( "sendAgentSetAppearance()" );
7196 7317
7197 LLMessageSystem* msg = gMessageSystem; 7318 LLMessageSystem* msg = gMessageSystem;
@@ -7205,7 +7326,7 @@ void LLAgent::sendAgentSetAppearance()
7205 // NOTE -- when we start correcting all of the other Havok geometry 7326 // NOTE -- when we start correcting all of the other Havok geometry
7206 // to compensate for the COLLISION_TOLERANCE ugliness we will have 7327 // to compensate for the COLLISION_TOLERANCE ugliness we will have
7207 // to tweak this number again 7328 // to tweak this number again
7208 LLVector3 body_size = mAvatarObject->mBodySize; 7329 const LLVector3 body_size = mAvatarObject->mBodySize;
7209 msg->addVector3Fast(_PREHASH_Size, body_size); 7330 msg->addVector3Fast(_PREHASH_Size, body_size);
7210 7331
7211 // To guard against out of order packets 7332 // To guard against out of order packets
@@ -7217,19 +7338,18 @@ void LLAgent::sendAgentSetAppearance()
7217 // KLW - TAT this will probably need to check the local queue. 7338 // KLW - TAT this will probably need to check the local queue.
7218 BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded; 7339 BOOL textures_current = !mAvatarObject->hasPendingBakedUploads() && mWearablesLoaded;
7219 7340
7220 S32 baked_texture_index; 7341 for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
7221 for( baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++ )
7222 { 7342 {
7223 S32 tex_index = LLVOAvatar::sBakedTextureIndices[baked_texture_index]; 7343 const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index);
7224 7344
7225 // if we're not wearing a skirt, we don't need the texture to be baked 7345 // if we're not wearing a skirt, we don't need the texture to be baked
7226 if (tex_index == LLVOAvatar::TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT)) 7346 if (texture_index == TEX_SKIRT_BAKED && !mAvatarObject->isWearingWearableType(WT_SKIRT))
7227 { 7347 {
7228 continue; 7348 continue;
7229 } 7349 }
7230 7350
7231 // IMG_DEFAULT_AVATAR means not baked 7351 // IMG_DEFAULT_AVATAR means not baked
7232 if (mAvatarObject->getTEImage( tex_index)->getID() == IMG_DEFAULT_AVATAR) 7352 if (!mAvatarObject->isTextureDefined(texture_index))
7233 { 7353 {
7234 textures_current = FALSE; 7354 textures_current = FALSE;
7235 break; 7355 break;
@@ -7240,50 +7360,56 @@ void LLAgent::sendAgentSetAppearance()
7240 if (textures_current) 7360 if (textures_current)
7241 { 7361 {
7242 llinfos << "TAT: Sending cached texture data" << llendl; 7362 llinfos << "TAT: Sending cached texture data" << llendl;
7243 for (baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++) 7363 for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
7244 { 7364 {
7365 const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index);
7245 LLUUID hash; 7366 LLUUID hash;
7246 7367 for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++)
7247 for( S32 wearable_num = 0; wearable_num < MAX_WEARABLES_PER_LAYERSET; wearable_num++ )
7248 { 7368 {
7249 EWearableType wearable_type = WEARABLE_BAKE_TEXTURE_MAP[baked_texture_index][wearable_num]; 7369 // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num];
7250 7370 const EWearableType wearable_type = wearable_dict->mWearablesVec[i];
7251 LLWearable* wearable = getWearable( wearable_type ); 7371 const LLWearable* wearable = getWearable(wearable_type);
7252 if (wearable) 7372 if (wearable)
7253 { 7373 {
7254 hash ^= wearable->getID(); 7374 hash ^= wearable->getID();
7255 } 7375 }
7256 } 7376 }
7257
7258 if (hash.notNull()) 7377 if (hash.notNull())
7259 { 7378 {
7260 hash ^= BAKED_TEXTURE_HASH[baked_texture_index]; 7379 hash ^= wearable_dict->mHashID;
7261 } 7380 }
7262 7381
7263 S32 tex_index = LLVOAvatar::sBakedTextureIndices[baked_texture_index]; 7382 const ETextureIndex texture_index = getTextureIndex((EBakedTextureIndex)baked_index);
7264 7383
7265 msg->nextBlockFast(_PREHASH_WearableData); 7384 msg->nextBlockFast(_PREHASH_WearableData);
7266 msg->addUUIDFast(_PREHASH_CacheID, hash); 7385 msg->addUUIDFast(_PREHASH_CacheID, hash);
7267 msg->addU8Fast(_PREHASH_TextureIndex, (U8)tex_index); 7386 msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
7268 } 7387 }
7388 msg->nextBlockFast(_PREHASH_ObjectData);
7389 mAvatarObject->packTEMessage( gMessageSystem );
7390 }
7391 else
7392 {
7393 // If the textures aren't baked, send NULL for texture IDs
7394 // This means the baked texture IDs on the server will be untouched.
7395 // Once all textures are baked, another AvatarAppearance message will be sent to update the TEs
7396 msg->nextBlockFast(_PREHASH_ObjectData);
7397 gMessageSystem->addBinaryDataFast(_PREHASH_TextureEntry, NULL, 0);
7269 } 7398 }
7270 7399
7271 msg->nextBlockFast(_PREHASH_ObjectData);
7272 mAvatarObject->packTEMessage( gMessageSystem );
7273 7400
7274 S32 transmitted_params = 0; 7401 S32 transmitted_params = 0;
7275 for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam(); 7402 for (LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarObject->getFirstVisualParam();
7276 param; 7403 param;
7277 param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam()) 7404 param = (LLViewerVisualParam*)mAvatarObject->getNextVisualParam())
7278 { 7405 {
7279 F32 param_value = param->getWeight();
7280
7281 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) 7406 if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE)
7282 { 7407 {
7283 msg->nextBlockFast(_PREHASH_VisualParam ); 7408 msg->nextBlockFast(_PREHASH_VisualParam );
7284 7409
7285 // We don't send the param ids. Instead, we assume that the receiver has the same params in the same sequence. 7410 // We don't send the param ids. Instead, we assume that the receiver has the same params in the same sequence.
7286 U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight()); 7411 const F32 param_value = param->getWeight();
7412 const U8 new_weight = F32_to_U8(param_value, param->getMinWeight(), param->getMaxWeight());
7287 msg->addU8Fast(_PREHASH_ParamValue, new_weight ); 7413 msg->addU8Fast(_PREHASH_ParamValue, new_weight );
7288 transmitted_params++; 7414 transmitted_params++;
7289 } 7415 }
@@ -7324,8 +7450,10 @@ void LLAgent::removeWearable( EWearableType type )
7324 { 7450 {
7325 if( old_wearable->isDirty() ) 7451 if( old_wearable->isDirty() )
7326 { 7452 {
7453 LLSD payload;
7454 payload["wearable_type"] = (S32)type;
7327 // Bring up view-modal dialog: Save changes? Yes, No, Cancel 7455 // Bring up view-modal dialog: Save changes? Yes, No, Cancel
7328 gViewerWindow->alertXml("WearableSave", LLAgent::onRemoveWearableDialog, (void*)type ); 7456 LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgent::onRemoveWearableDialog);
7329 return; 7457 return;
7330 } 7458 }
7331 else 7459 else
@@ -7336,9 +7464,10 @@ void LLAgent::removeWearable( EWearableType type )
7336} 7464}
7337 7465
7338// static 7466// static
7339void LLAgent::onRemoveWearableDialog( S32 option, void* userdata ) 7467bool LLAgent::onRemoveWearableDialog(const LLSD& notification, const LLSD& response )
7340{ 7468{
7341 EWearableType type = (EWearableType)(intptr_t)userdata; 7469 S32 option = LLNotification::getSelectedOption(notification, response);
7470 EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
7342 switch( option ) 7471 switch( option )
7343 { 7472 {
7344 case 0: // "Save" 7473 case 0: // "Save"
@@ -7357,6 +7486,7 @@ void LLAgent::onRemoveWearableDialog( S32 option, void* userdata )
7357 llassert(0); 7486 llassert(0);
7358 break; 7487 break;
7359 } 7488 }
7489 return false;
7360} 7490}
7361 7491
7362// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal. 7492// Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
@@ -7527,8 +7657,6 @@ void LLAgent::setWearableOutfit(
7527 wearables[i]->writeToAvatar( TRUE ); 7657 wearables[i]->writeToAvatar( TRUE );
7528 } 7658 }
7529 7659
7530 LLFloaterCustomize::setCurrentWearableType( WT_SHAPE );
7531
7532 // Start rendering & update the server 7660 // Start rendering & update the server
7533 mWearablesLoaded = TRUE; 7661 mWearablesLoaded = TRUE;
7534 sendAgentWearablesUpdate(); 7662 sendAgentWearablesUpdate();
@@ -7566,8 +7694,9 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
7566 if( old_wearable->isDirty() ) 7694 if( old_wearable->isDirty() )
7567 { 7695 {
7568 // Bring up modal dialog: Save changes? Yes, No, Cancel 7696 // Bring up modal dialog: Save changes? Yes, No, Cancel
7569 gViewerWindow->alertXml( "WearableSave", LLAgent::onSetWearableDialog, 7697 LLSD payload;
7570 new LLSetWearableData( new_item->getUUID(), new_wearable )); 7698 payload["item_id"] = new_item->getUUID();
7699 LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgent::onSetWearableDialog, _1, _2, new_wearable));
7571 return; 7700 return;
7572 } 7701 }
7573 } 7702 }
@@ -7576,25 +7705,25 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
7576} 7705}
7577 7706
7578// static 7707// static
7579void LLAgent::onSetWearableDialog( S32 option, void* userdata ) 7708bool LLAgent::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable )
7580{ 7709{
7581 LLSetWearableData* data = (LLSetWearableData*)userdata; 7710 S32 option = LLNotification::getSelectedOption(notification, response);
7582 LLInventoryItem* new_item = gInventory.getItem( data->mNewItemID ); 7711 LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID());
7583 if( !new_item ) 7712 if( !new_item )
7584 { 7713 {
7585 delete data; 7714 delete wearable;
7586 return; 7715 return false;
7587 } 7716 }
7588 7717
7589 switch( option ) 7718 switch( option )
7590 { 7719 {
7591 case 0: // "Save" 7720 case 0: // "Save"
7592 gAgent.saveWearable( data->mNewWearable->getType() ); 7721 gAgent.saveWearable( wearable->getType() );
7593 gAgent.setWearableFinal( new_item, data->mNewWearable ); 7722 gAgent.setWearableFinal( new_item, wearable );
7594 break; 7723 break;
7595 7724
7596 case 1: // "Don't Save" 7725 case 1: // "Don't Save"
7597 gAgent.setWearableFinal( new_item, data->mNewWearable ); 7726 gAgent.setWearableFinal( new_item, wearable );
7598 break; 7727 break;
7599 7728
7600 case 2: // "Cancel" 7729 case 2: // "Cancel"
@@ -7605,7 +7734,8 @@ void LLAgent::onSetWearableDialog( S32 option, void* userdata )
7605 break; 7734 break;
7606 } 7735 }
7607 7736
7608 delete data; 7737 delete wearable;
7738 return false;
7609} 7739}
7610 7740
7611// Called from setWearable() and onSetWearableDialog() to actually set the wearable. 7741// Called from setWearable() and onSetWearableDialog() to actually set the wearable.
@@ -7657,14 +7787,15 @@ void LLAgent::queryWearableCache()
7657 gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID); 7787 gMessageSystem->addS32Fast(_PREHASH_SerialNum, mTextureCacheQueryID);
7658 7788
7659 S32 num_queries = 0; 7789 S32 num_queries = 0;
7660 for (S32 baked_texture_index = 0; baked_texture_index < BAKED_TEXTURE_COUNT; baked_texture_index++) 7790 for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
7661 { 7791 {
7792 const LLVOAvatarDictionary::WearableDictionaryEntry *wearable_dict = LLVOAvatarDictionary::getInstance()->getWearable((EBakedTextureIndex)baked_index);
7662 LLUUID hash; 7793 LLUUID hash;
7663 for (S32 wearable_num = 0; wearable_num < MAX_WEARABLES_PER_LAYERSET; wearable_num++) 7794 for (U8 i=0; i < wearable_dict->mWearablesVec.size(); i++)
7664 { 7795 {
7665 EWearableType wearable_type = WEARABLE_BAKE_TEXTURE_MAP[baked_texture_index][wearable_num]; 7796 // EWearableType wearable_type = gBakedWearableMap[baked_index][wearable_num];
7666 7797 const EWearableType wearable_type = wearable_dict->mWearablesVec[i];
7667 LLWearable* wearable = getWearable( wearable_type ); 7798 const LLWearable* wearable = getWearable(wearable_type);
7668 if (wearable) 7799 if (wearable)
7669 { 7800 {
7670 hash ^= wearable->getID(); 7801 hash ^= wearable->getID();
@@ -7672,17 +7803,17 @@ void LLAgent::queryWearableCache()
7672 } 7803 }
7673 if (hash.notNull()) 7804 if (hash.notNull())
7674 { 7805 {
7675 hash ^= BAKED_TEXTURE_HASH[baked_texture_index]; 7806 hash ^= wearable_dict->mHashID;
7676 num_queries++; 7807 num_queries++;
7677 // *NOTE: make sure at least one request gets packed 7808 // *NOTE: make sure at least one request gets packed
7678 7809
7679 //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_texture_index << llendl; 7810 //llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
7680 gMessageSystem->nextBlockFast(_PREHASH_WearableData); 7811 gMessageSystem->nextBlockFast(_PREHASH_WearableData);
7681 gMessageSystem->addUUIDFast(_PREHASH_ID, hash); 7812 gMessageSystem->addUUIDFast(_PREHASH_ID, hash);
7682 gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_texture_index); 7813 gMessageSystem->addU8Fast(_PREHASH_TextureIndex, (U8)baked_index);
7683 } 7814 }
7684 7815
7685 mActiveCacheQueries[ baked_texture_index ] = mTextureCacheQueryID; 7816 mActiveCacheQueries[ baked_index ] = mTextureCacheQueryID;
7686 } 7817 }
7687 7818
7688 llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl; 7819 llinfos << "Requesting texture cache entry for " << num_queries << " baked textures" << llendl;
@@ -7708,18 +7839,19 @@ void LLAgent::userRemoveWearable( void* userdata )
7708// static 7839// static
7709void LLAgent::userRemoveAllClothesConfirm() 7840void LLAgent::userRemoveAllClothesConfirm()
7710{ 7841{
7711 gViewerWindow->alertXml("ConfirmRemoveAllClothes", 7842 LLNotifications::instance().add("ConfirmRemoveAllClothes", LLSD(), LLSD(), LLAgent::userRemoveAllClothesCallback);
7712 LLAgent::userRemoveAllClothesCallback, NULL);
7713} 7843}
7714 7844
7715// static 7845// static
7716void LLAgent::userRemoveAllClothesCallback(S32 option, void *userdata) 7846bool LLAgent::userRemoveAllClothesCallback( const LLSD& notification, const LLSD& response )
7717{ 7847{
7848 S32 option = LLNotification::getSelectedOption(notification, response);
7718 if( option == 0 ) 7849 if( option == 0 )
7719 { 7850 {
7720 // They confirmed it. Here we go! 7851 // They confirmed it. Here we go!
7721 LLAgent::userRemoveAllClothes(NULL); 7852 LLAgent::userRemoveAllClothes(NULL);
7722 } 7853 }
7854 return false;
7723} 7855}
7724 7856
7725 7857
@@ -7728,7 +7860,7 @@ void LLAgent::userRemoveAllClothes( void* userdata )
7728 // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty. 7860 // We have to do this up front to avoid having to deal with the case of multiple wearables being dirty.
7729 if( gFloaterCustomize ) 7861 if( gFloaterCustomize )
7730 { 7862 {
7731 gFloaterCustomize->askToSaveAllIfDirty( LLAgent::userRemoveAllClothesStep2, NULL ); 7863 gFloaterCustomize->askToSaveIfDirty( LLAgent::userRemoveAllClothesStep2, NULL );
7732 } 7864 }
7733 else 7865 else
7734 { 7866 {