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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llfollowcam.cpp
  3.  * @author Jeffrey Ventrella
  4.  * @brief LLFollowCam class implementation
  5.  *
  6.  * $LicenseInfo:firstyear=2005&license=viewergpl$
  7.  * 
  8.  * Copyright (c) 2005-2010, Linden Research, Inc.
  9.  * 
  10.  * Second Life Viewer Source Code
  11.  * The source code in this file ("Source Code") is provided by Linden Lab
  12.  * to you under the terms of the GNU General Public License, version 2.0
  13.  * ("GPL"), unless you have obtained a separate licensing agreement
  14.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  15.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17.  * 
  18.  * There are special exceptions to the terms and conditions of the GPL as
  19.  * it is applied to this Source Code. View the full text of the exception
  20.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  21.  * online at
  22.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23.  * 
  24.  * By copying, modifying or distributing this software, you acknowledge
  25.  * that you have read and understood your obligations described above,
  26.  * and agree to abide by those obligations.
  27.  * 
  28.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30.  * COMPLETENESS OR PERFORMANCE.
  31.  * $/LicenseInfo$
  32.  */
  33. #include "llviewerprecompiledheaders.h"
  34. #include "llfollowcam.h"
  35. #include "llagent.h"
  36. //-------------------------------------------------------
  37. // class statics
  38. //-------------------------------------------------------
  39. std::map<LLUUID, LLFollowCamParams*> LLFollowCamMgr::sParamMap;
  40. std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
  41. //-------------------------------------------------------
  42. // constants
  43. //-------------------------------------------------------
  44. const F32 ONE_HALF = 0.5; 
  45. const F32 FOLLOW_CAM_ZOOM_FACTOR = 0.1f;
  46. const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT = 0.1f;
  47. const F32 DISTANCE_EPSILON = 0.0001f;
  48. const F32 DEFAULT_MAX_DISTANCE_FROM_SUBJECT = 1000.0; // this will be correctly set on me by my caller
  49. //----------------------------------------------------------------------------------------
  50. // This is how slowly the camera position moves to its ideal position 
  51. //----------------------------------------------------------------------------------------
  52. const F32 FOLLOW_CAM_MIN_POSITION_LAG = 0.0f;
  53. const F32 FOLLOW_CAM_DEFAULT_POSITION_LAG = 0.1f;  
  54. const F32 FOLLOW_CAM_MAX_POSITION_LAG = 3.0f;
  55. //----------------------------------------------------------------------------------------
  56. // This is how slowly the camera focus moves to its subject
  57. //----------------------------------------------------------------------------------------
  58. const F32 FOLLOW_CAM_MIN_FOCUS_LAG = 0.0f;
  59. const F32 FOLLOW_CAM_DEFAULT_FOCUS_LAG = 0.1f;
  60. const F32 FOLLOW_CAM_MAX_FOCUS_LAG = 3.0f;
  61. //----------------------------------------------------------------------------------------
  62. // This is far the position can get from its IDEAL POSITION before it starts getting pulled
  63. //----------------------------------------------------------------------------------------
  64. const F32 FOLLOW_CAM_MIN_POSITION_THRESHOLD = 0.0f;
  65. const F32 FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD = 1.0f;
  66. const F32 FOLLOW_CAM_MAX_POSITION_THRESHOLD = 4.0f;
  67. //----------------------------------------------------------------------------------------
  68. // This is far the focus can get from the subject before it starts getting pulled
  69. //----------------------------------------------------------------------------------------
  70. const F32 FOLLOW_CAM_MIN_FOCUS_THRESHOLD = 0.0f;
  71. const F32 FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD = 1.0f;
  72. const F32 FOLLOW_CAM_MAX_FOCUS_THRESHOLD = 4.0f;
  73. //----------------------------------------------------------------------------------------
  74. // This is the distance the camera wants to be from the subject
  75. //----------------------------------------------------------------------------------------
  76. const F32 FOLLOW_CAM_MIN_DISTANCE = 0.5f;
  77. const F32 FOLLOW_CAM_DEFAULT_DISTANCE = 3.0f;
  78. //const F32 FOLLOW_CAM_MAX_DISTANCE = 10.0f; // from now on I am using mMaxCameraDistantFromSubject
  79. //----------------------------------------------------------------------------------------
  80. // this is an angluar value
  81. // It affects the angle that the camera rises (pitches) in relation 
  82. // to the horizontal plane
  83. //----------------------------------------------------------------------------------------
  84. const F32 FOLLOW_CAM_MIN_PITCH = -45.0f; 
  85. const F32 FOLLOW_CAM_DEFAULT_PITCH =   0.0f;
  86. const F32 FOLLOW_CAM_MAX_PITCH =  80.0f; // keep under 90 degrees - avoid gimble lock!
  87. //----------------------------------------------------------------------------------------
  88. // how high or low the camera considers its ideal focus to be (relative to its subject)
  89. //----------------------------------------------------------------------------------------
  90. const F32 FOLLOW_CAM_MIN_FOCUS_OFFSET = -10.0f;
  91. const LLVector3 FOLLOW_CAM_DEFAULT_FOCUS_OFFSET =  LLVector3(1.0f, 0.f, 0.f);
  92. const F32 FOLLOW_CAM_MAX_FOCUS_OFFSET =  10.0f;
  93. //----------------------------------------------------------------------------------------
  94. // This affects the rate at which the camera adjusts to stay behind the subject
  95. //----------------------------------------------------------------------------------------
  96. const F32 FOLLOW_CAM_MIN_BEHINDNESS_LAG = 0.0f;
  97. const F32 FOLLOW_CAM_DEFAULT_BEHINDNESS_LAG = 0.f;
  98. const F32 FOLLOW_CAM_MAX_BEHINDNESS_LAG = 3.0f;
  99. //---------------------------------------------------------------------------------------------------------------------
  100. // in  degrees: This is the size of the pie slice behind the subject matter within which the camera is free to move
  101. //---------------------------------------------------------------------------------------------------------------------
  102. const F32 FOLLOW_CAM_MIN_BEHINDNESS_ANGLE = 0.0f;
  103. const F32 FOLLOW_CAM_DEFAULT_BEHINDNESS_ANGLE = 10.0f;
  104. const F32 FOLLOW_CAM_MAX_BEHINDNESS_ANGLE = 180.0f;
  105. const F32 FOLLOW_CAM_BEHINDNESS_EPSILON = 1.0f;
  106. //------------------------------------
  107. // Constructor
  108. //------------------------------------
  109. LLFollowCamParams::LLFollowCamParams()
  110. {
  111. mMaxCameraDistantFromSubject = DEFAULT_MAX_DISTANCE_FROM_SUBJECT;
  112. mPositionLocked = false;
  113. mFocusLocked = false;
  114. mUsePosition = false;
  115. mUseFocus = false;
  116. //------------------------------------------------------
  117. // setting the attributes to their defaults
  118. //------------------------------------------------------
  119. setPositionLag ( FOLLOW_CAM_DEFAULT_POSITION_LAG );
  120. setFocusLag ( FOLLOW_CAM_DEFAULT_FOCUS_LAG );
  121. setPositionThreshold( FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD );
  122. setFocusThreshold ( FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD );
  123. setBehindnessLag ( FOLLOW_CAM_DEFAULT_BEHINDNESS_LAG );
  124. setDistance ( FOLLOW_CAM_DEFAULT_DISTANCE );
  125. setPitch ( FOLLOW_CAM_DEFAULT_PITCH );
  126. setFocusOffset ( FOLLOW_CAM_DEFAULT_FOCUS_OFFSET );
  127. setBehindnessAngle ( FOLLOW_CAM_DEFAULT_BEHINDNESS_ANGLE );
  128. setPositionThreshold( FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD );
  129. setFocusThreshold ( FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD );
  130. }
  131. LLFollowCamParams::~LLFollowCamParams() { }
  132. //---------------------------------------------------------
  133. // buncho set methods
  134. //---------------------------------------------------------
  135. //---------------------------------------------------------
  136. void LLFollowCamParams::setPositionLag( F32 p ) 
  137. mPositionLag = llclamp(p, FOLLOW_CAM_MIN_POSITION_LAG, FOLLOW_CAM_MAX_POSITION_LAG); 
  138. }
  139. //---------------------------------------------------------
  140. void LLFollowCamParams::setFocusLag( F32 f ) 
  141. mFocusLag = llclamp(f, FOLLOW_CAM_MIN_FOCUS_LAG, FOLLOW_CAM_MAX_FOCUS_LAG); 
  142. }
  143. //---------------------------------------------------------
  144. void LLFollowCamParams::setPositionThreshold( F32 p ) 
  145. mPositionThreshold = llclamp(p, FOLLOW_CAM_MIN_POSITION_THRESHOLD, FOLLOW_CAM_MAX_POSITION_THRESHOLD); 
  146. }
  147. //---------------------------------------------------------
  148. void LLFollowCamParams::setFocusThreshold( F32 f ) 
  149. mFocusThreshold = llclamp(f, FOLLOW_CAM_MIN_FOCUS_THRESHOLD, FOLLOW_CAM_MAX_FOCUS_THRESHOLD); 
  150. }
  151. //---------------------------------------------------------
  152. void LLFollowCamParams::setPitch( F32 p ) 
  153. mPitch = llclamp(p, FOLLOW_CAM_MIN_PITCH, FOLLOW_CAM_MAX_PITCH); 
  154. }
  155. //---------------------------------------------------------
  156. void LLFollowCamParams::setBehindnessLag( F32 b ) 
  157. mBehindnessLag = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_LAG, FOLLOW_CAM_MAX_BEHINDNESS_LAG); 
  158. }
  159. //---------------------------------------------------------
  160. void LLFollowCamParams::setBehindnessAngle( F32 b ) 
  161. mBehindnessMaxAngle = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_ANGLE, FOLLOW_CAM_MAX_BEHINDNESS_ANGLE); 
  162. }
  163. //---------------------------------------------------------
  164. void LLFollowCamParams::setDistance( F32 d ) 
  165. mDistance = llclamp(d, FOLLOW_CAM_MIN_DISTANCE, mMaxCameraDistantFromSubject); 
  166. }
  167. //---------------------------------------------------------
  168. void LLFollowCamParams::setPositionLocked( bool l ) 
  169. {
  170. mPositionLocked = l;
  171. }
  172. //---------------------------------------------------------
  173. void LLFollowCamParams::setFocusLocked( bool l ) 
  174. {
  175. mFocusLocked = l;
  176. }
  177. //---------------------------------------------------------
  178. void LLFollowCamParams::setFocusOffset( const LLVector3& v ) 
  179. mFocusOffset = v; 
  180. mFocusOffset.clamp(FOLLOW_CAM_MIN_FOCUS_OFFSET, FOLLOW_CAM_MAX_FOCUS_OFFSET);
  181. }
  182. //---------------------------------------------------------
  183. void LLFollowCamParams::setPosition( const LLVector3& p ) 
  184. mUsePosition = true;
  185. mPosition = p;
  186. }
  187. //---------------------------------------------------------
  188. void LLFollowCamParams::setFocus( const LLVector3& f ) 
  189. mUseFocus = true;
  190. mFocus = f;
  191. }
  192. //---------------------------------------------------------
  193. // buncho get methods
  194. //---------------------------------------------------------
  195. F32 LLFollowCamParams::getPositionLag () const { return mPositionLag; }
  196. F32 LLFollowCamParams::getFocusLag () const { return mFocusLag; }
  197. F32 LLFollowCamParams::getPositionThreshold () const { return mPositionThreshold; }
  198. F32 LLFollowCamParams::getFocusThreshold () const { return mFocusThreshold; }
  199. F32 LLFollowCamParams::getDistance () const { return mDistance; }
  200. F32 LLFollowCamParams::getPitch () const { return mPitch; }
  201. LLVector3 LLFollowCamParams::getFocusOffset () const { return mFocusOffset; }
  202. F32 LLFollowCamParams::getBehindnessAngle () const { return mBehindnessMaxAngle; }
  203. F32 LLFollowCamParams::getBehindnessLag () const { return mBehindnessLag; }
  204. LLVector3 LLFollowCamParams::getPosition () const { return mPosition; }
  205. LLVector3 LLFollowCamParams::getFocus () const { return mFocus; }
  206. bool LLFollowCamParams::getPositionLocked () const { return mPositionLocked; }
  207. bool LLFollowCamParams::getFocusLocked () const { return mFocusLocked; }
  208. //------------------------------------
  209. // Constructor
  210. //------------------------------------
  211. LLFollowCam::LLFollowCam() : LLFollowCamParams()
  212. {
  213. mUpVector = LLVector3::z_axis;
  214. mSubjectPosition = LLVector3::zero;
  215. mSubjectRotation = LLQuaternion::DEFAULT;
  216. mZoomedToMinimumDistance = false;
  217. mPitchCos = mPitchSin = 0.f;
  218. mPitchSineAndCosineNeedToBeUpdated = true; 
  219. mSimulatedDistance = mDistance;
  220. }
  221. void LLFollowCam::copyParams(LLFollowCamParams& params)
  222. {
  223. setPositionLag(params.getPositionLag());
  224. setFocusLag(params.getFocusLag());
  225. setFocusThreshold( params.getFocusThreshold());
  226. setPositionThreshold(params.getPositionThreshold());
  227. setPitch(params.getPitch());
  228. setFocusOffset(params.getFocusOffset());
  229. setBehindnessAngle(params.getBehindnessAngle());
  230. setBehindnessLag(params.getBehindnessLag());
  231. setPositionLocked(params.getPositionLocked());
  232. setFocusLocked(params.getFocusLocked());
  233. setDistance(params.getDistance());
  234. if (params.getUsePosition())
  235. {
  236. setPosition(params.getPosition());
  237. }
  238. if (params.getUseFocus())
  239. {
  240. setFocus(params.getFocus());
  241. }
  242. }
  243. //---------------------------------------------------------------------------------------------------------
  244. void LLFollowCam::update()
  245. {
  246. //####################################################################################
  247. // update Focus
  248. //####################################################################################
  249. LLVector3 offsetSubjectPosition = mSubjectPosition + (mFocusOffset * mSubjectRotation);
  250. LLVector3 simulated_pos_agent = gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal);
  251. LLVector3 vectorFromCameraToSubject = offsetSubjectPosition - simulated_pos_agent;
  252. F32 distanceFromCameraToSubject = vectorFromCameraToSubject.magVec();
  253. LLVector3 whereFocusWantsToBe = mFocus;
  254. LLVector3 focus_pt_agent = gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal);
  255. if ( mFocusLocked ) // if focus is locked, only relative focus needs to be updated
  256. {
  257. mRelativeFocus = (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation;
  258. }
  259. else
  260. {
  261. LLVector3 focusOffset = offsetSubjectPosition - focus_pt_agent;
  262. F32 focusOffsetDistance = focusOffset.magVec();
  263. LLVector3 focusOffsetDirection = focusOffset / focusOffsetDistance;
  264. whereFocusWantsToBe = focus_pt_agent + 
  265. (focusOffsetDirection * (focusOffsetDistance - mFocusThreshold));
  266. if ( focusOffsetDistance > mFocusThreshold )
  267. {
  268. // this version normalizes focus threshold by distance 
  269. // so that the effect is not changed with distance
  270. /*
  271. F32 focusThresholdNormalizedByDistance = distanceFromCameraToSubject * mFocusThreshold;
  272. if ( focusOffsetDistance > focusThresholdNormalizedByDistance )
  273. {
  274. LLVector3 focusOffsetDirection = focusOffset / focusOffsetDistance;
  275. F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance;
  276. */
  277. F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag );
  278. focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp );
  279. mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent);
  280. }
  281. mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
  282. }// if focus is not locked ---------------------------------------------
  283. LLVector3 whereCameraPositionWantsToBe = gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal);
  284. if (  mPositionLocked )
  285. {
  286. mRelativePos = (whereCameraPositionWantsToBe - mSubjectPosition) * ~mSubjectRotation;
  287. }
  288. else
  289. {
  290. //####################################################################################
  291. // update Position
  292. //####################################################################################
  293. //-------------------------------------------------------------------------
  294. // I determine the horizontal vector from the camera to the subject
  295. //-------------------------------------------------------------------------
  296. LLVector3 horizontalVectorFromCameraToSubject = vectorFromCameraToSubject;
  297. horizontalVectorFromCameraToSubject.mV[VZ] = 0.0f;
  298. //---------------------------------------------------------
  299. // Now I determine the horizontal distance
  300. //---------------------------------------------------------
  301. F32 horizontalDistanceFromCameraToSubject = horizontalVectorFromCameraToSubject.magVec();  
  302. //---------------------------------------------------------
  303. // Then I get the (normalized) horizontal direction...
  304. //---------------------------------------------------------
  305. LLVector3 horizontalDirectionFromCameraToSubject;
  306. if ( horizontalDistanceFromCameraToSubject < DISTANCE_EPSILON )
  307. {
  308. // make sure we still have a normalized vector if distance is really small 
  309. // (this case is rare and fleeting)
  310. horizontalDirectionFromCameraToSubject = LLVector3::z_axis;
  311. }
  312. else
  313. {
  314. // I'm not using the "normalize" method, because I can just divide by horizontalDistanceFromCameraToSubject
  315. horizontalDirectionFromCameraToSubject = horizontalVectorFromCameraToSubject / horizontalDistanceFromCameraToSubject;
  316. }
  317. //------------------------------------------------------------------------------------------------------------
  318. // Here is where I determine an offset relative to subject position in oder to set the ideal position. 
  319. //------------------------------------------------------------------------------------------------------------
  320. if ( mPitchSineAndCosineNeedToBeUpdated )
  321. {
  322. calculatePitchSineAndCosine();
  323. mPitchSineAndCosineNeedToBeUpdated = false;
  324. }
  325. LLVector3 positionOffsetFromSubject;
  326. positionOffsetFromSubject.setVec
  327. horizontalDirectionFromCameraToSubject.mV[ VX ] * mPitchCos,
  328. horizontalDirectionFromCameraToSubject.mV[ VY ] * mPitchCos,
  329. -mPitchSin
  330. );
  331. positionOffsetFromSubject *= mSimulatedDistance;
  332. //----------------------------------------------------------------------
  333. // Finally, ideal position is set by taking the subject position and 
  334. // extending the positionOffsetFromSubject from that
  335. //----------------------------------------------------------------------
  336. LLVector3 idealCameraPosition = offsetSubjectPosition - positionOffsetFromSubject;
  337. //--------------------------------------------------------------------------------
  338. // Now I prepare to move the current camera position towards its ideal position...
  339. //--------------------------------------------------------------------------------
  340. LLVector3 vectorFromPositionToIdealPosition = idealCameraPosition - simulated_pos_agent;
  341. F32 distanceFromPositionToIdealPosition = vectorFromPositionToIdealPosition.magVec();
  342. //put this inside of the block?
  343. LLVector3 normalFromPositionToIdealPosition = vectorFromPositionToIdealPosition / distanceFromPositionToIdealPosition;
  344. whereCameraPositionWantsToBe = simulated_pos_agent + 
  345. (normalFromPositionToIdealPosition * (distanceFromPositionToIdealPosition - mPositionThreshold));
  346. //-------------------------------------------------------------------------------------------------
  347. // The following method takes the target camera position and resets it so that it stays "behind" the subject, 
  348. // using behindness angle and behindness force as parameters affecting the exact behavior
  349. //-------------------------------------------------------------------------------------------------
  350. if ( distanceFromPositionToIdealPosition > mPositionThreshold )
  351. {
  352. F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag );
  353. simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp );
  354. }
  355. //--------------------------------------------------------------------
  356. // don't let the camera get farther than its official max distance
  357. //--------------------------------------------------------------------
  358. if ( distanceFromCameraToSubject > mMaxCameraDistantFromSubject )
  359. {
  360. LLVector3 directionFromCameraToSubject = vectorFromCameraToSubject / distanceFromCameraToSubject;
  361. simulated_pos_agent = offsetSubjectPosition - directionFromCameraToSubject * mMaxCameraDistantFromSubject;
  362. }
  363. ////-------------------------------------------------------------------------------------------------
  364. //// The following method takes mSimulatedPositionGlobal and resets it so that it stays "behind" the subject, 
  365. //// using behindness angle and behindness force as parameters affecting the exact behavior
  366. ////-------------------------------------------------------------------------------------------------
  367. updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent);
  368. mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent);
  369. mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
  370. } // if position is not locked -----------------------------------------------------------
  371. //####################################################################################
  372. // update UpVector
  373. //####################################################################################
  374. // this just points upward for now, but I anticipate future effects requiring 
  375. // some rolling ("banking" effects for fun, swoopy vehicles, etc.)
  376. mUpVector = LLVector3::z_axis;
  377. }
  378. //-------------------------------------------------------------------------------------
  379. BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_position)
  380. {
  381. BOOL constraint_active = FALSE;
  382. // only apply this stuff if the behindness angle is something other than opened up all the way
  383. if ( mBehindnessMaxAngle < FOLLOW_CAM_MAX_BEHINDNESS_ANGLE - FOLLOW_CAM_BEHINDNESS_EPSILON )
  384. {
  385. //--------------------------------------------------------------
  386. // horizontalized vector from focus to camera 
  387. //--------------------------------------------------------------
  388. LLVector3 horizontalVectorFromFocusToCamera;
  389. horizontalVectorFromFocusToCamera.setVec(cam_position - focus);
  390. horizontalVectorFromFocusToCamera.mV[ VZ ] = 0.0f; 
  391. F32 cameraZ = cam_position.mV[ VZ ];
  392. //--------------------------------------------------------------
  393. // distance of horizontalized vector
  394. //--------------------------------------------------------------
  395. F32 horizontalDistance = horizontalVectorFromFocusToCamera.magVec();
  396. //--------------------------------------------------------------------------------------------------
  397. // calculate horizontalized back vector of the subject and scale by horizontalDistance
  398. //--------------------------------------------------------------------------------------------------
  399. LLVector3 horizontalSubjectBack( -1.0f, 0.0f, 0.0f );
  400. horizontalSubjectBack *= mSubjectRotation;
  401. horizontalSubjectBack.mV[ VZ ] = 0.0f; 
  402. horizontalSubjectBack.normVec(); // because horizontalizing might make it shorter than 1
  403. horizontalSubjectBack *= horizontalDistance;
  404. //--------------------------------------------------------------------------------------------------
  405. // find the angle (in degrees) between these vectors
  406. //--------------------------------------------------------------------------------------------------
  407. F32 cameraOffsetAngle = 0.f;
  408. LLVector3 cameraOffsetRotationAxis;
  409. LLQuaternion camera_offset_rotation;
  410. camera_offset_rotation.shortestArc(horizontalSubjectBack, horizontalVectorFromFocusToCamera);
  411. camera_offset_rotation.getAngleAxis(&cameraOffsetAngle, cameraOffsetRotationAxis);
  412. cameraOffsetAngle *= RAD_TO_DEG;
  413. if ( cameraOffsetAngle > mBehindnessMaxAngle )
  414. {
  415. F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag);
  416. cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT));
  417. cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it
  418. constraint_active = TRUE;
  419. }
  420. }
  421. return constraint_active;
  422. }
  423. //---------------------------------------------------------
  424. void LLFollowCam::calculatePitchSineAndCosine()
  425. {
  426. F32 radian = mPitch * DEG_TO_RAD;
  427. mPitchCos = cos( radian );
  428. mPitchSin = sin( radian );
  429. }
  430. //---------------------------------------------------------
  431. void LLFollowCam::setSubjectPositionAndRotation( const LLVector3 p, const LLQuaternion r )
  432. {
  433. mSubjectPosition = p;
  434. mSubjectRotation = r;
  435. }
  436. //---------------------------------------------------------
  437. void LLFollowCam::zoom( S32 z ) 
  438. F32 zoomAmount = z * mSimulatedDistance * FOLLOW_CAM_ZOOM_FACTOR;
  439. if (( zoomAmount <  FOLLOW_CAM_MIN_ZOOM_AMOUNT )
  440. &&  ( zoomAmount > -FOLLOW_CAM_MIN_ZOOM_AMOUNT ))
  441. {
  442. if ( zoomAmount < 0.0f )
  443. {
  444. zoomAmount = -FOLLOW_CAM_MIN_ZOOM_AMOUNT;
  445. }
  446. else
  447. {
  448. zoomAmount = FOLLOW_CAM_MIN_ZOOM_AMOUNT;
  449. }
  450. }
  451. mSimulatedDistance += zoomAmount;
  452. mZoomedToMinimumDistance = false;
  453. if ( mSimulatedDistance < FOLLOW_CAM_MIN_DISTANCE ) 
  454. {
  455. mSimulatedDistance = FOLLOW_CAM_MIN_DISTANCE;
  456. // if zoomAmount is negative (i.e., getting closer), then
  457. // this signifies having hit the minimum:
  458. if ( zoomAmount < 0.0f )
  459. {
  460. mZoomedToMinimumDistance = true;
  461. }
  462. }
  463. else if ( mSimulatedDistance > mMaxCameraDistantFromSubject ) 
  464. {
  465. mSimulatedDistance = mMaxCameraDistantFromSubject;
  466. }
  467. }
  468. //---------------------------------------------------------
  469. bool LLFollowCam::isZoomedToMinimumDistance()
  470. {
  471. return mZoomedToMinimumDistance;
  472. }
  473. //---------------------------------------------------------
  474. void LLFollowCam::reset( const LLVector3 p, const LLVector3 f , const LLVector3 u )
  475. {
  476. setPosition(p);
  477. setFocus(f);
  478. mUpVector = u;
  479. }
  480. //---------------------------------------------------------
  481. void LLFollowCam::setMaxCameraDistantFromSubject( F32 m )
  482. {
  483. mMaxCameraDistantFromSubject = m;
  484. }
  485. void LLFollowCam::setPitch( F32 p ) 
  486. LLFollowCamParams::setPitch(p);
  487. mPitchSineAndCosineNeedToBeUpdated = true; // important
  488. }
  489. void LLFollowCam::setDistance( F32 d ) 
  490. if (d != mDistance)
  491. {
  492. LLFollowCamParams::setDistance(d);
  493. mSimulatedDistance = d;
  494. mZoomedToMinimumDistance = false; 
  495. }
  496. }
  497. void LLFollowCam::setPosition( const LLVector3& p ) 
  498. if (p != mPosition)
  499. {
  500. LLFollowCamParams::setPosition(p);
  501. mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(mPosition);
  502. if (mPositionLocked)
  503. {
  504. mRelativePos = (mPosition - mSubjectPosition) * ~mSubjectRotation;
  505. }
  506. }
  507. }
  508. void LLFollowCam::setFocus( const LLVector3& f ) 
  509. if (f != mFocus)
  510. {
  511. LLFollowCamParams::setFocus(f);
  512. mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(f);
  513. if (mFocusLocked)
  514. {
  515. mRelativeFocus = (mFocus - mSubjectPosition) * ~mSubjectRotation;
  516. }
  517. }
  518. }
  519. void LLFollowCam::setPositionLocked( bool locked )
  520. {
  521. LLFollowCamParams::setPositionLocked(locked);
  522. if (locked)
  523. {
  524. // propagate set position to relative position
  525. mRelativePos = (gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal) - mSubjectPosition) * ~mSubjectRotation;
  526. }
  527. }
  528. void LLFollowCam::setFocusLocked( bool locked )
  529. {
  530. LLFollowCamParams::setFocusLocked(locked);
  531. if (locked)
  532. {
  533. // propagate set position to relative position
  534. mRelativeFocus = (gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal) - mSubjectPosition) * ~mSubjectRotation;
  535. }
  536. }
  537. LLVector3 LLFollowCam::getSimulatedPosition() const 
  538. // return simulated position
  539. return mSubjectPosition + (mRelativePos * mSubjectRotation);
  540. }
  541. LLVector3 LLFollowCam::getSimulatedFocus() const 
  542. // return simulated focus point
  543. return mSubjectPosition + (mRelativeFocus * mSubjectRotation);
  544. }
  545. LLVector3 LLFollowCam::getUpVector() 
  546. return mUpVector;
  547. }
  548. //------------------------------------
  549. // Destructor
  550. //------------------------------------
  551. LLFollowCam::~LLFollowCam()
  552. {
  553. }
  554. //-------------------------------------------------------
  555. // LLFollowCamMgr
  556. //-------------------------------------------------------
  557. //static
  558. void LLFollowCamMgr::cleanupClass()
  559. {
  560. for (param_map_t::iterator iter = sParamMap.begin(); iter != sParamMap.end(); ++iter)
  561. {
  562. LLFollowCamParams* params = iter->second;
  563. delete params;
  564. }
  565. sParamMap.clear();
  566. }
  567. //static
  568. void LLFollowCamMgr::setPositionLag( const LLUUID& source, F32 lag)
  569. {
  570. LLFollowCamParams* paramsp = getParamsForID(source);
  571. if (paramsp)
  572. {
  573. paramsp->setPositionLag(lag);
  574. }
  575. }
  576. //static
  577. void LLFollowCamMgr::setFocusLag( const LLUUID& source, F32 lag)
  578. {
  579. LLFollowCamParams* paramsp = getParamsForID(source);
  580. if (paramsp)
  581. {
  582. paramsp->setFocusLag(lag);
  583. }
  584. }
  585. //static
  586. void LLFollowCamMgr::setFocusThreshold( const LLUUID& source, F32 threshold)
  587. {
  588. LLFollowCamParams* paramsp = getParamsForID(source);
  589. if (paramsp)
  590. {
  591. paramsp->setFocusThreshold(threshold);
  592. }
  593. }
  594. //static
  595. void LLFollowCamMgr::setPositionThreshold( const LLUUID& source, F32 threshold)
  596. {
  597. LLFollowCamParams* paramsp = getParamsForID(source);
  598. if (paramsp)
  599. {
  600. paramsp->setPositionThreshold(threshold);
  601. }
  602. }
  603. //static
  604. void LLFollowCamMgr::setDistance( const LLUUID& source, F32 distance)
  605. {
  606. LLFollowCamParams* paramsp = getParamsForID(source);
  607. if (paramsp)
  608. {
  609. paramsp->setDistance(distance);
  610. }
  611. }
  612. //static
  613. void LLFollowCamMgr::setPitch( const LLUUID& source, F32 pitch)
  614. {
  615. LLFollowCamParams* paramsp = getParamsForID(source);
  616. if (paramsp)
  617. {
  618. paramsp->setPitch(pitch);
  619. }
  620. }
  621. //static
  622. void LLFollowCamMgr::setFocusOffset( const LLUUID& source, const LLVector3& offset)
  623. {
  624. LLFollowCamParams* paramsp = getParamsForID(source);
  625. if (paramsp)
  626. {
  627. paramsp->setFocusOffset(offset);
  628. }
  629. }
  630. //static
  631. void LLFollowCamMgr::setBehindnessAngle( const LLUUID& source, F32 angle)
  632. {
  633. LLFollowCamParams* paramsp = getParamsForID(source);
  634. if (paramsp)
  635. {
  636. paramsp->setBehindnessAngle(angle);
  637. }
  638. }
  639. //static
  640. void LLFollowCamMgr::setBehindnessLag( const LLUUID& source, F32 force)
  641. {
  642. LLFollowCamParams* paramsp = getParamsForID(source);
  643. if (paramsp)
  644. {
  645. paramsp->setBehindnessLag(force);
  646. }
  647. }
  648. //static
  649. void LLFollowCamMgr::setPosition( const LLUUID& source, const LLVector3 position)
  650. {
  651. LLFollowCamParams* paramsp = getParamsForID(source);
  652. if (paramsp)
  653. {
  654. paramsp->setPosition(position);
  655. }
  656. }
  657. //static
  658. void LLFollowCamMgr::setFocus( const LLUUID& source, const LLVector3 focus)
  659. {
  660. LLFollowCamParams* paramsp = getParamsForID(source);
  661. if (paramsp)
  662. {
  663. paramsp->setFocus(focus);
  664. }
  665. }
  666. //static
  667. void LLFollowCamMgr::setPositionLocked( const LLUUID& source, bool locked)
  668. {
  669. LLFollowCamParams* paramsp = getParamsForID(source);
  670. if (paramsp)
  671. {
  672. paramsp->setPositionLocked(locked);
  673. }
  674. }
  675. //static
  676. void LLFollowCamMgr::setFocusLocked( const LLUUID& source, bool locked )
  677. {
  678. LLFollowCamParams* paramsp = getParamsForID(source);
  679. if (paramsp)
  680. {
  681. paramsp->setFocusLocked(locked);
  682. }
  683. }
  684. //static 
  685. LLFollowCamParams* LLFollowCamMgr::getParamsForID(const LLUUID& source)
  686. {
  687. LLFollowCamParams* params = NULL;
  688. param_map_t::iterator found_it = sParamMap.find(source);
  689. if (found_it == sParamMap.end()) // didn't find it?
  690. {
  691. params = new LLFollowCamParams();
  692. sParamMap[source] = params;
  693. }
  694. else
  695. {
  696. params = found_it->second;
  697. }
  698. return params;
  699. }
  700. //static
  701. LLFollowCamParams* LLFollowCamMgr::getActiveFollowCamParams()
  702. {
  703. if (sParamStack.empty())
  704. {
  705. return NULL;
  706. }
  707. return sParamStack.back();
  708. }
  709. //static 
  710. void LLFollowCamMgr::setCameraActive( const LLUUID& source, bool active )
  711. {
  712. LLFollowCamParams* params = getParamsForID(source);
  713. param_stack_t::iterator found_it = std::find(sParamStack.begin(), sParamStack.end(), params);
  714. if (found_it != sParamStack.end())
  715. {
  716. sParamStack.erase(found_it);
  717. }
  718. // put on top of stack
  719. if(active)
  720. {
  721. sParamStack.push_back(params);
  722. }
  723. }
  724. //static
  725. void LLFollowCamMgr::removeFollowCamParams(const LLUUID& source)
  726. {
  727. setCameraActive(source, FALSE);
  728. LLFollowCamParams* params = getParamsForID(source);
  729. sParamMap.erase(source);
  730. delete params;
  731. }
  732. //static
  733. bool LLFollowCamMgr::isScriptedCameraSource(const LLUUID& source)
  734. {
  735. param_map_t::iterator found_it = sParamMap.find(source);
  736. return (found_it != sParamMap.end());
  737. }
  738. //static 
  739. void LLFollowCamMgr::dump()
  740. {
  741. S32 param_count = 0;
  742. llinfos << "Scripted camera active stack" << llendl;
  743. for (param_stack_t::iterator param_it = sParamStack.begin();
  744. param_it != sParamStack.end();
  745. ++param_it)
  746. {
  747. llinfos << param_count++ << 
  748. " rot_limit: " << (*param_it)->getBehindnessAngle() << 
  749. " rot_lag: " << (*param_it)->getBehindnessLag() << 
  750. " distance: " << (*param_it)->getDistance() << 
  751. " focus: " << (*param_it)->getFocus() << 
  752. " foc_lag: " << (*param_it)->getFocusLag() << 
  753. " foc_lock: " << ((*param_it)->getFocusLocked() ? "Y" : "N") << 
  754. " foc_offset: " << (*param_it)->getFocusOffset() << 
  755. " foc_thresh: " << (*param_it)->getFocusThreshold() << 
  756. " pitch: " << (*param_it)->getPitch() << 
  757. " pos: " << (*param_it)->getPosition() << 
  758. " pos_lag: " << (*param_it)->getPositionLag() << 
  759. " pos_lock: " << ((*param_it)->getPositionLocked() ? "Y" : "N") << 
  760. " pos_thresh: " << (*param_it)->getPositionThreshold() << llendl;
  761. }
  762. }