llagent.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:183k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llagent.cpp
  3.  * @brief LLAgent class implementation
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  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
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llagent.h" 
  34. #include "pipeline.h"
  35. #include "llagentlistener.h"
  36. #include "llagentwearables.h"
  37. #include "llagentui.h"
  38. #include "llanimationstates.h"
  39. #include "llbottomtray.h"
  40. #include "llcallingcard.h"
  41. #include "llchannelmanager.h"
  42. #include "llconsole.h"
  43. //#include "llfirstuse.h"
  44. #include "llfloatercamera.h"
  45. #include "llfloatercustomize.h"
  46. #include "llfloaterreg.h"
  47. #include "llfloatertools.h"
  48. #include "llgroupactions.h"
  49. #include "llgroupmgr.h"
  50. #include "llhomelocationresponder.h"
  51. #include "llhudmanager.h"
  52. #include "lljoystickbutton.h"
  53. #include "llmorphview.h"
  54. #include "llmoveview.h"
  55. #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
  56. #include "llnearbychatbar.h"
  57. #include "llnotificationsutil.h"
  58. #include "llparcel.h"
  59. #include "llsdutil.h"
  60. #include "llsidetray.h"
  61. #include "llsky.h"
  62. #include "llsmoothstep.h"
  63. #include "llstatusbar.h"
  64. #include "llteleportflags.h"
  65. #include "lltool.h"
  66. #include "lltoolmgr.h"
  67. #include "lltrans.h"
  68. #include "llviewercontrol.h"
  69. #include "llviewerdisplay.h"
  70. #include "llviewerjoystick.h"
  71. #include "llviewermediafocus.h"
  72. #include "llviewerobjectlist.h"
  73. #include "llviewerparcelmgr.h"
  74. #include "llviewerstats.h"
  75. #include "llvoavatarself.h"
  76. #include "llwindow.h"
  77. #include "llworld.h"
  78. #include "llworldmap.h"
  79. using namespace LLVOAvatarDefines;
  80. extern LLMenuBarGL* gMenuBarView;
  81. const BOOL ANIMATE = TRUE;
  82. const U8 AGENT_STATE_TYPING = 0x04;
  83. const U8 AGENT_STATE_EDITING =  0x10;
  84. //drone wandering constants
  85. const F32 MAX_WANDER_TIME = 20.f; // seconds
  86. const F32 MAX_HEADING_HALF_ERROR = 0.2f; // radians
  87. const F32 WANDER_MAX_SLEW_RATE = 2.f * DEG_TO_RAD; // radians / frame
  88. const F32 WANDER_TARGET_MIN_DISTANCE = 10.f; // meters
  89. // Autopilot constants
  90. const F32 AUTOPILOT_HEADING_HALF_ERROR = 10.f * DEG_TO_RAD; // radians
  91. const F32 AUTOPILOT_MAX_SLEW_RATE = 1.f * DEG_TO_RAD; // radians / frame
  92. const F32 AUTOPILOT_STOP_DISTANCE = 2.f; // meters
  93. const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f; // meters
  94. const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f; // meters
  95. const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f; // seconds
  96. // face editing constants
  97. const LLVector3d FACE_EDIT_CAMERA_OFFSET(0.4f, -0.05f, 0.07f);
  98. const LLVector3d FACE_EDIT_TARGET_OFFSET(0.f, 0.f, 0.05f);
  99. // Mousewheel camera zoom
  100. const F32 MIN_ZOOM_FRACTION = 0.25f;
  101. const F32 INITIAL_ZOOM_FRACTION = 1.f;
  102. const F32 MAX_ZOOM_FRACTION = 8.f;
  103. const F32 METERS_PER_WHEEL_CLICK = 1.f;
  104. const F32 MAX_TIME_DELTA = 1.f;
  105. const F32 CAMERA_ZOOM_HALF_LIFE = 0.07f; // seconds
  106. const F32 FOV_ZOOM_HALF_LIFE = 0.07f; // seconds
  107. const F32 CAMERA_FOCUS_HALF_LIFE = 0.f;//0.02f;
  108. const F32 CAMERA_LAG_HALF_LIFE = 0.25f;
  109. const F32 MIN_CAMERA_LAG = 0.5f;
  110. const F32 MAX_CAMERA_LAG = 5.f;
  111. const F32 CAMERA_COLLIDE_EPSILON = 0.1f;
  112. const F32 MIN_CAMERA_DISTANCE = 0.1f;
  113. const F32 AVATAR_ZOOM_MIN_X_FACTOR = 0.55f;
  114. const F32 AVATAR_ZOOM_MIN_Y_FACTOR = 0.7f;
  115. const F32 AVATAR_ZOOM_MIN_Z_FACTOR = 1.15f;
  116. const F32 MAX_CAMERA_DISTANCE_FROM_AGENT = 50.f;
  117. const F32 MAX_CAMERA_SMOOTH_DISTANCE = 50.0f;
  118. const F32 HEAD_BUFFER_SIZE = 0.3f;
  119. const F32 CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP = 0.2f;
  120. const F32 LAND_MIN_ZOOM = 0.15f;
  121. const F32 AVATAR_MIN_ZOOM = 0.5f;
  122. const F32 OBJECT_MIN_ZOOM = 0.02f;
  123. const F32 APPEARANCE_MIN_ZOOM = 0.39f;
  124. const F32 APPEARANCE_MAX_ZOOM = 8.f;
  125. // fidget constants
  126. const F32 MIN_FIDGET_TIME = 8.f; // seconds
  127. const F32 MAX_FIDGET_TIME = 20.f; // seconds
  128. const S32 MAX_NUM_CHAT_POSITIONS = 10;
  129. const F32 GROUND_TO_AIR_CAMERA_TRANSITION_TIME = 0.5f;
  130. const F32 GROUND_TO_AIR_CAMERA_TRANSITION_START_TIME = 0.5f;
  131. const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
  132. const F32 MAX_FOCUS_OFFSET = 20.f;
  133. const F32 OBJECT_EXTENTS_PADDING = 0.5f;
  134. const F32 MIN_RADIUS_ALPHA_SIZZLE = 0.5f;
  135. const F64 CHAT_AGE_FAST_RATE = 3.0;
  136. // The agent instance.
  137. LLAgent gAgent;
  138. //--------------------------------------------------------------------
  139. // Statics
  140. //
  141. const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
  142. std::map<std::string, std::string> LLAgent::sTeleportErrorMessages;
  143. std::map<std::string, std::string> LLAgent::sTeleportProgressMessages;
  144. class LLAgentFriendObserver : public LLFriendObserver
  145. {
  146. public:
  147. LLAgentFriendObserver() {}
  148. virtual ~LLAgentFriendObserver() {}
  149. virtual void changed(U32 mask);
  150. };
  151. void LLAgentFriendObserver::changed(U32 mask)
  152. {
  153. // if there's a change we're interested in.
  154. if((mask & (LLFriendObserver::POWERS)) != 0)
  155. {
  156. gAgent.friendsChanged();
  157. }
  158. }
  159. bool handleSlowMotionAnimation(const LLSD& newvalue)
  160. {
  161. if (newvalue.asBoolean())
  162. {
  163. gAgent.getAvatarObject()->setAnimTimeFactor(0.2f);
  164. }
  165. else
  166. {
  167. gAgent.getAvatarObject()->setAnimTimeFactor(1.0f);
  168. }
  169. return true;
  170. }
  171. // ************************************************************
  172. // Enabled this definition to compile a 'hacked' viewer that
  173. // locally believes the end user has godlike powers.
  174. // #define HACKED_GODLIKE_VIEWER
  175. // For a toggled version, see viewer.h for the
  176. // TOGGLE_HACKED_GODLIKE_VIEWER define, instead.
  177. // ************************************************************
  178. // Constructors and Destructors
  179. // JC - Please try to make this order match the order in the header
  180. // file.  Otherwise it's hard to find variables that aren't initialized.
  181. //-----------------------------------------------------------------------------
  182. // LLAgent()
  183. //-----------------------------------------------------------------------------
  184. LLAgent::LLAgent() :
  185. mDrawDistance( DEFAULT_FAR_PLANE ),
  186. mGroupPowers(0),
  187. mHideGroupTitle(FALSE),
  188. mGroupID(),
  189. mLookAt(NULL),
  190. mPointAt(NULL),
  191. mHUDTargetZoom(1.f),
  192. mHUDCurZoom(1.f),
  193. mInitialized(FALSE),
  194. mListener(),
  195. mForceMouselook(FALSE),
  196. mDoubleTapRunTimer(),
  197. mDoubleTapRunMode(DOUBLETAP_NONE),
  198. mbAlwaysRun(false),
  199. mbRunning(false),
  200. mAgentAccess(gSavedSettings),
  201. mTeleportState( TELEPORT_NONE ),
  202. mRegionp(NULL),
  203. mAgentOriginGlobal(),
  204. mPositionGlobal(),
  205. mDistanceTraveled(0.F),
  206. mLastPositionGlobal(LLVector3d::zero),
  207. mAvatarObject(NULL),
  208. mRenderState(0),
  209. mTypingTimer(),
  210. mCameraMode( CAMERA_MODE_THIRD_PERSON ),
  211. mLastCameraMode( CAMERA_MODE_THIRD_PERSON ),
  212. mViewsPushed(FALSE),
  213. mCameraPreset(CAMERA_PRESET_REAR_VIEW),
  214. mCustomAnim(FALSE),
  215. mShowAvatar(TRUE),
  216. mCameraAnimating( FALSE ),
  217. mAnimationCameraStartGlobal(),
  218. mAnimationFocusStartGlobal(),
  219. mAnimationTimer(),
  220. mAnimationDuration(0.33f),
  221. mCameraFOVZoomFactor(0.f),
  222. mCameraCurrentFOVZoomFactor(0.f),
  223. mCameraFocusOffset(),
  224. mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
  225. mCameraCollidePlane(),
  226. mCurrentCameraDistance(2.f), // meters, set in init()
  227. mTargetCameraDistance(2.f),
  228. mCameraZoomFraction(1.f), // deprecated
  229. mThirdPersonHeadOffset(0.f, 0.f, 1.f),
  230. mSitCameraEnabled(FALSE),
  231. mCameraSmoothingLastPositionGlobal(),
  232. mCameraSmoothingLastPositionAgent(),
  233. mCameraSmoothingStop(FALSE),
  234. mCameraUpVector(LLVector3::z_axis), // default is straight up
  235. mFocusOnAvatar(TRUE),
  236. mFocusGlobal(),
  237. mFocusTargetGlobal(),
  238. mFocusObject(NULL),
  239. mFocusObjectDist(0.f),
  240. mFocusObjectOffset(),
  241. mFocusDotRadius( 0.1f ), // meters
  242. mTrackFocusObject(TRUE),
  243. mUIOffset(0.f),
  244. mFrameAgent(),
  245. mIsBusy(FALSE),
  246. mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
  247. mWalkKey(0), // like AtKey, but causes less forward thrust
  248. mLeftKey(0),
  249. mUpKey(0),
  250. mYawKey(0.f),
  251. mPitchKey(0.f),
  252. mOrbitLeftKey(0.f),
  253. mOrbitRightKey(0.f),
  254. mOrbitUpKey(0.f),
  255. mOrbitDownKey(0.f),
  256. mOrbitInKey(0.f),
  257. mOrbitOutKey(0.f),
  258. mPanUpKey(0.f),
  259. mPanDownKey(0.f),
  260. mPanLeftKey(0.f),
  261. mPanRightKey(0.f),
  262. mPanInKey(0.f),
  263. mPanOutKey(0.f),
  264. mControlFlags(0x00000000),
  265. mbFlagsDirty(FALSE),
  266. mbFlagsNeedReset(FALSE),
  267. mbJump(FALSE),
  268. mAutoPilot(FALSE),
  269. mAutoPilotFlyOnStop(FALSE),
  270. mAutoPilotTargetGlobal(),
  271. mAutoPilotStopDistance(1.f),
  272. mAutoPilotUseRotation(FALSE),
  273. mAutoPilotTargetFacing(LLVector3::zero),
  274. mAutoPilotTargetDist(0.f),
  275. mAutoPilotNoProgressFrameCount(0),
  276. mAutoPilotRotationThreshold(0.f),
  277. mAutoPilotFinishedCallback(NULL),
  278. mAutoPilotCallbackData(NULL),
  279. mEffectColor(LLColor4(0.f, 1.f, 1.f, 1.f)),
  280. mHaveHomePosition(FALSE),
  281. mHomeRegionHandle( 0 ),
  282. mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f),
  283. mNextFidgetTime(0.f),
  284. mCurrentFidget(0),
  285. mFirstLogin(FALSE),
  286. mGenderChosen(FALSE),
  287. mAppearanceSerialNum(0)
  288. {
  289. for (U32 i = 0; i < TOTAL_CONTROLS; i++)
  290. {
  291. mControlsTakenCount[i] = 0;
  292. mControlsTakenPassedOnCount[i] = 0;
  293. }
  294. mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
  295. mListener.reset(new LLAgentListener(*this));
  296. }
  297. // Requires gSavedSettings to be initialized.
  298. //-----------------------------------------------------------------------------
  299. // init()
  300. //-----------------------------------------------------------------------------
  301. void LLAgent::init()
  302. {
  303. gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
  304. gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
  305. mDrawDistance = gSavedSettings.getF32("RenderFarClip");
  306. // *Note: this is where LLViewerCamera::getInstance() used to be constructed.
  307. LLViewerCamera::getInstance()->setView(DEFAULT_FIELD_OF_VIEW);
  308. // Leave at 0.1 meters until we have real near clip management
  309. LLViewerCamera::getInstance()->setNear(0.1f);
  310. LLViewerCamera::getInstance()->setFar(mDrawDistance); // if you want to change camera settings, do so in camera.h
  311. LLViewerCamera::getInstance()->setAspect( gViewerWindow->getWorldViewAspectRatio() ); // default, overridden in LLViewerWindow::reshape
  312. LLViewerCamera::getInstance()->setViewHeightInPixels(768); // default, overridden in LLViewerWindow::reshape
  313. setFlying( gSavedSettings.getBOOL("FlyingAtExit") );
  314. mCameraFocusOffsetTarget = LLVector4(gSavedSettings.getVector3("CameraOffsetBuild"));
  315. mCameraPreset = (ECameraPreset) gSavedSettings.getU32("CameraPreset");
  316. mCameraOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3("CameraOffsetRearView");
  317. mCameraOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3("CameraOffsetFrontView");
  318. mCameraOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3("CameraOffsetGroupView");
  319. mFocusOffsetInitial[CAMERA_PRESET_REAR_VIEW] = gSavedSettings.getVector3d("FocusOffsetRearView");
  320. mFocusOffsetInitial[CAMERA_PRESET_FRONT_VIEW] = gSavedSettings.getVector3d("FocusOffsetFrontView");
  321. mFocusOffsetInitial[CAMERA_PRESET_GROUP_VIEW] = gSavedSettings.getVector3d("FocusOffsetGroupView");
  322. mCameraCollidePlane.clearVec();
  323. mCurrentCameraDistance = getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale");
  324. mTargetCameraDistance = mCurrentCameraDistance;
  325. mCameraZoomFraction = 1.f;
  326. mTrackFocusObject = gSavedSettings.getBOOL("TrackFocusObject");
  327. mEffectColor = LLUIColorTable::instance().getColor("EffectColor");
  328. gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));
  329. gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2));
  330. mInitialized = TRUE;
  331. }
  332. //-----------------------------------------------------------------------------
  333. // cleanup()
  334. //-----------------------------------------------------------------------------
  335. void LLAgent::cleanup()
  336. {
  337. setSitCamera(LLUUID::null);
  338. mAvatarObject = NULL;
  339. if(mLookAt)
  340. {
  341. mLookAt->markDead() ;
  342. mLookAt = NULL;
  343. }
  344. if(mPointAt)
  345. {
  346. mPointAt->markDead() ;
  347. mPointAt = NULL;
  348. }
  349. mRegionp = NULL;
  350. setFocusObject(NULL);
  351. }
  352. //-----------------------------------------------------------------------------
  353. // LLAgent()
  354. //-----------------------------------------------------------------------------
  355. LLAgent::~LLAgent()
  356. {
  357. cleanup();
  358. // *Note: this is where LLViewerCamera::getInstance() used to be deleted.
  359. }
  360. // Change camera back to third person, stop the autopilot,
  361. // deselect stuff, etc.
  362. //-----------------------------------------------------------------------------
  363. // resetView()
  364. //-----------------------------------------------------------------------------
  365. void LLAgent::resetView(BOOL reset_camera, BOOL change_camera)
  366. {
  367. if (mAutoPilot)
  368. {
  369. stopAutoPilot(TRUE);
  370. }
  371. if (!gNoRender)
  372. {
  373. LLSelectMgr::getInstance()->unhighlightAll();
  374. // By popular request, keep land selection while walking around. JC
  375. // LLViewerParcelMgr::getInstance()->deselectLand();
  376. // force deselect when walking and attachment is selected
  377. // this is so people don't wig out when their avatar moves without animating
  378. if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
  379. {
  380. LLSelectMgr::getInstance()->deselectAll();
  381. }
  382. // Hide all popup menus
  383. gMenuHolder->hideMenus();
  384. }
  385. if (change_camera && !gSavedSettings.getBOOL("FreezeTime"))
  386. {
  387. changeCameraToDefault();
  388. if (LLViewerJoystick::getInstance()->getOverrideCamera())
  389. {
  390. handle_toggle_flycam();
  391. }
  392. // reset avatar mode from eventual residual motion
  393. if (LLToolMgr::getInstance()->inBuildMode())
  394. {
  395. LLViewerJoystick::getInstance()->moveAvatar(true);
  396. }
  397. //Camera Tool is needed for Free Camera Control Mode
  398. if (!LLFloaterCamera::inFreeCameraMode())
  399. {
  400. LLFloaterReg::hideInstance("build");
  401. // Switch back to basic toolset
  402. LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
  403. }
  404. gViewerWindow->showCursor();
  405. }
  406. if (reset_camera && !gSavedSettings.getBOOL("FreezeTime"))
  407. {
  408. if (!gViewerWindow->getLeftMouseDown() && cameraThirdPerson())
  409. {
  410. // leaving mouse-steer mode
  411. LLVector3 agent_at_axis = getAtAxis();
  412. agent_at_axis -= projected_vec(agent_at_axis, getReferenceUpVector());
  413. agent_at_axis.normalize();
  414. gAgent.resetAxes(lerp(getAtAxis(), agent_at_axis, LLCriticalDamp::getInterpolant(0.3f)));
  415. }
  416. setFocusOnAvatar(TRUE, ANIMATE);
  417. mCameraFOVZoomFactor = 0.f;
  418. }
  419. mHUDTargetZoom = 1.f;
  420. }
  421. // Handle any actions that need to be performed when the main app gains focus
  422. // (such as through alt-tab).
  423. //-----------------------------------------------------------------------------
  424. // onAppFocusGained()
  425. //-----------------------------------------------------------------------------
  426. void LLAgent::onAppFocusGained()
  427. {
  428. if (CAMERA_MODE_MOUSELOOK == mCameraMode)
  429. {
  430. changeCameraToDefault();
  431. LLToolMgr::getInstance()->clearSavedTool();
  432. }
  433. }
  434. void LLAgent::ageChat()
  435. {
  436. if (mAvatarObject.notNull())
  437. {
  438. // get amount of time since I last chatted
  439. F64 elapsed_time = (F64)mAvatarObject->mChatTimer.getElapsedTimeF32();
  440. // add in frame time * 3 (so it ages 4x)
  441. mAvatarObject->mChatTimer.setAge(elapsed_time + (F64)gFrameDTClamped * (CHAT_AGE_FAST_RATE - 1.0));
  442. }
  443. }
  444. // Allow camera to be moved somewhere other than behind avatar.
  445. //-----------------------------------------------------------------------------
  446. // unlockView()
  447. //-----------------------------------------------------------------------------
  448. void LLAgent::unlockView()
  449. {
  450. if (getFocusOnAvatar())
  451. {
  452. if (mAvatarObject.notNull())
  453. {
  454. setFocusGlobal( LLVector3d::zero, mAvatarObject->mID );
  455. }
  456. setFocusOnAvatar(FALSE, FALSE); // no animation
  457. }
  458. }
  459. //-----------------------------------------------------------------------------
  460. // moveAt()
  461. //-----------------------------------------------------------------------------
  462. void LLAgent::moveAt(S32 direction, bool reset)
  463. {
  464. // age chat timer so it fades more quickly when you are intentionally moving
  465. ageChat();
  466. setKey(direction, mAtKey);
  467. if (direction > 0)
  468. {
  469. setControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_FAST_AT);
  470. }
  471. else if (direction < 0)
  472. {
  473. setControlFlags(AGENT_CONTROL_AT_NEG | AGENT_CONTROL_FAST_AT);
  474. }
  475. if (reset)
  476. {
  477. resetView();
  478. }
  479. }
  480. //-----------------------------------------------------------------------------
  481. // moveAtNudge()
  482. //-----------------------------------------------------------------------------
  483. void LLAgent::moveAtNudge(S32 direction)
  484. {
  485. // age chat timer so it fades more quickly when you are intentionally moving
  486. ageChat();
  487. setKey(direction, mWalkKey);
  488. if (direction > 0)
  489. {
  490. setControlFlags(AGENT_CONTROL_NUDGE_AT_POS);
  491. }
  492. else if (direction < 0)
  493. {
  494. setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG);
  495. }
  496. resetView();
  497. }
  498. //-----------------------------------------------------------------------------
  499. // moveLeft()
  500. //-----------------------------------------------------------------------------
  501. void LLAgent::moveLeft(S32 direction)
  502. {
  503. // age chat timer so it fades more quickly when you are intentionally moving
  504. ageChat();
  505. setKey(direction, mLeftKey);
  506. if (direction > 0)
  507. {
  508. setControlFlags(AGENT_CONTROL_LEFT_POS | AGENT_CONTROL_FAST_LEFT);
  509. }
  510. else if (direction < 0)
  511. {
  512. setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT);
  513. }
  514. resetView();
  515. }
  516. //-----------------------------------------------------------------------------
  517. // moveLeftNudge()
  518. //-----------------------------------------------------------------------------
  519. void LLAgent::moveLeftNudge(S32 direction)
  520. {
  521. // age chat timer so it fades more quickly when you are intentionally moving
  522. ageChat();
  523. setKey(direction, mLeftKey);
  524. if (direction > 0)
  525. {
  526. setControlFlags(AGENT_CONTROL_NUDGE_LEFT_POS);
  527. }
  528. else if (direction < 0)
  529. {
  530. setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG);
  531. }
  532. resetView();
  533. }
  534. //-----------------------------------------------------------------------------
  535. // moveUp()
  536. //-----------------------------------------------------------------------------
  537. void LLAgent::moveUp(S32 direction)
  538. {
  539. // age chat timer so it fades more quickly when you are intentionally moving
  540. ageChat();
  541. setKey(direction, mUpKey);
  542. if (direction > 0)
  543. {
  544. setControlFlags(AGENT_CONTROL_UP_POS | AGENT_CONTROL_FAST_UP);
  545. }
  546. else if (direction < 0)
  547. {
  548. setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP);
  549. }
  550. resetView();
  551. }
  552. //-----------------------------------------------------------------------------
  553. // moveYaw()
  554. //-----------------------------------------------------------------------------
  555. void LLAgent::moveYaw(F32 mag, bool reset_view)
  556. {
  557. mYawKey = mag;
  558. if (mag > 0)
  559. {
  560. setControlFlags(AGENT_CONTROL_YAW_POS);
  561. }
  562. else if (mag < 0)
  563. {
  564. setControlFlags(AGENT_CONTROL_YAW_NEG);
  565. }
  566.     if (reset_view)
  567. {
  568.         resetView();
  569. }
  570. }
  571. //-----------------------------------------------------------------------------
  572. // movePitch()
  573. //-----------------------------------------------------------------------------
  574. void LLAgent::movePitch(F32 mag)
  575. {
  576. mPitchKey = mag;
  577. if (mag > 0)
  578. {
  579. setControlFlags(AGENT_CONTROL_PITCH_POS);
  580. }
  581. else if (mag < 0)
  582. {
  583. setControlFlags(AGENT_CONTROL_PITCH_NEG);
  584. }
  585. }
  586. // Does this parcel allow you to fly?
  587. BOOL LLAgent::canFly()
  588. {
  589. if (isGodlike()) return TRUE;
  590. LLViewerRegion* regionp = getRegion();
  591. if (regionp && regionp->getBlockFly()) return FALSE;
  592. LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
  593. if (!parcel) return FALSE;
  594. // Allow owners to fly on their own land.
  595. if (LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_ALLOW_FLY))
  596. {
  597. return TRUE;
  598. }
  599. return parcel->getAllowFly();
  600. }
  601. BOOL LLAgent::getFlying() const
  602. return mControlFlags & AGENT_CONTROL_FLY; 
  603. }
  604. //-----------------------------------------------------------------------------
  605. // setFlying()
  606. //-----------------------------------------------------------------------------
  607. void LLAgent::setFlying(BOOL fly)
  608. {
  609. if (mAvatarObject.notNull())
  610. {
  611. // *HACK: Don't allow to start the flying mode if we got ANIM_AGENT_STANDUP signal
  612. // because in this case we won't get a signal to start avatar flying animation and
  613. // it will be walking with flying mode "ON" indication. However we allow to switch
  614. // the flying mode off if we get ANIM_AGENT_STANDUP signal. See process_avatar_animation().
  615. // See EXT-2781.
  616. if(fly && mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_STANDUP) != mAvatarObject->mSignaledAnimations.end())
  617. {
  618. return;
  619. }
  620. // don't allow taking off while sitting
  621. if (fly && mAvatarObject->isSitting())
  622. {
  623. return;
  624. }
  625. }
  626. if (fly)
  627. {
  628. BOOL was_flying = getFlying();
  629. if (!canFly() && !was_flying)
  630. {
  631. // parcel doesn't let you start fly
  632. // gods can always fly
  633. // and it's OK if you're already flying
  634. make_ui_sound("UISndBadKeystroke");
  635. return;
  636. }
  637. if( !was_flying )
  638. {
  639. LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT);
  640. }
  641. setControlFlags(AGENT_CONTROL_FLY);
  642. }
  643. else
  644. {
  645. clearControlFlags(AGENT_CONTROL_FLY);
  646. }
  647. // Update Movement Controls according to Fly mode
  648. LLFloaterMove::setFlyingMode(fly);
  649. mbFlagsDirty = TRUE;
  650. }
  651. // UI based mechanism of setting fly state
  652. //-----------------------------------------------------------------------------
  653. // toggleFlying()
  654. //-----------------------------------------------------------------------------
  655. // static
  656. void LLAgent::toggleFlying()
  657. {
  658. BOOL fly = !gAgent.getFlying();
  659. gAgent.setFlying( fly );
  660. gAgent.resetView();
  661. }
  662. // static
  663. bool LLAgent::enableFlying()
  664. {
  665. BOOL sitting = FALSE;
  666. if (gAgent.getAvatarObject())
  667. {
  668. sitting = gAgent.getAvatarObject()->isSitting();
  669. }
  670. return !sitting;
  671. }
  672. void LLAgent::standUp()
  673. {
  674. setControlFlags(AGENT_CONTROL_STAND_UP);
  675. }
  676. //-----------------------------------------------------------------------------
  677. // setRegion()
  678. //-----------------------------------------------------------------------------
  679. void LLAgent::setRegion(LLViewerRegion *regionp)
  680. {
  681. llassert(regionp);
  682. if (mRegionp != regionp)
  683. {
  684. // std::string host_name;
  685. // host_name = regionp->getHost().getHostName();
  686. std::string ip = regionp->getHost().getString();
  687. llinfos << "Moving agent into region: " << regionp->getName()
  688. << " located at " << ip << llendl;
  689. if (mRegionp)
  690. {
  691. // We've changed regions, we're now going to change our agent coordinate frame.
  692. mAgentOriginGlobal = regionp->getOriginGlobal();
  693. LLVector3d agent_offset_global = mRegionp->getOriginGlobal();
  694. LLVector3 delta;
  695. delta.setVec(regionp->getOriginGlobal() - mRegionp->getOriginGlobal());
  696. setPositionAgent(getPositionAgent() - delta);
  697. LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
  698. LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
  699. // Update all of the regions.
  700. LLWorld::getInstance()->updateAgentOffset(agent_offset_global);
  701. // Hack to keep sky in the agent's region, otherwise it may get deleted - DJS 08/02/02
  702. // *TODO: possibly refactor into gSky->setAgentRegion(regionp)? -Brad
  703. if (gSky.mVOSkyp)
  704. {
  705. gSky.mVOSkyp->setRegion(regionp);
  706. }
  707. if (gSky.mVOGroundp)
  708. {
  709. gSky.mVOGroundp->setRegion(regionp);
  710. }
  711. }
  712. else
  713. {
  714. // First time initialization.
  715. // We've changed regions, we're now going to change our agent coordinate frame.
  716. mAgentOriginGlobal = regionp->getOriginGlobal();
  717. LLVector3 delta;
  718. delta.setVec(regionp->getOriginGlobal());
  719. setPositionAgent(getPositionAgent() - delta);
  720. LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
  721. LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
  722. // Update all of the regions.
  723. LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
  724. }
  725. }
  726. mRegionp = regionp;
  727. // Must shift hole-covering water object locations because local
  728. // coordinate frame changed.
  729. LLWorld::getInstance()->updateWaterObjects();
  730. // keep a list of regions we've been too
  731. // this is just an interesting stat, logged at the dataserver
  732. // we could trake this at the dataserver side, but that's harder
  733. U64 handle = regionp->getHandle();
  734. mRegionsVisited.insert(handle);
  735. LLSelectMgr::getInstance()->updateSelectionCenter();
  736. LLFloaterMove::sUpdateFlyingStatus();
  737. }
  738. //-----------------------------------------------------------------------------
  739. // getRegion()
  740. //-----------------------------------------------------------------------------
  741. LLViewerRegion *LLAgent::getRegion() const
  742. {
  743. return mRegionp;
  744. }
  745. LLHost LLAgent::getRegionHost() const
  746. {
  747. if (mRegionp)
  748. {
  749. return mRegionp->getHost();
  750. }
  751. else
  752. {
  753. return LLHost::invalid;
  754. }
  755. }
  756. //-----------------------------------------------------------------------------
  757. // inPrelude()
  758. //-----------------------------------------------------------------------------
  759. BOOL LLAgent::inPrelude()
  760. {
  761. return mRegionp && mRegionp->isPrelude();
  762. }
  763. //-----------------------------------------------------------------------------
  764. // canManageEstate()
  765. //-----------------------------------------------------------------------------
  766. BOOL LLAgent::canManageEstate() const
  767. {
  768. return mRegionp && mRegionp->canManageEstate();
  769. }
  770. //-----------------------------------------------------------------------------
  771. // sendMessage()
  772. //-----------------------------------------------------------------------------
  773. void LLAgent::sendMessage()
  774. {
  775. if (gDisconnected)
  776. {
  777. llwarns << "Trying to send message when disconnected!" << llendl;
  778. return;
  779. }
  780. if (!mRegionp)
  781. {
  782. llerrs << "No region for agent yet!" << llendl;
  783. return;
  784. }
  785. gMessageSystem->sendMessage(mRegionp->getHost());
  786. }
  787. //-----------------------------------------------------------------------------
  788. // sendReliableMessage()
  789. //-----------------------------------------------------------------------------
  790. void LLAgent::sendReliableMessage()
  791. {
  792. if (gDisconnected)
  793. {
  794. lldebugs << "Trying to send message when disconnected!" << llendl;
  795. return;
  796. }
  797. if (!mRegionp)
  798. {
  799. lldebugs << "LLAgent::sendReliableMessage No region for agent yet, not sending message!" << llendl;
  800. return;
  801. }
  802. gMessageSystem->sendReliable(mRegionp->getHost());
  803. }
  804. //-----------------------------------------------------------------------------
  805. // getVelocity()
  806. //-----------------------------------------------------------------------------
  807. LLVector3 LLAgent::getVelocity() const
  808. {
  809. if (mAvatarObject.notNull())
  810. {
  811. return mAvatarObject->getVelocity();
  812. }
  813. else
  814. {
  815. return LLVector3::zero;
  816. }
  817. }
  818. //-----------------------------------------------------------------------------
  819. // setPositionAgent()
  820. //-----------------------------------------------------------------------------
  821. void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
  822. {
  823. if (!pos_agent.isFinite())
  824. {
  825. llerrs << "setPositionAgent is not a number" << llendl;
  826. }
  827. if (mAvatarObject.notNull() && mAvatarObject->getParent())
  828. {
  829. LLVector3 pos_agent_sitting;
  830. LLVector3d pos_agent_d;
  831. LLViewerObject *parent = (LLViewerObject*)mAvatarObject->getParent();
  832. pos_agent_sitting = mAvatarObject->getPosition() * parent->getRotation() + parent->getPositionAgent();
  833. pos_agent_d.setVec(pos_agent_sitting);
  834. mFrameAgent.setOrigin(pos_agent_sitting);
  835. mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
  836. }
  837. else
  838. {
  839. mFrameAgent.setOrigin(pos_agent);
  840. LLVector3d pos_agent_d;
  841. pos_agent_d.setVec(pos_agent);
  842. mPositionGlobal = pos_agent_d + mAgentOriginGlobal;
  843. }
  844. }
  845. //-----------------------------------------------------------------------------
  846. // slamLookAt()
  847. //-----------------------------------------------------------------------------
  848. void LLAgent::slamLookAt(const LLVector3 &look_at)
  849. {
  850. LLVector3 look_at_norm = look_at;
  851. look_at_norm.mV[VZ] = 0.f;
  852. look_at_norm.normalize();
  853. resetAxes(look_at_norm);
  854. }
  855. //-----------------------------------------------------------------------------
  856. // getPositionGlobal()
  857. //-----------------------------------------------------------------------------
  858. const LLVector3d &LLAgent::getPositionGlobal() const
  859. {
  860. if (mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
  861. {
  862. mPositionGlobal = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());
  863. }
  864. else
  865. {
  866. mPositionGlobal = getPosGlobalFromAgent(mFrameAgent.getOrigin());
  867. }
  868. return mPositionGlobal;
  869. }
  870. //-----------------------------------------------------------------------------
  871. // getPositionAgent()
  872. //-----------------------------------------------------------------------------
  873. const LLVector3 &LLAgent::getPositionAgent()
  874. {
  875. if(mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
  876. {
  877. mFrameAgent.setOrigin(mAvatarObject->getRenderPosition());
  878. }
  879. return mFrameAgent.getOrigin();
  880. }
  881. //-----------------------------------------------------------------------------
  882. // getRegionsVisited()
  883. //-----------------------------------------------------------------------------
  884. S32 LLAgent::getRegionsVisited() const
  885. {
  886. return mRegionsVisited.size();
  887. }
  888. //-----------------------------------------------------------------------------
  889. // getDistanceTraveled()
  890. //-----------------------------------------------------------------------------
  891. F64 LLAgent::getDistanceTraveled() const
  892. {
  893. return mDistanceTraveled;
  894. }
  895. //-----------------------------------------------------------------------------
  896. // getPosAgentFromGlobal()
  897. //-----------------------------------------------------------------------------
  898. LLVector3 LLAgent::getPosAgentFromGlobal(const LLVector3d &pos_global) const
  899. {
  900. LLVector3 pos_agent;
  901. pos_agent.setVec(pos_global - mAgentOriginGlobal);
  902. return pos_agent;
  903. }
  904. //-----------------------------------------------------------------------------
  905. // getPosGlobalFromAgent()
  906. //-----------------------------------------------------------------------------
  907. LLVector3d LLAgent::getPosGlobalFromAgent(const LLVector3 &pos_agent) const
  908. {
  909. LLVector3d pos_agent_d;
  910. pos_agent_d.setVec(pos_agent);
  911. return pos_agent_d + mAgentOriginGlobal;
  912. }
  913. //-----------------------------------------------------------------------------
  914. // resetAxes()
  915. //-----------------------------------------------------------------------------
  916. void LLAgent::resetAxes()
  917. {
  918. mFrameAgent.resetAxes();
  919. }
  920. // Copied from LLCamera::setOriginAndLookAt
  921. // Look_at must be unit vector
  922. //-----------------------------------------------------------------------------
  923. // resetAxes()
  924. //-----------------------------------------------------------------------------
  925. void LLAgent::resetAxes(const LLVector3 &look_at)
  926. {
  927. LLVector3 skyward = getReferenceUpVector();
  928. // if look_at has zero length, fail
  929. // if look_at and skyward are parallel, fail
  930. //
  931. // Test both of these conditions with a cross product.
  932. LLVector3 cross(look_at % skyward);
  933. if (cross.isNull())
  934. {
  935. llinfos << "LLAgent::resetAxes cross-product is zero" << llendl;
  936. return;
  937. }
  938. // Make sure look_at and skyward are not parallel
  939. // and neither are zero length
  940. LLVector3 left(skyward % look_at);
  941. LLVector3 up(look_at % left);
  942. mFrameAgent.setAxes(look_at, left, up);
  943. }
  944. //-----------------------------------------------------------------------------
  945. // rotate()
  946. //-----------------------------------------------------------------------------
  947. void LLAgent::rotate(F32 angle, const LLVector3 &axis) 
  948. mFrameAgent.rotate(angle, axis); 
  949. }
  950. //-----------------------------------------------------------------------------
  951. // rotate()
  952. //-----------------------------------------------------------------------------
  953. void LLAgent::rotate(F32 angle, F32 x, F32 y, F32 z) 
  954. mFrameAgent.rotate(angle, x, y, z); 
  955. }
  956. //-----------------------------------------------------------------------------
  957. // rotate()
  958. //-----------------------------------------------------------------------------
  959. void LLAgent::rotate(const LLMatrix3 &matrix) 
  960. mFrameAgent.rotate(matrix); 
  961. }
  962. //-----------------------------------------------------------------------------
  963. // rotate()
  964. //-----------------------------------------------------------------------------
  965. void LLAgent::rotate(const LLQuaternion &quaternion) 
  966. mFrameAgent.rotate(quaternion); 
  967. }
  968. //-----------------------------------------------------------------------------
  969. // getReferenceUpVector()
  970. //-----------------------------------------------------------------------------
  971. LLVector3 LLAgent::getReferenceUpVector()
  972. {
  973. // this vector is in the coordinate frame of the avatar's parent object, or the world if none
  974. LLVector3 up_vector = LLVector3::z_axis;
  975. if (mAvatarObject.notNull() && 
  976. mAvatarObject->getParent() &&
  977. mAvatarObject->mDrawable.notNull())
  978. {
  979. U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
  980. // and in third person...
  981. if (camera_mode == CAMERA_MODE_THIRD_PERSON)
  982. {
  983. // make the up vector point to the absolute +z axis
  984. up_vector = up_vector * ~((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
  985. }
  986. else if (camera_mode == CAMERA_MODE_MOUSELOOK)
  987. {
  988. // make the up vector point to the avatar's +z axis
  989. up_vector = up_vector * mAvatarObject->mDrawable->getRotation();
  990. }
  991. }
  992. return up_vector;
  993. }
  994. // Radians, positive is forward into ground
  995. //-----------------------------------------------------------------------------
  996. // pitch()
  997. //-----------------------------------------------------------------------------
  998. void LLAgent::pitch(F32 angle)
  999. {
  1000. // don't let user pitch if pointed almost all the way down or up
  1001. mFrameAgent.pitch(clampPitchToLimits(angle));
  1002. }
  1003. // Radians, positive is forward into ground
  1004. //-----------------------------------------------------------------------------
  1005. // clampPitchToLimits()
  1006. //-----------------------------------------------------------------------------
  1007. F32 LLAgent::clampPitchToLimits(F32 angle)
  1008. {
  1009. // A dot B = mag(A) * mag(B) * cos(angle between A and B)
  1010. // so... cos(angle between A and B) = A dot B / mag(A) / mag(B)
  1011. //                                  = A dot B for unit vectors
  1012. LLVector3 skyward = getReferenceUpVector();
  1013. F32 look_down_limit;
  1014. F32 look_up_limit = 10.f * DEG_TO_RAD;
  1015. F32 angle_from_skyward = acos( mFrameAgent.getAtAxis() * skyward );
  1016. if (mAvatarObject.notNull() && mAvatarObject->isSitting())
  1017. {
  1018. look_down_limit = 130.f * DEG_TO_RAD;
  1019. }
  1020. else
  1021. {
  1022. look_down_limit = 170.f * DEG_TO_RAD;
  1023. }
  1024. // clamp pitch to limits
  1025. if ((angle >= 0.f) && (angle_from_skyward + angle > look_down_limit))
  1026. {
  1027. angle = look_down_limit - angle_from_skyward;
  1028. }
  1029. else if ((angle < 0.f) && (angle_from_skyward + angle < look_up_limit))
  1030. {
  1031. angle = look_up_limit - angle_from_skyward;
  1032. }
  1033.    
  1034.     return angle;
  1035. }
  1036. //-----------------------------------------------------------------------------
  1037. // roll()
  1038. //-----------------------------------------------------------------------------
  1039. void LLAgent::roll(F32 angle)
  1040. {
  1041. mFrameAgent.roll(angle);
  1042. }
  1043. //-----------------------------------------------------------------------------
  1044. // yaw()
  1045. //-----------------------------------------------------------------------------
  1046. void LLAgent::yaw(F32 angle)
  1047. {
  1048. if (!rotateGrabbed())
  1049. {
  1050. mFrameAgent.rotate(angle, getReferenceUpVector());
  1051. }
  1052. }
  1053. // Returns a quat that represents the rotation of the agent in the absolute frame
  1054. //-----------------------------------------------------------------------------
  1055. // getQuat()
  1056. //-----------------------------------------------------------------------------
  1057. LLQuaternion LLAgent::getQuat() const
  1058. {
  1059. return mFrameAgent.getQuaternion();
  1060. }
  1061. //-----------------------------------------------------------------------------
  1062. // calcFocusOffset()
  1063. //-----------------------------------------------------------------------------
  1064. LLVector3 LLAgent::calcFocusOffset(LLViewerObject *object, LLVector3 original_focus_point, S32 x, S32 y)
  1065. {
  1066. LLMatrix4 obj_matrix = object->getRenderMatrix();
  1067. LLQuaternion obj_rot = object->getRenderRotation();
  1068. LLVector3 obj_pos = object->getRenderPosition();
  1069. BOOL is_avatar = object->isAvatar();
  1070. // if is avatar - don't do any funk heuristics to position the focal point
  1071. // see DEV-30589
  1072. if (is_avatar)
  1073. {
  1074. return original_focus_point - obj_pos;
  1075. }
  1076. LLQuaternion inv_obj_rot = ~obj_rot; // get inverse of rotation
  1077. LLVector3 object_extents = object->getScale();
  1078. // make sure they object extents are non-zero
  1079. object_extents.clamp(0.001f, F32_MAX);
  1080. // obj_to_cam_ray is unit vector pointing from object center to camera, in the coordinate frame of the object
  1081. LLVector3 obj_to_cam_ray = obj_pos - LLViewerCamera::getInstance()->getOrigin();
  1082. obj_to_cam_ray.rotVec(inv_obj_rot);
  1083. obj_to_cam_ray.normalize();
  1084. // obj_to_cam_ray_proportions are the (positive) ratios of 
  1085. // the obj_to_cam_ray x,y,z components with the x,y,z object dimensions.
  1086. LLVector3 obj_to_cam_ray_proportions;
  1087. obj_to_cam_ray_proportions.mV[VX] = llabs(obj_to_cam_ray.mV[VX] / object_extents.mV[VX]);
  1088. obj_to_cam_ray_proportions.mV[VY] = llabs(obj_to_cam_ray.mV[VY] / object_extents.mV[VY]);
  1089. obj_to_cam_ray_proportions.mV[VZ] = llabs(obj_to_cam_ray.mV[VZ] / object_extents.mV[VZ]);
  1090. // find the largest ratio stored in obj_to_cam_ray_proportions
  1091. // this corresponds to the object's local axial plane (XY, YZ, XZ) that is *most* facing the camera
  1092. LLVector3 longest_object_axis;
  1093. // is x-axis longest?
  1094. if (obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VY] 
  1095. && obj_to_cam_ray_proportions.mV[VX] > obj_to_cam_ray_proportions.mV[VZ])
  1096. {
  1097. // then grab it
  1098. longest_object_axis.setVec(obj_matrix.getFwdRow4());
  1099. }
  1100. // is y-axis longest?
  1101. else if (obj_to_cam_ray_proportions.mV[VY] > obj_to_cam_ray_proportions.mV[VZ])
  1102. {
  1103. // then grab it
  1104. longest_object_axis.setVec(obj_matrix.getLeftRow4());
  1105. }
  1106. // otherwise, use z axis
  1107. else
  1108. {
  1109. longest_object_axis.setVec(obj_matrix.getUpRow4());
  1110. }
  1111. // Use this axis as the normal to project mouse click on to plane with that normal, at the object center.
  1112. // This generates a point behind the mouse cursor that is approximately in the middle of the object in
  1113. // terms of depth.  
  1114. // We do this to allow the camera rotation tool to "tumble" the object by rotating the camera.
  1115. // If the focus point were the object surface under the mouse, camera rotation would introduce an undesirable
  1116. // eccentricity to the object orientation
  1117. LLVector3 focus_plane_normal(longest_object_axis);
  1118. focus_plane_normal.normalize();
  1119. LLVector3d focus_pt_global;
  1120. gViewerWindow->mousePointOnPlaneGlobal(focus_pt_global, x, y, gAgent.getPosGlobalFromAgent(obj_pos), focus_plane_normal);
  1121. LLVector3 focus_pt = gAgent.getPosAgentFromGlobal(focus_pt_global);
  1122. // find vector from camera to focus point in object space
  1123. LLVector3 camera_to_focus_vec = focus_pt - LLViewerCamera::getInstance()->getOrigin();
  1124. camera_to_focus_vec.rotVec(inv_obj_rot);
  1125. // find vector from object origin to focus point in object coordinates
  1126. LLVector3 focus_offset_from_object_center = focus_pt - obj_pos;
  1127. // convert to object-local space
  1128. focus_offset_from_object_center.rotVec(inv_obj_rot);
  1129. // We need to project the focus point back into the bounding box of the focused object.
  1130. // Do this by calculating the XYZ scale factors needed to get focus offset back in bounds along the camera_focus axis
  1131. LLVector3 clip_fraction;
  1132. // for each axis...
  1133. for (U32 axis = VX; axis <= VZ; axis++)
  1134. {
  1135. //...calculate distance that focus offset sits outside of bounding box along that axis...
  1136. //NOTE: dist_out_of_bounds keeps the sign of focus_offset_from_object_center 
  1137. F32 dist_out_of_bounds;
  1138. if (focus_offset_from_object_center.mV[axis] > 0.f)
  1139. {
  1140. dist_out_of_bounds = llmax(0.f, focus_offset_from_object_center.mV[axis] - (object_extents.mV[axis] * 0.5f));
  1141. }
  1142. else
  1143. {
  1144. dist_out_of_bounds = llmin(0.f, focus_offset_from_object_center.mV[axis] + (object_extents.mV[axis] * 0.5f));
  1145. }
  1146. //...then calculate the scale factor needed to push camera_to_focus_vec back in bounds along current axis
  1147. if (llabs(camera_to_focus_vec.mV[axis]) < 0.0001f)
  1148. {
  1149. // don't divide by very small number
  1150. clip_fraction.mV[axis] = 0.f;
  1151. }
  1152. else
  1153. {
  1154. clip_fraction.mV[axis] = dist_out_of_bounds / camera_to_focus_vec.mV[axis];
  1155. }
  1156. }
  1157. LLVector3 abs_clip_fraction = clip_fraction;
  1158. abs_clip_fraction.abs();
  1159. // find axis of focus offset that is *most* outside the bounding box and use that to
  1160. // rescale focus offset to inside object extents
  1161. if (abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VY]
  1162. && abs_clip_fraction.mV[VX] > abs_clip_fraction.mV[VZ])
  1163. {
  1164. focus_offset_from_object_center -= clip_fraction.mV[VX] * camera_to_focus_vec;
  1165. }
  1166. else if (abs_clip_fraction.mV[VY] > abs_clip_fraction.mV[VZ])
  1167. {
  1168. focus_offset_from_object_center -= clip_fraction.mV[VY] * camera_to_focus_vec;
  1169. }
  1170. else
  1171. {
  1172. focus_offset_from_object_center -= clip_fraction.mV[VZ] * camera_to_focus_vec;
  1173. }
  1174. // convert back to world space
  1175. focus_offset_from_object_center.rotVec(obj_rot);
  1176. // now, based on distance of camera from object relative to object size
  1177. // push the focus point towards the near surface of the object when (relatively) close to the objcet
  1178. // or keep the focus point in the object middle when (relatively) far
  1179. // NOTE: leave focus point in middle of avatars, since the behavior you want when alt-zooming on avatars
  1180. // is almost always "tumble about middle" and not "spin around surface point"
  1181. if (!is_avatar) 
  1182. {
  1183. LLVector3 obj_rel = original_focus_point - object->getRenderPosition();
  1184. //now that we have the object relative position, we should bias toward the center of the object 
  1185. //based on the distance of the camera to the focus point vs. the distance of the camera to the focus
  1186. F32 relDist = llabs(obj_rel * LLViewerCamera::getInstance()->getAtAxis());
  1187. F32 viewDist = dist_vec(obj_pos + obj_rel, LLViewerCamera::getInstance()->getOrigin());
  1188. LLBBox obj_bbox = object->getBoundingBoxAgent();
  1189. F32 bias = 0.f;
  1190. // virtual_camera_pos is the camera position we are simulating by backing the camera off
  1191. // and adjusting the FOV
  1192. LLVector3 virtual_camera_pos = gAgent.getPosAgentFromGlobal(mFocusTargetGlobal + (getCameraPositionGlobal() - mFocusTargetGlobal) / (1.f + mCameraFOVZoomFactor));
  1193. // if the camera is inside the object (large, hollow objects, for example)
  1194. // leave focus point all the way to destination depth, away from object center
  1195. if(!obj_bbox.containsPointAgent(virtual_camera_pos))
  1196. {
  1197. // perform magic number biasing of focus point towards surface vs. planar center
  1198. bias = clamp_rescale(relDist/viewDist, 0.1f, 0.7f, 0.0f, 1.0f);
  1199. obj_rel = lerp(focus_offset_from_object_center, obj_rel, bias);
  1200. }
  1201. focus_offset_from_object_center = obj_rel;
  1202. }
  1203. return focus_offset_from_object_center;
  1204. }
  1205. //-----------------------------------------------------------------------------
  1206. // calcCameraMinDistance()
  1207. //-----------------------------------------------------------------------------
  1208. BOOL LLAgent::calcCameraMinDistance(F32 &obj_min_distance)
  1209. {
  1210. BOOL soft_limit = FALSE; // is the bounding box to be treated literally (volumes) or as an approximation (avatars)
  1211. if (!mFocusObject || mFocusObject->isDead())
  1212. {
  1213. obj_min_distance = 0.f;
  1214. return TRUE;
  1215. }
  1216. if (mFocusObject->mDrawable.isNull())
  1217. {
  1218. #ifdef LL_RELEASE_FOR_DOWNLOAD
  1219. llwarns << "Focus object with no drawable!" << llendl;
  1220. #else
  1221. mFocusObject->dump();
  1222. llerrs << "Focus object with no drawable!" << llendl;
  1223. #endif
  1224. obj_min_distance = 0.f;
  1225. return TRUE;
  1226. }
  1227. LLQuaternion inv_object_rot = ~mFocusObject->getRenderRotation();
  1228. LLVector3 target_offset_origin = mFocusObjectOffset;
  1229. LLVector3 camera_offset_target(getCameraPositionAgent() - getPosAgentFromGlobal(mFocusTargetGlobal));
  1230. // convert offsets into object local space
  1231. camera_offset_target.rotVec(inv_object_rot);
  1232. target_offset_origin.rotVec(inv_object_rot);
  1233. // push around object extents based on target offset
  1234. LLVector3 object_extents = mFocusObject->getScale();
  1235. if (mFocusObject->isAvatar())
  1236. {
  1237. // fudge factors that lets you zoom in on avatars a bit more (which don't do FOV zoom)
  1238. object_extents.mV[VX] *= AVATAR_ZOOM_MIN_X_FACTOR;
  1239. object_extents.mV[VY] *= AVATAR_ZOOM_MIN_Y_FACTOR;
  1240. object_extents.mV[VZ] *= AVATAR_ZOOM_MIN_Z_FACTOR;
  1241. soft_limit = TRUE;
  1242. }
  1243. LLVector3 abs_target_offset = target_offset_origin;
  1244. abs_target_offset.abs();
  1245. LLVector3 target_offset_dir = target_offset_origin;
  1246. F32 object_radius = mFocusObject->getVObjRadius();
  1247. BOOL target_outside_object_extents = FALSE;
  1248. for (U32 i = VX; i <= VZ; i++)
  1249. {
  1250. if (abs_target_offset.mV[i] * 2.f > object_extents.mV[i] + OBJECT_EXTENTS_PADDING)
  1251. {
  1252. target_outside_object_extents = TRUE;
  1253. }
  1254. if (camera_offset_target.mV[i] > 0.f)
  1255. {
  1256. object_extents.mV[i] -= target_offset_origin.mV[i] * 2.f;
  1257. }
  1258. else
  1259. {
  1260. object_extents.mV[i] += target_offset_origin.mV[i] * 2.f;
  1261. }
  1262. }
  1263. // don't shrink the object extents so far that the object inverts
  1264. object_extents.clamp(0.001f, F32_MAX);
  1265. // move into first octant
  1266. LLVector3 camera_offset_target_abs_norm = camera_offset_target;
  1267. camera_offset_target_abs_norm.abs();
  1268. // make sure offset is non-zero
  1269. camera_offset_target_abs_norm.clamp(0.001f, F32_MAX);
  1270. camera_offset_target_abs_norm.normalize();
  1271. // find camera position relative to normalized object extents
  1272. LLVector3 camera_offset_target_scaled = camera_offset_target_abs_norm;
  1273. camera_offset_target_scaled.mV[VX] /= object_extents.mV[VX];
  1274. camera_offset_target_scaled.mV[VY] /= object_extents.mV[VY];
  1275. camera_offset_target_scaled.mV[VZ] /= object_extents.mV[VZ];
  1276. if (camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VY] && 
  1277. camera_offset_target_scaled.mV[VX] > camera_offset_target_scaled.mV[VZ])
  1278. {
  1279. if (camera_offset_target_abs_norm.mV[VX] < 0.001f)
  1280. {
  1281. obj_min_distance = object_extents.mV[VX] * 0.5f;
  1282. }
  1283. else
  1284. {
  1285. obj_min_distance = object_extents.mV[VX] * 0.5f / camera_offset_target_abs_norm.mV[VX];
  1286. }
  1287. }
  1288. else if (camera_offset_target_scaled.mV[VY] > camera_offset_target_scaled.mV[VZ])
  1289. {
  1290. if (camera_offset_target_abs_norm.mV[VY] < 0.001f)
  1291. {
  1292. obj_min_distance = object_extents.mV[VY] * 0.5f;
  1293. }
  1294. else
  1295. {
  1296. obj_min_distance = object_extents.mV[VY] * 0.5f / camera_offset_target_abs_norm.mV[VY];
  1297. }
  1298. }
  1299. else
  1300. {
  1301. if (camera_offset_target_abs_norm.mV[VZ] < 0.001f)
  1302. {
  1303. obj_min_distance = object_extents.mV[VZ] * 0.5f;
  1304. }
  1305. else
  1306. {
  1307. obj_min_distance = object_extents.mV[VZ] * 0.5f / camera_offset_target_abs_norm.mV[VZ];
  1308. }
  1309. }
  1310. LLVector3 object_split_axis;
  1311. LLVector3 target_offset_scaled = target_offset_origin;
  1312. target_offset_scaled.abs();
  1313. target_offset_scaled.normalize();
  1314. target_offset_scaled.mV[VX] /= object_extents.mV[VX];
  1315. target_offset_scaled.mV[VY] /= object_extents.mV[VY];
  1316. target_offset_scaled.mV[VZ] /= object_extents.mV[VZ];
  1317. if (target_offset_scaled.mV[VX] > target_offset_scaled.mV[VY] && 
  1318. target_offset_scaled.mV[VX] > target_offset_scaled.mV[VZ])
  1319. {
  1320. object_split_axis = LLVector3::x_axis;
  1321. }
  1322. else if (target_offset_scaled.mV[VY] > target_offset_scaled.mV[VZ])
  1323. {
  1324. object_split_axis = LLVector3::y_axis;
  1325. }
  1326. else
  1327. {
  1328. object_split_axis = LLVector3::z_axis;
  1329. }
  1330. LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
  1331. // length projected orthogonal to target offset
  1332. F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
  1333. // calculate whether the target point would be "visible" if it were outside the bounding box
  1334. // on the opposite of the splitting plane defined by object_split_axis;
  1335. BOOL exterior_target_visible = FALSE;
  1336. if (camera_offset_dist > object_radius)
  1337. {
  1338. // target is visible from camera, so turn off fov zoom
  1339. exterior_target_visible = TRUE;
  1340. }
  1341. F32 camera_offset_clip = camera_offset_object * object_split_axis;
  1342. F32 target_offset_clip = target_offset_dir * object_split_axis;
  1343. // target has moved outside of object extents
  1344. // check to see if camera and target are on same side 
  1345. if (target_outside_object_extents)
  1346. {
  1347. if (camera_offset_clip > 0.f && target_offset_clip > 0.f)
  1348. {
  1349. return FALSE;
  1350. }
  1351. else if (camera_offset_clip < 0.f && target_offset_clip < 0.f)
  1352. {
  1353. return FALSE;
  1354. }
  1355. }
  1356. // clamp obj distance to diagonal of 10 by 10 cube
  1357. obj_min_distance = llmin(obj_min_distance, 10.f * F_SQRT3);
  1358. obj_min_distance += LLViewerCamera::getInstance()->getNear() + (soft_limit ? 0.1f : 0.2f);
  1359. return TRUE;
  1360. }
  1361. F32 LLAgent::getCameraZoomFraction()
  1362. {
  1363. // 0.f -> camera zoomed all the way out
  1364. // 1.f -> camera zoomed all the way in
  1365. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  1366. if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
  1367. {
  1368. // already [0,1]
  1369. return mHUDTargetZoom;
  1370. }
  1371. else if (mFocusOnAvatar && cameraThirdPerson())
  1372. {
  1373. return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
  1374. }
  1375. else if (cameraCustomizeAvatar())
  1376. {
  1377. F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
  1378. return clamp_rescale(distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM, 1.f, 0.f );
  1379. }
  1380. else
  1381. {
  1382. F32 min_zoom;
  1383. const F32 DIST_FUDGE = 16.f; // meters
  1384. F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
  1385. LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
  1386. MAX_CAMERA_DISTANCE_FROM_AGENT);
  1387. F32 distance = (F32)mCameraFocusOffsetTarget.magVec();
  1388. if (mFocusObject.notNull())
  1389. {
  1390. if (mFocusObject->isAvatar())
  1391. {
  1392. min_zoom = AVATAR_MIN_ZOOM;
  1393. }
  1394. else
  1395. {
  1396. min_zoom = OBJECT_MIN_ZOOM;
  1397. }
  1398. }
  1399. else
  1400. {
  1401. min_zoom = LAND_MIN_ZOOM;
  1402. }
  1403. return clamp_rescale(distance, min_zoom, max_zoom, 1.f, 0.f);
  1404. }
  1405. }
  1406. void LLAgent::setCameraZoomFraction(F32 fraction)
  1407. {
  1408. // 0.f -> camera zoomed all the way out
  1409. // 1.f -> camera zoomed all the way in
  1410. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  1411. if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
  1412. {
  1413. mHUDTargetZoom = fraction;
  1414. }
  1415. else if (mFocusOnAvatar && cameraThirdPerson())
  1416. {
  1417. mCameraZoomFraction = rescale(fraction, 0.f, 1.f, MAX_ZOOM_FRACTION, MIN_ZOOM_FRACTION);
  1418. }
  1419. else if (cameraCustomizeAvatar())
  1420. {
  1421. LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
  1422. camera_offset_dir.normalize();
  1423. mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, APPEARANCE_MAX_ZOOM, APPEARANCE_MIN_ZOOM);
  1424. }
  1425. else
  1426. {
  1427. F32 min_zoom = LAND_MIN_ZOOM;
  1428. const F32 DIST_FUDGE = 16.f; // meters
  1429. F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 
  1430. LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
  1431. MAX_CAMERA_DISTANCE_FROM_AGENT);
  1432. if (mFocusObject.notNull())
  1433. {
  1434. if (mFocusObject.notNull())
  1435. {
  1436. if (mFocusObject->isAvatar())
  1437. {
  1438. min_zoom = AVATAR_MIN_ZOOM;
  1439. }
  1440. else
  1441. {
  1442. min_zoom = OBJECT_MIN_ZOOM;
  1443. }
  1444. }
  1445. }
  1446. LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
  1447. camera_offset_dir.normalize();
  1448. mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
  1449. }
  1450. startCameraAnimation();
  1451. }
  1452. //-----------------------------------------------------------------------------
  1453. // cameraOrbitAround()
  1454. //-----------------------------------------------------------------------------
  1455. void LLAgent::cameraOrbitAround(const F32 radians)
  1456. {
  1457. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  1458. if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
  1459. {
  1460. // do nothing for hud selection
  1461. }
  1462. else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON || mCameraMode == CAMERA_MODE_FOLLOW))
  1463. {
  1464. mFrameAgent.rotate(radians, getReferenceUpVector());
  1465. }
  1466. else
  1467. {
  1468. mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f);
  1469. cameraZoomIn(1.f);
  1470. }
  1471. }
  1472. //-----------------------------------------------------------------------------
  1473. // cameraOrbitOver()
  1474. //-----------------------------------------------------------------------------
  1475. void LLAgent::cameraOrbitOver(const F32 angle)
  1476. {
  1477. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  1478. if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
  1479. {
  1480. // do nothing for hud selection
  1481. }
  1482. else if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
  1483. {
  1484. pitch(angle);
  1485. }
  1486. else
  1487. {
  1488. LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
  1489. camera_offset_unit.normalize();
  1490. F32 angle_from_up = acos( camera_offset_unit * getReferenceUpVector() );
  1491. LLVector3d left_axis;
  1492. left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
  1493. F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD);
  1494. mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis);
  1495. cameraZoomIn(1.f);
  1496. }
  1497. }
  1498. //-----------------------------------------------------------------------------
  1499. // cameraZoomIn()
  1500. //-----------------------------------------------------------------------------
  1501. void LLAgent::cameraZoomIn(const F32 fraction)
  1502. {
  1503. if (gDisconnected)
  1504. {
  1505. return;
  1506. }
  1507. LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
  1508. if (selection->getObjectCount() && selection->getSelectType() == SELECT_TYPE_HUD)
  1509. {
  1510. // just update hud zoom level
  1511. mHUDTargetZoom /= fraction;
  1512. return;
  1513. }
  1514. LLVector3d camera_offset(mCameraFocusOffsetTarget);
  1515. LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
  1516. F32 min_zoom = LAND_MIN_ZOOM;
  1517. F32 current_distance = (F32)camera_offset_unit.normalize();
  1518. F32 new_distance = current_distance * fraction;
  1519. // Don't move through focus point
  1520. if (mFocusObject)
  1521. {
  1522. LLVector3 camera_offset_dir((F32)camera_offset_unit.mdV[VX], (F32)camera_offset_unit.mdV[VY], (F32)camera_offset_unit.mdV[VZ]);
  1523. if (mFocusObject->isAvatar())
  1524. {
  1525. calcCameraMinDistance(min_zoom);
  1526. }
  1527. else
  1528. {
  1529. min_zoom = OBJECT_MIN_ZOOM;
  1530. }
  1531. }
  1532. new_distance = llmax(new_distance, min_zoom); 
  1533. // Don't zoom too far back
  1534. const F32 DIST_FUDGE = 16.f; // meters
  1535. F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
  1536.  LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
  1537. if (new_distance > max_distance)
  1538. {
  1539. new_distance = max_distance;
  1540. /*
  1541. // Unless camera is unlocked
  1542. if (!LLViewerCamera::sDisableCameraConstraints)
  1543. {
  1544. return;
  1545. }
  1546. */
  1547. }
  1548. if( cameraCustomizeAvatar() )
  1549. {
  1550. new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
  1551. }
  1552. mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
  1553. }
  1554. //-----------------------------------------------------------------------------
  1555. // cameraOrbitIn()
  1556. //-----------------------------------------------------------------------------
  1557. void LLAgent::cameraOrbitIn(const F32 meters)
  1558. {
  1559. if (mFocusOnAvatar && mCameraMode == CAMERA_MODE_THIRD_PERSON)
  1560. {
  1561. F32 camera_offset_dist = llmax(0.001f, getCameraOffsetInitial().magVec() * gSavedSettings.getF32("CameraOffsetScale"));
  1562. mCameraZoomFraction = (mTargetCameraDistance - meters) / camera_offset_dist;
  1563. if (!gSavedSettings.getBOOL("FreezeTime") && mCameraZoomFraction < MIN_ZOOM_FRACTION && meters > 0.f)
  1564. {
  1565. // No need to animate, camera is already there.
  1566. changeCameraToMouselook(FALSE);
  1567. }
  1568. mCameraZoomFraction = llclamp(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION);
  1569. }
  1570. else
  1571. {
  1572. LLVector3d camera_offset(mCameraFocusOffsetTarget);
  1573. LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
  1574. F32 current_distance = (F32)camera_offset_unit.normalize();
  1575. F32 new_distance = current_distance - meters;
  1576. F32 min_zoom = LAND_MIN_ZOOM;
  1577. // Don't move through focus point
  1578. if (mFocusObject.notNull())
  1579. {
  1580. if (mFocusObject->isAvatar())
  1581. {
  1582. min_zoom = AVATAR_MIN_ZOOM;
  1583. }
  1584. else
  1585. {
  1586. min_zoom = OBJECT_MIN_ZOOM;
  1587. }
  1588. }
  1589. new_distance = llmax(new_distance, min_zoom);
  1590. // Don't zoom too far back
  1591. const F32 DIST_FUDGE = 16.f; // meters
  1592. F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 
  1593.  LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
  1594. if (new_distance > max_distance)
  1595. {
  1596. // Unless camera is unlocked
  1597. if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
  1598. {
  1599. return;
  1600. }
  1601. }
  1602. if( CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode() )
  1603. {
  1604. new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
  1605. }
  1606. // Compute new camera offset
  1607. mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
  1608. cameraZoomIn(1.f);
  1609. }
  1610. }
  1611. //-----------------------------------------------------------------------------
  1612. // cameraPanIn()
  1613. //-----------------------------------------------------------------------------
  1614. void LLAgent::cameraPanIn(F32 meters)
  1615. {
  1616. LLVector3d at_axis;
  1617. at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis());
  1618. mFocusTargetGlobal += meters * at_axis;
  1619. mFocusGlobal = mFocusTargetGlobal;
  1620. // don't enforce zoom constraints as this is the only way for users to get past them easily
  1621. updateFocusOffset();
  1622. // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
  1623. mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
  1624. }
  1625. //-----------------------------------------------------------------------------
  1626. // cameraPanLeft()
  1627. //-----------------------------------------------------------------------------
  1628. void LLAgent::cameraPanLeft(F32 meters)
  1629. {
  1630. LLVector3d left_axis;
  1631. left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis());
  1632. mFocusTargetGlobal += meters * left_axis;
  1633. mFocusGlobal = mFocusTargetGlobal;
  1634. // disable smoothing for camera pan, which causes some residents unhappiness
  1635. mCameraSmoothingStop = TRUE;
  1636. cameraZoomIn(1.f);
  1637. updateFocusOffset();
  1638. // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx
  1639. mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
  1640. }
  1641. //-----------------------------------------------------------------------------
  1642. // cameraPanUp()
  1643. //-----------------------------------------------------------------------------
  1644. void LLAgent::cameraPanUp(F32 meters)
  1645. {
  1646. LLVector3d up_axis;
  1647. up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis());
  1648. mFocusTargetGlobal += meters * up_axis;
  1649. mFocusGlobal = mFocusTargetGlobal;
  1650. // disable smoothing for camera pan, which causes some residents unhappiness
  1651. mCameraSmoothingStop = TRUE;
  1652. cameraZoomIn(1.f);
  1653. updateFocusOffset();
  1654. // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx
  1655. mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal();
  1656. }
  1657. //-----------------------------------------------------------------------------
  1658. // setKey()
  1659. //-----------------------------------------------------------------------------
  1660. void LLAgent::setKey(const S32 direction, S32 &key)
  1661. {
  1662. if (direction > 0)
  1663. {
  1664. key = 1;
  1665. }
  1666. else if (direction < 0)
  1667. {
  1668. key = -1;
  1669. }
  1670. else
  1671. {
  1672. key = 0;
  1673. }
  1674. }
  1675. //-----------------------------------------------------------------------------
  1676. // getControlFlags()
  1677. //-----------------------------------------------------------------------------
  1678. U32 LLAgent::getControlFlags()
  1679. {
  1680. /*
  1681. // HACK -- avoids maintenance of control flags when camera mode is turned on or off,
  1682. // only worries about it when the flags are measured
  1683. if (mCameraMode == CAMERA_MODE_MOUSELOOK) 
  1684. {
  1685. if ( !(mControlFlags & AGENT_CONTROL_MOUSELOOK) )
  1686. {
  1687. mControlFlags |= AGENT_CONTROL_MOUSELOOK;
  1688. }
  1689. }
  1690. */
  1691. return mControlFlags;
  1692. }
  1693. //-----------------------------------------------------------------------------
  1694. // setControlFlags()
  1695. //-----------------------------------------------------------------------------
  1696. void LLAgent::setControlFlags(U32 mask)
  1697. {
  1698. mControlFlags |= mask;
  1699. mbFlagsDirty = TRUE;
  1700. }
  1701. //-----------------------------------------------------------------------------
  1702. // clearControlFlags()
  1703. //-----------------------------------------------------------------------------
  1704. void LLAgent::clearControlFlags(U32 mask)
  1705. {
  1706. U32 old_flags = mControlFlags;
  1707. mControlFlags &= ~mask;
  1708. if (old_flags != mControlFlags)
  1709. {
  1710. mbFlagsDirty = TRUE;
  1711. }
  1712. }
  1713. //-----------------------------------------------------------------------------
  1714. // controlFlagsDirty()
  1715. //-----------------------------------------------------------------------------
  1716. BOOL LLAgent::controlFlagsDirty() const
  1717. {
  1718. return mbFlagsDirty;
  1719. }
  1720. //-----------------------------------------------------------------------------
  1721. // enableControlFlagReset()
  1722. //-----------------------------------------------------------------------------
  1723. void LLAgent::enableControlFlagReset()
  1724. {
  1725. mbFlagsNeedReset = TRUE;
  1726. }
  1727. //-----------------------------------------------------------------------------
  1728. // resetControlFlags()
  1729. //-----------------------------------------------------------------------------
  1730. void LLAgent::resetControlFlags()
  1731. {
  1732. if (mbFlagsNeedReset)
  1733. {
  1734. mbFlagsNeedReset = FALSE;
  1735. mbFlagsDirty = FALSE;
  1736. // reset all of the ephemeral flags
  1737. // some flags are managed elsewhere
  1738. mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK;
  1739. }
  1740. }
  1741. //-----------------------------------------------------------------------------
  1742. // setAFK()
  1743. //-----------------------------------------------------------------------------
  1744. void LLAgent::setAFK()
  1745. {
  1746. // Drones can't go AFK
  1747. if (gNoRender)
  1748. {
  1749. return;
  1750. }
  1751. if (!gAgent.getRegion())
  1752. {
  1753. // Don't set AFK if we're not talking to a region yet.
  1754. return;
  1755. }
  1756. if (!(mControlFlags & AGENT_CONTROL_AWAY))
  1757. {
  1758. sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
  1759. setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
  1760. gAwayTimer.start();
  1761. if (gAFKMenu)
  1762. {
  1763. gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway"));
  1764. }
  1765. }
  1766. }
  1767. //-----------------------------------------------------------------------------
  1768. // clearAFK()
  1769. //-----------------------------------------------------------------------------
  1770. void LLAgent::clearAFK()
  1771. {
  1772. gAwayTriggerTimer.reset();
  1773. // Gods can sometimes get into away state (via gestures)
  1774. // without setting the appropriate control flag. JC
  1775. LLVOAvatar* av = mAvatarObject;
  1776. if (mControlFlags & AGENT_CONTROL_AWAY
  1777. || (av
  1778. && (av->mSignaledAnimations.find(ANIM_AGENT_AWAY) != av->mSignaledAnimations.end())))
  1779. {
  1780. sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
  1781. clearControlFlags(AGENT_CONTROL_AWAY);
  1782. if (gAFKMenu)
  1783. {
  1784. gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
  1785. }
  1786. }
  1787. }
  1788. //-----------------------------------------------------------------------------
  1789. // getAFK()
  1790. //-----------------------------------------------------------------------------
  1791. BOOL LLAgent::getAFK() const
  1792. {
  1793. return (mControlFlags & AGENT_CONTROL_AWAY) != 0;
  1794. }
  1795. //-----------------------------------------------------------------------------
  1796. // setBusy()
  1797. //-----------------------------------------------------------------------------
  1798. void LLAgent::setBusy()
  1799. {
  1800. sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START);
  1801. mIsBusy = TRUE;
  1802. if (gBusyMenu)
  1803. {
  1804. gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy"));
  1805. }
  1806. LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true);
  1807. }
  1808. //-----------------------------------------------------------------------------
  1809. // clearBusy()
  1810. //-----------------------------------------------------------------------------
  1811. void LLAgent::clearBusy()
  1812. {
  1813. mIsBusy = FALSE;
  1814. sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
  1815. if (gBusyMenu)
  1816. {
  1817. gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy"));
  1818. }
  1819. LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false);
  1820. }
  1821. //-----------------------------------------------------------------------------
  1822. // getBusy()
  1823. //-----------------------------------------------------------------------------
  1824. BOOL LLAgent::getBusy() const
  1825. {
  1826. return mIsBusy;
  1827. }
  1828. //-----------------------------------------------------------------------------
  1829. // startAutoPilotGlobal()
  1830. //-----------------------------------------------------------------------------
  1831. 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)
  1832. {
  1833. if (!gAgent.getAvatarObject())
  1834. {
  1835. return;
  1836. }
  1837. mAutoPilotFinishedCallback = finish_callback;
  1838. mAutoPilotCallbackData = callback_data;
  1839. mAutoPilotRotationThreshold = rot_threshold;
  1840. mAutoPilotBehaviorName = behavior_name;
  1841. LLVector3d delta_pos( target_global );
  1842. delta_pos -= getPositionGlobal();
  1843. F64 distance = delta_pos.magVec();
  1844. LLVector3d trace_target = target_global;
  1845. trace_target.mdV[VZ] -= 10.f;
  1846. LLVector3d intersection;
  1847. LLVector3 normal;
  1848. LLViewerObject *hit_obj;
  1849. F32 heightDelta = LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, trace_target, intersection, normal, &hit_obj);
  1850. if (stop_distance > 0.f)
  1851. {
  1852. mAutoPilotStopDistance = stop_distance;
  1853. }
  1854. else
  1855. {
  1856. // Guess at a reasonable stop distance.
  1857. mAutoPilotStopDistance = fsqrtf( distance );
  1858. if (mAutoPilotStopDistance < 0.5f) 
  1859. {
  1860. mAutoPilotStopDistance = 0.5f;
  1861. }
  1862. }
  1863. mAutoPilotFlyOnStop = getFlying();
  1864. if (distance > 30.0)
  1865. {
  1866. setFlying(TRUE);
  1867. }
  1868. if ( distance > 1.f && heightDelta > (sqrtf(mAutoPilotStopDistance) + 1.f))
  1869. {
  1870. setFlying(TRUE);
  1871. mAutoPilotFlyOnStop = TRUE;
  1872. }
  1873. mAutoPilot = TRUE;
  1874. mAutoPilotTargetGlobal = target_global;
  1875. // trace ray down to find height of destination from ground
  1876. LLVector3d traceEndPt = target_global;
  1877. traceEndPt.mdV[VZ] -= 20.f;
  1878. LLVector3d targetOnGround;
  1879. LLVector3 groundNorm;
  1880. LLViewerObject *obj;
  1881. LLWorld::getInstance()->resolveStepHeightGlobal(NULL, target_global, traceEndPt, targetOnGround, groundNorm, &obj);
  1882. F64 target_height = llmax((F64)gAgent.getAvatarObject()->getPelvisToFoot(), target_global.mdV[VZ] - targetOnGround.mdV[VZ]);
  1883. // clamp z value of target to minimum height above ground
  1884. mAutoPilotTargetGlobal.mdV[VZ] = targetOnGround.mdV[VZ] + target_height;
  1885. mAutoPilotTargetDist = (F32)dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal);
  1886. if (target_rotation)
  1887. {
  1888. mAutoPilotUseRotation = TRUE;
  1889. mAutoPilotTargetFacing = LLVector3::x_axis * *target_rotation;
  1890. mAutoPilotTargetFacing.mV[VZ] = 0.f;
  1891. mAutoPilotTargetFacing.normalize();
  1892. }
  1893. else
  1894. {
  1895. mAutoPilotUseRotation = FALSE;
  1896. }
  1897. mAutoPilotNoProgressFrameCount = 0;
  1898. }
  1899. //-----------------------------------------------------------------------------
  1900. // startFollowPilot()
  1901. //-----------------------------------------------------------------------------
  1902. void LLAgent::startFollowPilot(const LLUUID &leader_id)
  1903. {
  1904. if (!mAutoPilot) return;
  1905. mLeaderID = leader_id;
  1906. if ( mLeaderID.isNull() ) return;
  1907. LLViewerObject* object = gObjectList.findObject(mLeaderID);
  1908. if (!object) 
  1909. {
  1910. mLeaderID = LLUUID::null;
  1911. return;
  1912. }
  1913. startAutoPilotGlobal(object->getPositionGlobal());
  1914. }
  1915. //-----------------------------------------------------------------------------
  1916. // stopAutoPilot()
  1917. //-----------------------------------------------------------------------------
  1918. void LLAgent::stopAutoPilot(BOOL user_cancel)
  1919. {
  1920. if (mAutoPilot)
  1921. {
  1922. mAutoPilot = FALSE;
  1923. if (mAutoPilotUseRotation && !user_cancel)
  1924. {
  1925. resetAxes(mAutoPilotTargetFacing);
  1926. }
  1927. //NB: auto pilot can terminate for a reason other than reaching the destination
  1928. if (mAutoPilotFinishedCallback)
  1929. {
  1930. mAutoPilotFinishedCallback(!user_cancel && dist_vec(gAgent.getPositionGlobal(), mAutoPilotTargetGlobal) < mAutoPilotStopDistance, mAutoPilotCallbackData);
  1931. }
  1932. mLeaderID = LLUUID::null;
  1933. // If the user cancelled, don't change the fly state
  1934. if (!user_cancel)
  1935. {
  1936. setFlying(mAutoPilotFlyOnStop);
  1937. }
  1938. setControlFlags(AGENT_CONTROL_STOP);
  1939. if (user_cancel && !mAutoPilotBehaviorName.empty())
  1940. {
  1941. if (mAutoPilotBehaviorName == "Sit")
  1942. LLNotificationsUtil::add("CancelledSit");
  1943. else if (mAutoPilotBehaviorName == "Attach")
  1944. LLNotificationsUtil::add("CancelledAttach");
  1945. else
  1946. LLNotificationsUtil::add("Cancelled");
  1947. }
  1948. }
  1949. }
  1950. // Returns necessary agent pitch and yaw changes, radians.
  1951. //-----------------------------------------------------------------------------
  1952. // autoPilot()
  1953. //-----------------------------------------------------------------------------
  1954. void LLAgent::autoPilot(F32 *delta_yaw)
  1955. {
  1956. if (mAutoPilot)
  1957. {
  1958. if (!mLeaderID.isNull())
  1959. {
  1960. LLViewerObject* object = gObjectList.findObject(mLeaderID);
  1961. if (!object) 
  1962. {
  1963. stopAutoPilot();
  1964. return;
  1965. }
  1966. mAutoPilotTargetGlobal = object->getPositionGlobal();
  1967. }
  1968. if (mAvatarObject.isNull())
  1969. {
  1970. return;
  1971. }
  1972. if (mAvatarObject->mInAir)
  1973. {
  1974. setFlying(TRUE);
  1975. }
  1976. LLVector3 at;
  1977. at.setVec(mFrameAgent.getAtAxis());
  1978. LLVector3 target_agent = getPosAgentFromGlobal(mAutoPilotTargetGlobal);
  1979. LLVector3 direction = target_agent - getPositionAgent();
  1980. F32 target_dist = direction.magVec();
  1981. if (target_dist >= mAutoPilotTargetDist)
  1982. {
  1983. mAutoPilotNoProgressFrameCount++;
  1984. if (mAutoPilotNoProgressFrameCount > AUTOPILOT_MAX_TIME_NO_PROGRESS * gFPSClamped)
  1985. {
  1986. stopAutoPilot();
  1987. return;
  1988. }
  1989. }
  1990. mAutoPilotTargetDist = target_dist;
  1991. // Make this a two-dimensional solution
  1992. at.mV[VZ] = 0.f;
  1993. direction.mV[VZ] = 0.f;
  1994. at.normalize();
  1995. F32 xy_distance = direction.normalize();
  1996. F32 yaw = 0.f;
  1997. if (mAutoPilotTargetDist > mAutoPilotStopDistance)
  1998. {
  1999. yaw = angle_between(mFrameAgent.getAtAxis(), direction);
  2000. }
  2001. else if (mAutoPilotUseRotation)
  2002. {
  2003. // we're close now just aim at target facing
  2004. yaw = angle_between(at, mAutoPilotTargetFacing);
  2005. direction = mAutoPilotTargetFacing;
  2006. }
  2007. yaw = 4.f * yaw / gFPSClamped;
  2008. // figure out which direction to turn
  2009. LLVector3 scratch(at % direction);
  2010. if (scratch.mV[VZ] > 0.f)
  2011. {
  2012. setControlFlags(AGENT_CONTROL_YAW_POS);
  2013. }
  2014. else
  2015. {
  2016. yaw = -yaw;
  2017. setControlFlags(AGENT_CONTROL_YAW_NEG);
  2018. }
  2019. *delta_yaw = yaw;
  2020. // Compute when to start slowing down and when to stop
  2021. F32 stop_distance = mAutoPilotStopDistance;
  2022. F32 slow_distance;
  2023. if (getFlying())
  2024. {
  2025. slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
  2026. stop_distance = llmax(2.f, mAutoPilotStopDistance);
  2027. }
  2028. else
  2029. {
  2030. slow_distance = llmax(3.f, mAutoPilotStopDistance + 2.f);
  2031. }
  2032. // If we're flying, handle autopilot points above or below you.
  2033. if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE)
  2034. {
  2035. if (mAvatarObject.notNull())
  2036. {
  2037. F64 current_height = mAvatarObject->getPositionGlobal().mdV[VZ];
  2038. F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height);
  2039. F32 slope = delta_z / xy_distance;
  2040. if (slope > 0.45f && delta_z > 6.f)
  2041. {
  2042. setControlFlags(AGENT_CONTROL_FAST_UP | AGENT_CONTROL_UP_POS);
  2043. }
  2044. else if (slope > 0.002f && delta_z > 0.5f)
  2045. {
  2046. setControlFlags(AGENT_CONTROL_UP_POS);
  2047. }
  2048. else if (slope < -0.45f && delta_z < -6.f && current_height > AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND)
  2049. {
  2050. setControlFlags(AGENT_CONTROL_FAST_UP | AGENT_CONTROL_UP_NEG);
  2051. }
  2052. else if (slope < -0.002f && delta_z < -0.5f && current_height > AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND)
  2053. {
  2054. setControlFlags(AGENT_CONTROL_UP_NEG);
  2055. }
  2056. }
  2057. }
  2058. //  calculate delta rotation to target heading
  2059. F32 delta_target_heading = angle_between(mFrameAgent.getAtAxis(), mAutoPilotTargetFacing);
  2060. if (xy_distance > slow_distance && yaw < (F_PI / 10.f))
  2061. {
  2062. // walking/flying fast
  2063. setControlFlags(AGENT_CONTROL_FAST_AT | AGENT_CONTROL_AT_POS);
  2064. }
  2065. else if (mAutoPilotTargetDist > mAutoPilotStopDistance)
  2066. {
  2067. // walking/flying slow
  2068. if (at * direction > 0.9f)
  2069. {
  2070. setControlFlags(AGENT_CONTROL_AT_POS);
  2071. }
  2072. else if (at * direction < -0.9f)
  2073. {
  2074. setControlFlags(AGENT_CONTROL_AT_NEG);
  2075. }
  2076. }
  2077. // check to see if we need to keep rotating to target orientation
  2078. if (mAutoPilotTargetDist < mAutoPilotStopDistance)
  2079. {
  2080. setControlFlags(AGENT_CONTROL_STOP);
  2081. if(!mAutoPilotUseRotation || (delta_target_heading < mAutoPilotRotationThreshold))
  2082. {
  2083. stopAutoPilot();
  2084. }
  2085. }
  2086. }
  2087. }
  2088. //-----------------------------------------------------------------------------
  2089. // propagate()
  2090. //-----------------------------------------------------------------------------
  2091. void LLAgent::propagate(const F32 dt)
  2092. {
  2093. // Update UI based on agent motion
  2094. LLFloaterMove *floater_move = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
  2095. if (floater_move)
  2096. {
  2097. floater_move->mForwardButton   ->setToggleState( mAtKey > 0 || mWalkKey > 0 );
  2098. floater_move->mBackwardButton  ->setToggleState( mAtKey < 0 || mWalkKey < 0 );
  2099. floater_move->mTurnLeftButton  ->setToggleState( mYawKey > 0.f );
  2100. floater_move->mTurnRightButton ->setToggleState( mYawKey < 0.f );
  2101. floater_move->mMoveUpButton    ->setToggleState( mUpKey > 0 );
  2102. floater_move->mMoveDownButton  ->setToggleState( mUpKey < 0 );
  2103. }
  2104. // handle rotation based on keyboard levels
  2105. const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second
  2106. yaw(YAW_RATE * mYawKey * dt);
  2107. const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second
  2108. pitch(PITCH_RATE * mPitchKey * dt);
  2109. // handle auto-land behavior
  2110. if (mAvatarObject.notNull())
  2111. {
  2112. BOOL in_air = mAvatarObject->mInAir;
  2113. LLVector3 land_vel = getVelocity();
  2114. land_vel.mV[VZ] = 0.f;
  2115. if (!in_air 
  2116. && mUpKey < 0 
  2117. && land_vel.magVecSquared() < MAX_VELOCITY_AUTO_LAND_SQUARED
  2118. && gSavedSettings.getBOOL("AutomaticFly"))
  2119. {
  2120. // land automatically
  2121. setFlying(FALSE);
  2122. }
  2123. }
  2124. // clear keys
  2125. mAtKey = 0;
  2126. mWalkKey = 0;
  2127. mLeftKey = 0;
  2128. mUpKey = 0;
  2129. mYawKey = 0.f;
  2130. mPitchKey = 0.f;
  2131. }
  2132. //-----------------------------------------------------------------------------
  2133. // updateAgentPosition()
  2134. //-----------------------------------------------------------------------------
  2135. void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y)
  2136. {
  2137. propagate(dt);
  2138. // static S32 cameraUpdateCount = 0;
  2139. rotate(yaw_radians, 0, 0, 1);
  2140. //
  2141. // Check for water and land collision, set underwater flag
  2142. //
  2143. updateLookAt(mouse_x, mouse_y);
  2144. }
  2145. //-----------------------------------------------------------------------------
  2146. // updateLookAt()
  2147. //-----------------------------------------------------------------------------
  2148. void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
  2149. {
  2150. static LLVector3 last_at_axis;
  2151. if (mAvatarObject.isNull())
  2152. {
  2153. return;
  2154. }
  2155. LLQuaternion av_inv_rot = ~mAvatarObject->mRoot.getWorldRotation();
  2156. LLVector3 root_at = LLVector3::x_axis * mAvatarObject->mRoot.getWorldRotation();
  2157. if  ((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
  2158. (root_at * last_at_axis > 0.95f ))
  2159. {
  2160. LLVector3 vel = mAvatarObject->getVelocity();
  2161. if (vel.magVecSquared() > 4.f)
  2162. {
  2163. setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, vel * av_inv_rot);
  2164. }
  2165. else
  2166. {
  2167. // *FIX: rotate mframeagent by sit object's rotation?
  2168. LLQuaternion look_rotation = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion(); // use camera's current rotation
  2169. LLVector3 look_offset = LLVector3(2.f, 0.f, 0.f) * look_rotation * av_inv_rot;
  2170. setLookAt(LOOKAT_TARGET_IDLE, mAvatarObject, look_offset);
  2171. }
  2172. last_at_axis = root_at;
  2173. return;
  2174. }
  2175. last_at_axis = root_at;
  2176. if (CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode())
  2177. {
  2178. setLookAt(LOOKAT_TARGET_NONE, mAvatarObject, LLVector3(-2.f, 0.f, 0.f));
  2179. }
  2180. else
  2181. {
  2182. // Move head based on cursor position
  2183. ELookAtType lookAtType = LOOKAT_TARGET_NONE;
  2184. LLVector3 headLookAxis;
  2185. LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
  2186. if (cameraMouselook())
  2187. {
  2188. lookAtType = LOOKAT_TARGET_MOUSELOOK;
  2189. }
  2190. else if (cameraThirdPerson())
  2191. {
  2192. // range from -.5 to .5
  2193. F32 x_from_center = 
  2194. ((F32) mouse_x / (F32) gViewerWindow->getWindowWidthScaled() ) - 0.5f;
  2195. F32 y_from_center = 
  2196. ((F32) mouse_y / (F32) gViewerWindow->getWindowHeightScaled() ) - 0.5f;
  2197. frameCamera.yaw( - x_from_center * gSavedSettings.getF32("YawFromMousePosition") * DEG_TO_RAD);
  2198. frameCamera.pitch( - y_from_center * gSavedSettings.getF32("PitchFromMousePosition") * DEG_TO_RAD);
  2199. lookAtType = LOOKAT_TARGET_FREELOOK;
  2200. }
  2201. headLookAxis = frameCamera.getAtAxis();
  2202. // RN: we use world-space offset for mouselook and freelook
  2203. //headLookAxis = headLookAxis * av_inv_rot;
  2204. setLookAt(lookAtType, mAvatarObject, headLookAxis);
  2205. }
  2206. }
  2207. // friends and operators
  2208. std::ostream& operator<<(std::ostream &s, const LLAgent &agent)
  2209. {
  2210. // This is unfinished, but might never be used. 
  2211. // We'll just leave it for now; we can always delete it.
  2212. s << " { "
  2213.   << "  Frame = " << agent.mFrameAgent << "n"
  2214.   << " }";
  2215. return s;
  2216. }
  2217. // ------------------- Beginning of legacy LLCamera hack ----------------------
  2218. // This section is included for legacy LLCamera support until
  2219. // it is no longer needed.  Some legacy code must exist in 
  2220. // non-legacy functions, and is labeled with "// legacy" comments.
  2221. //-----------------------------------------------------------------------------
  2222. // setAvatarObject()
  2223. //-----------------------------------------------------------------------------
  2224. void LLAgent::setAvatarObject(LLVOAvatarSelf *avatar)
  2225. mAvatarObject = avatar;
  2226. if (!avatar)
  2227. {
  2228. llinfos << "Setting LLAgent::mAvatarObject to NULL" << llendl;
  2229. return;
  2230. }
  2231. if (!mLookAt)
  2232. {
  2233. mLookAt = (LLHUDEffectLookAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_LOOKAT);
  2234. }
  2235. if (!mPointAt)
  2236. {
  2237. mPointAt = (LLHUDEffectPointAt *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINTAT);
  2238. }
  2239. if (!mLookAt.isNull())
  2240. {
  2241. mLookAt->setSourceObject(avatar);
  2242. }
  2243. if (!mPointAt.isNull())
  2244. {
  2245. mPointAt->setSourceObject(avatar);
  2246. }
  2247. }
  2248. // TRUE if your own avatar needs to be rendered.  Usually only
  2249. // in third person and build.
  2250. //-----------------------------------------------------------------------------
  2251. // needsRenderAvatar()
  2252. //-----------------------------------------------------------------------------
  2253. BOOL LLAgent::needsRenderAvatar()
  2254. {
  2255. if (cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson)
  2256. {
  2257. return FALSE;
  2258. }
  2259. return mShowAvatar && mGenderChosen;
  2260. }
  2261. // TRUE if we need to render your own avatar's head.
  2262. BOOL LLAgent::needsRenderHead()
  2263. {
  2264. return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !cameraMouselook());
  2265. }
  2266. //-----------------------------------------------------------------------------
  2267. // startTyping()
  2268. //-----------------------------------------------------------------------------
  2269. void LLAgent::startTyping()
  2270. {
  2271. mTypingTimer.reset();
  2272. if (getRenderState() & AGENT_STATE_TYPING)
  2273. {
  2274. // already typing, don't trigger a different animation
  2275. return;
  2276. }
  2277. setRenderState(AGENT_STATE_TYPING);
  2278. if (mChatTimer.getElapsedTimeF32() < 2.f)
  2279. {
  2280. LLViewerObject* chatter = gObjectList.findObject(mLastChatterID);
  2281. if (chatter && chatter->isAvatar())
  2282. {
  2283. gAgent.setLookAt(LOOKAT_TARGET_RESPOND, chatter, LLVector3::zero);
  2284. }
  2285. }
  2286. if (gSavedSettings.getBOOL("PlayTypingAnim"))
  2287. {
  2288. sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
  2289. }
  2290. LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
  2291. }
  2292. //-----------------------------------------------------------------------------
  2293. // stopTyping()
  2294. //-----------------------------------------------------------------------------
  2295. void LLAgent::stopTyping()
  2296. {
  2297. if (mRenderState & AGENT_STATE_TYPING)
  2298. {
  2299. clearRenderState(AGENT_STATE_TYPING);
  2300. sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
  2301. LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
  2302. }
  2303. }
  2304. //-----------------------------------------------------------------------------
  2305. // setRenderState()
  2306. //-----------------------------------------------------------------------------
  2307. void LLAgent::setRenderState(U8 newstate)
  2308. {
  2309. mRenderState |= newstate;
  2310. }
  2311. //-----------------------------------------------------------------------------
  2312. // clearRenderState()
  2313. //-----------------------------------------------------------------------------
  2314. void LLAgent::clearRenderState(U8 clearstate)
  2315. {
  2316. mRenderState &= ~clearstate;
  2317. }
  2318. //-----------------------------------------------------------------------------
  2319. // getRenderState()
  2320. //-----------------------------------------------------------------------------
  2321. U8 LLAgent::getRenderState()
  2322. {
  2323. if (gNoRender || gKeyboard == NULL)
  2324. {
  2325. return 0;
  2326. }
  2327. // *FIX: don't do stuff in a getter!  This is infinite loop city!
  2328. if ((mTypingTimer.getElapsedTimeF32() > TYPING_TIMEOUT_SECS) 
  2329. && (mRenderState & AGENT_STATE_TYPING))
  2330. {
  2331. stopTyping();
  2332. }
  2333. if ((!LLSelectMgr::getInstance()->getSelection()->isEmpty() && LLSelectMgr::getInstance()->shouldShowSelection())
  2334. || LLToolMgr::getInstance()->getCurrentTool()->isEditing() )
  2335. {
  2336. setRenderState(AGENT_STATE_EDITING);
  2337. }
  2338. else
  2339. {
  2340. clearRenderState(AGENT_STATE_EDITING);
  2341. }
  2342. return mRenderState;
  2343. }
  2344. //-----------------------------------------------------------------------------
  2345. //-----------------------------------------------------------------------------
  2346. //-----------------------------------------------------------------------------
  2347. // endAnimationUpdateUI()
  2348. //-----------------------------------------------------------------------------
  2349. void LLAgent::endAnimationUpdateUI()
  2350. {
  2351. if (mCameraMode == mLastCameraMode)
  2352. {
  2353. // We're already done endAnimationUpdateUI for this transition.
  2354. return;
  2355. }
  2356. // clean up UI from mode we're leaving
  2357. if ( mLastCameraMode == CAMERA_MODE_MOUSELOOK )
  2358. {
  2359. // show mouse cursor
  2360. gViewerWindow->showCursor();
  2361. // show menus
  2362. gMenuBarView->setVisible(TRUE);
  2363. LLNavigationBar::getInstance()->setVisible(TRUE);
  2364. gStatusBar->setVisibleForMouselook(true);
  2365. LLBottomTray::getInstance()->onMouselookModeOut();
  2366. LLSideTray::getInstance()->getButtonsPanel()->setVisible(TRUE);
  2367. LLSideTray::getInstance()->updateSidetrayVisibility();
  2368. LLPanelStandStopFlying::getInstance()->setVisible(TRUE);
  2369. LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
  2370. LLFloaterCamera::onLeavingMouseLook();
  2371. // Only pop if we have pushed...
  2372. if (TRUE == mViewsPushed)
  2373. {
  2374. #if 0 // Use this once all floaters are registered
  2375. LLFloaterReg::restoreVisibleInstances();
  2376. #else // Use this for now
  2377. LLFloaterView::skip_list_t skip_list;
  2378. if (LLFloaterReg::findInstance("mini_map"))
  2379. {
  2380. skip_list.insert(LLFloaterReg::findInstance("mini_map"));
  2381. }
  2382. gFloaterView->popVisibleAll(skip_list);
  2383. #endif
  2384. mViewsPushed = FALSE;
  2385. }
  2386. gAgent.setLookAt(LOOKAT_TARGET_CLEAR);
  2387. if( gMorphView )
  2388. {
  2389. gMorphView->setVisible( FALSE );
  2390. }
  2391. // Disable mouselook-specific animations
  2392. if (mAvatarObject.notNull())
  2393. {
  2394. if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
  2395. {
  2396. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_RIFLE_R) != mAvatarObject->mSignaledAnimations.end())
  2397. {
  2398. sendAnimationRequest(ANIM_AGENT_AIM_RIFLE_R, ANIM_REQUEST_STOP);
  2399. sendAnimationRequest(ANIM_AGENT_HOLD_RIFLE_R, ANIM_REQUEST_START);
  2400. }
  2401. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_HANDGUN_R) != mAvatarObject->mSignaledAnimations.end())
  2402. {
  2403. sendAnimationRequest(ANIM_AGENT_AIM_HANDGUN_R, ANIM_REQUEST_STOP);
  2404. sendAnimationRequest(ANIM_AGENT_HOLD_HANDGUN_R, ANIM_REQUEST_START);
  2405. }
  2406. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_BAZOOKA_R) != mAvatarObject->mSignaledAnimations.end())
  2407. {
  2408. sendAnimationRequest(ANIM_AGENT_AIM_BAZOOKA_R, ANIM_REQUEST_STOP);
  2409. sendAnimationRequest(ANIM_AGENT_HOLD_BAZOOKA_R, ANIM_REQUEST_START);
  2410. }
  2411. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_AIM_BOW_L) != mAvatarObject->mSignaledAnimations.end())
  2412. {
  2413. sendAnimationRequest(ANIM_AGENT_AIM_BOW_L, ANIM_REQUEST_STOP);
  2414. sendAnimationRequest(ANIM_AGENT_HOLD_BOW_L, ANIM_REQUEST_START);
  2415. }
  2416. }
  2417. }
  2418. }
  2419. else
  2420. if( mLastCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR )
  2421. {
  2422. // make sure we ask to save changes
  2423. LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
  2424. if( gMorphView )
  2425. {
  2426. gMorphView->setVisible( FALSE );
  2427. }
  2428. if (mAvatarObject.notNull())
  2429. {
  2430. if(mCustomAnim)
  2431. {
  2432. sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_STOP);
  2433. sendAnimationRequest(ANIM_AGENT_CUSTOMIZE_DONE, ANIM_REQUEST_START);
  2434. mCustomAnim = FALSE ;
  2435. }
  2436. }
  2437. setLookAt(LOOKAT_TARGET_CLEAR);
  2438. }
  2439. //---------------------------------------------------------------------
  2440. // Set up UI for mode we're entering
  2441. //---------------------------------------------------------------------
  2442. if (mCameraMode == CAMERA_MODE_MOUSELOOK)
  2443. {
  2444. // hide menus
  2445. gMenuBarView->setVisible(FALSE);
  2446. LLNavigationBar::getInstance()->setVisible(FALSE);
  2447. gStatusBar->setVisibleForMouselook(false);
  2448. LLBottomTray::getInstance()->onMouselookModeIn();
  2449. LLSideTray::getInstance()->getButtonsPanel()->setVisible(FALSE);
  2450. LLSideTray::getInstance()->updateSidetrayVisibility();
  2451. LLPanelStandStopFlying::getInstance()->setVisible(FALSE);
  2452. // clear out camera lag effect
  2453. mCameraLag.clearVec();
  2454. // JC - Added for always chat in third person option
  2455. gFocusMgr.setKeyboardFocus(NULL);
  2456. LLToolMgr::getInstance()->setCurrentToolset(gMouselookToolset);
  2457. mViewsPushed = TRUE;
  2458. // hide all floaters except the mini map
  2459. #if 0 // Use this once all floaters are registered
  2460. std::set<std::string> exceptions;
  2461. exceptions.insert("mini_map");
  2462. LLFloaterReg::hideVisibleInstances(exceptions);
  2463. #else // Use this for now
  2464. LLFloaterView::skip_list_t skip_list;
  2465. skip_list.insert(LLFloaterReg::findInstance("mini_map"));
  2466. gFloaterView->pushVisibleAll(FALSE, skip_list);
  2467. #endif
  2468. if( gMorphView )
  2469. {
  2470. gMorphView->setVisible(FALSE);
  2471. }
  2472. gConsole->setVisible( TRUE );
  2473. if (mAvatarObject.notNull())
  2474. {
  2475. // Trigger mouselook-specific animations
  2476. if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_HOLD_ANIMS, NUM_AGENT_GUN_HOLD_ANIMS) )
  2477. {
  2478. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_RIFLE_R) != mAvatarObject->mSignaledAnimations.end())
  2479. {
  2480. sendAnimationRequest(ANIM_AGENT_HOLD_RIFLE_R, ANIM_REQUEST_STOP);
  2481. sendAnimationRequest(ANIM_AGENT_AIM_RIFLE_R, ANIM_REQUEST_START);
  2482. }
  2483. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_HANDGUN_R) != mAvatarObject->mSignaledAnimations.end())
  2484. {
  2485. sendAnimationRequest(ANIM_AGENT_HOLD_HANDGUN_R, ANIM_REQUEST_STOP);
  2486. sendAnimationRequest(ANIM_AGENT_AIM_HANDGUN_R, ANIM_REQUEST_START);
  2487. }
  2488. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_BAZOOKA_R) != mAvatarObject->mSignaledAnimations.end())
  2489. {
  2490. sendAnimationRequest(ANIM_AGENT_HOLD_BAZOOKA_R, ANIM_REQUEST_STOP);
  2491. sendAnimationRequest(ANIM_AGENT_AIM_BAZOOKA_R, ANIM_REQUEST_START);
  2492. }
  2493. if (mAvatarObject->mSignaledAnimations.find(ANIM_AGENT_HOLD_BOW_L) != mAvatarObject->mSignaledAnimations.end())
  2494. {
  2495. sendAnimationRequest(ANIM_AGENT_HOLD_BOW_L, ANIM_REQUEST_STOP);
  2496. sendAnimationRequest(ANIM_AGENT_AIM_BOW_L, ANIM_REQUEST_START);
  2497. }
  2498. }
  2499. if (mAvatarObject->getParent())
  2500. {
  2501. LLVector3 at_axis = LLViewerCamera::getInstance()->getAtAxis();
  2502. LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
  2503. if (root_object->flagCameraDecoupled())
  2504. {
  2505. resetAxes(at_axis);
  2506. }
  2507. else
  2508. {
  2509. resetAxes(at_axis * ~((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation());
  2510. }
  2511. }
  2512. }
  2513. }
  2514. else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
  2515. {
  2516. LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
  2517. if( gMorphView )
  2518. {
  2519. gMorphView->setVisible( TRUE );
  2520. }
  2521. // freeze avatar
  2522. if (mAvatarObject.notNull())
  2523. {
  2524. mPauseRequest = mAvatarObject->requestPause();
  2525. }
  2526. }
  2527. if (getAvatarObject())
  2528. {
  2529. getAvatarObject()->updateAttachmentVisibility(mCameraMode);
  2530. }
  2531. gFloaterTools->dirty();
  2532. // Don't let this be called more than once if the camera
  2533. // mode hasn't changed.  --JC
  2534. mLastCameraMode = mCameraMode;
  2535. }
  2536. //-----------------------------------------------------------------------------
  2537. // updateCamera()
  2538. //-----------------------------------------------------------------------------
  2539. void LLAgent::updateCamera()
  2540. {
  2541. //Ventrella - changed camera_skyward to the new global "mCameraUpVector"
  2542. mCameraUpVector = LLVector3::z_axis;
  2543. //LLVector3 camera_skyward(0.f, 0.f, 1.f);
  2544. //end Ventrella
  2545. U32 camera_mode = mCameraAnimating ? mLastCameraMode : mCameraMode;
  2546. validateFocusObject();
  2547. if (mAvatarObject.notNull() && 
  2548. mAvatarObject->isSitting() &&
  2549. camera_mode == CAMERA_MODE_MOUSELOOK)
  2550. {
  2551. //Ventrella
  2552. //changed camera_skyward to the new global "mCameraUpVector"
  2553. mCameraUpVector = mCameraUpVector * mAvatarObject->getRenderRotation();
  2554. //end Ventrella
  2555. }
  2556. if (cameraThirdPerson() && mFocusOnAvatar && LLFollowCamMgr::getActiveFollowCamParams())
  2557. {
  2558. changeCameraToFollow();
  2559. }
  2560. //Ventrella
  2561. //NOTE - this needs to be integrated into a general upVector system here within llAgent. 
  2562. if ( camera_mode == CAMERA_MODE_FOLLOW && mFocusOnAvatar )
  2563. {
  2564. mCameraUpVector = mFollowCam.getUpVector();
  2565. }
  2566. //end Ventrella
  2567. if (mSitCameraEnabled)
  2568. {
  2569. if (mSitCameraReferenceObject->isDead())
  2570. {
  2571. setSitCamera(LLUUID::null);
  2572. }
  2573. }
  2574. // Update UI with our camera inputs
  2575. LLFloaterCamera* camera_floater = LLFloaterReg::findTypedInstance<LLFloaterCamera>("camera");
  2576. if (camera_floater)
  2577. {
  2578. camera_floater->mRotate->setToggleState(
  2579. mOrbitRightKey > 0.f, // left
  2580. mOrbitUpKey > 0.f, // top
  2581. mOrbitLeftKey > 0.f, // right
  2582. mOrbitDownKey > 0.f); // bottom
  2583. camera_floater->mTrack->setToggleState(
  2584. mPanLeftKey > 0.f, // left
  2585. mPanUpKey > 0.f, // top
  2586. mPanRightKey > 0.f, // right
  2587. mPanDownKey > 0.f); // bottom
  2588. }
  2589. // Handle camera movement based on keyboard.
  2590. const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second
  2591. const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD; // radians per second
  2592. const F32 PAN_RATE = 5.f; // meters per second
  2593. if( mOrbitUpKey || mOrbitDownKey )
  2594. {
  2595. F32 input_rate = mOrbitUpKey - mOrbitDownKey;
  2596. cameraOrbitOver( input_rate * ORBIT_OVER_RATE / gFPSClamped );
  2597. }
  2598. if( mOrbitLeftKey || mOrbitRightKey)
  2599. {
  2600. F32 input_rate = mOrbitLeftKey - mOrbitRightKey;
  2601. cameraOrbitAround( input_rate * ORBIT_AROUND_RATE / gFPSClamped );
  2602. }
  2603. if( mOrbitInKey || mOrbitOutKey )
  2604. {
  2605. F32 input_rate = mOrbitInKey - mOrbitOutKey;
  2606. LLVector3d to_focus = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin()) - calcFocusPositionTargetGlobal();
  2607. F32 distance_to_focus = (F32)to_focus.magVec();
  2608. // Move at distance (in meters) meters per second
  2609. cameraOrbitIn( input_rate * distance_to_focus / gFPSClamped );
  2610. }
  2611. if( mPanInKey || mPanOutKey )
  2612. {
  2613. F32 input_rate = mPanInKey - mPanOutKey;
  2614. cameraPanIn( input_rate * PAN_RATE / gFPSClamped );
  2615. }
  2616. if( mPanRightKey || mPanLeftKey )
  2617. {
  2618. F32 input_rate = mPanRightKey - mPanLeftKey;
  2619. cameraPanLeft( input_rate * -PAN_RATE / gFPSClamped );
  2620. }
  2621. if( mPanUpKey || mPanDownKey )
  2622. {
  2623. F32 input_rate = mPanUpKey - mPanDownKey;
  2624. cameraPanUp( input_rate * PAN_RATE / gFPSClamped );
  2625. }
  2626. // Clear camera keyboard keys.
  2627. mOrbitLeftKey = 0.f;
  2628. mOrbitRightKey = 0.f;
  2629. mOrbitUpKey = 0.f;
  2630. mOrbitDownKey = 0.f;
  2631. mOrbitInKey = 0.f;
  2632. mOrbitOutKey = 0.f;
  2633. mPanRightKey = 0.f;
  2634. mPanLeftKey = 0.f;
  2635. mPanUpKey = 0.f;
  2636. mPanDownKey = 0.f;
  2637. mPanInKey = 0.f;
  2638. mPanOutKey = 0.f;
  2639. // lerp camera focus offset
  2640. mCameraFocusOffset = lerp(mCameraFocusOffset, mCameraFocusOffsetTarget, LLCriticalDamp::getInterpolant(CAMERA_FOCUS_HALF_LIFE));
  2641. //Ventrella
  2642. if ( mCameraMode == CAMERA_MODE_FOLLOW )
  2643. {
  2644. if ( mAvatarObject.notNull() )
  2645. {
  2646. //--------------------------------------------------------------------------------
  2647. // this is where the avatar's position and rotation are given to followCam, and 
  2648. // where it is updated. All three of its attributes are updated: (1) position, 
  2649. // (2) focus, and (3) upvector. They can then be queried elsewhere in llAgent.
  2650. //--------------------------------------------------------------------------------
  2651. // *TODO: use combined rotation of frameagent and sit object
  2652. LLQuaternion avatarRotationForFollowCam = mAvatarObject->isSitting() ? mAvatarObject->getRenderRotation() : mFrameAgent.getQuaternion();
  2653. LLFollowCamParams* current_cam = LLFollowCamMgr::getActiveFollowCamParams();
  2654. if (current_cam)
  2655. {
  2656. mFollowCam.copyParams(*current_cam);
  2657. mFollowCam.setSubjectPositionAndRotation( mAvatarObject->getRenderPosition(), avatarRotationForFollowCam );
  2658. mFollowCam.update();
  2659. LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
  2660. }
  2661. else
  2662. {
  2663. changeCameraToThirdPerson(TRUE);
  2664. }
  2665. }
  2666. }
  2667. // end Ventrella
  2668. BOOL hit_limit;
  2669. LLVector3d camera_pos_global;
  2670. LLVector3d camera_target_global = calcCameraPositionTargetGlobal(&hit_limit);
  2671. mCameraVirtualPositionAgent = getPosAgentFromGlobal(camera_target_global);
  2672. LLVector3d focus_target_global = calcFocusPositionTargetGlobal();
  2673. // perform field of view correction
  2674. mCameraFOVZoomFactor = calcCameraFOVZoomFactor();
  2675. camera_target_global = focus_target_global + (camera_target_global - focus_target_global) * (1.f + mCameraFOVZoomFactor);
  2676. mShowAvatar = TRUE; // can see avatar by default
  2677. // Adjust position for animation
  2678. if (mCameraAnimating)
  2679. {
  2680. F32 time = mAnimationTimer.getElapsedTimeF32();
  2681. // yet another instance of critically damped motion, hooray!
  2682. // F32 fraction_of_animation = 1.f - pow(2.f, -time / CAMERA_ZOOM_HALF_LIFE);
  2683. // linear interpolation
  2684. F32 fraction_of_animation = time / mAnimationDuration;
  2685. BOOL isfirstPerson = mCameraMode == CAMERA_MODE_MOUSELOOK;
  2686. BOOL wasfirstPerson = mLastCameraMode == CAMERA_MODE_MOUSELOOK;
  2687. F32 fraction_animation_to_skip;
  2688. if (mAnimationCameraStartGlobal == camera_target_global)
  2689. {
  2690. fraction_animation_to_skip = 0.f;
  2691. }
  2692. else
  2693. {
  2694. LLVector3d cam_delta = mAnimationCameraStartGlobal - camera_target_global;
  2695. fraction_animation_to_skip = HEAD_BUFFER_SIZE / (F32)cam_delta.magVec();
  2696. }
  2697. F32 animation_start_fraction = (wasfirstPerson) ? fraction_animation_to_skip : 0.f;
  2698. F32 animation_finish_fraction =  (isfirstPerson) ? (1.f - fraction_animation_to_skip) : 1.f;
  2699. if (fraction_of_animation < animation_finish_fraction)
  2700. {
  2701. if (fraction_of_animation < animation_start_fraction || fraction_of_animation > animation_finish_fraction )
  2702. {
  2703. mShowAvatar = FALSE;
  2704. }
  2705. // ...adjust position for animation
  2706. F32 smooth_fraction_of_animation = llsmoothstep(0.0f, 1.0f, fraction_of_animation);
  2707. camera_pos_global = lerp(mAnimationCameraStartGlobal, camera_target_global, smooth_fraction_of_animation);
  2708. mFocusGlobal = lerp(mAnimationFocusStartGlobal, focus_target_global, smooth_fraction_of_animation);
  2709. }
  2710. else
  2711. {
  2712. // ...animation complete
  2713. mCameraAnimating = FALSE;
  2714. camera_pos_global = camera_target_global;
  2715. mFocusGlobal = focus_target_global;
  2716. endAnimationUpdateUI();
  2717. mShowAvatar = TRUE;
  2718. }
  2719. if (getAvatarObject() && mCameraMode != CAMERA_MODE_MOUSELOOK)
  2720. {
  2721. getAvatarObject()->updateAttachmentVisibility(mCameraMode);
  2722. }
  2723. }
  2724. else 
  2725. {
  2726. camera_pos_global = camera_target_global;
  2727. mFocusGlobal = focus_target_global;
  2728. mShowAvatar = TRUE;
  2729. }
  2730. // smoothing
  2731. if (TRUE)
  2732. {
  2733. LLVector3d agent_pos = getPositionGlobal();
  2734. LLVector3d camera_pos_agent = camera_pos_global - agent_pos;
  2735. // Sitting on what you're manipulating can cause camera jitter with smoothing. 
  2736. // This turns off smoothing while editing. -MG
  2737. mCameraSmoothingStop |= (BOOL)LLToolMgr::getInstance()->inBuildMode();
  2738. if (cameraThirdPerson() && !mCameraSmoothingStop)