llfollowcam.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /**
  2. * @file llfollowcam.h
  3. * @author Jeffrey Ventrella
  4. * @brief LLFollowCam class definition
  5. *
  6. * $LicenseInfo:firstyear=2005&license=viewergpl$
  7. *
  8. * Copyright (c) 2005-2009, 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. //-----------------------------------------------------------------------------
  34. // FollowCam
  35. //
  36. // The FollowCam controls three dynamic variables which determine a camera
  37. // orientation and position for a "loose" third-person view (orientation being
  38. // derived from a combination of focus and up vector). It is good for fast
  39. // moving vehicles that change acceleration a lot, but it can also be general
  40. // purpose, like for avatar navigation. It has a handful of parameters allowing
  41. // it to be tweaked to assume different styles of tracking objects.
  42. //-----------------------------------------------------------------------------
  43. #ifndef LL_FOLLOWCAM_H
  44. #define LL_FOLLOWCAM_H
  45. #include <vector>
  46. #include "indra_constants.h"
  47. #include "llcoordframe.h"
  48. #include "llcriticaldamp.h"
  49. #include "hbfastmap.h"
  50. #include "llmath.h"
  51. #include "llquaternion.h"
  52. #include "lltimer.h"
  53. class LLFollowCamParams
  54. {
  55. public:
  56. LLFollowCamParams();
  57. virtual ~LLFollowCamParams() = default;
  58. LL_INLINE virtual void setPosition(const LLVector3& pos)
  59. {
  60. mUsePosition = true;
  61. mPosition = pos;
  62. }
  63. LL_INLINE virtual void setFocus(const LLVector3& focus)
  64. {
  65. mUseFocus = true;
  66. mFocus = focus;
  67. }
  68. LL_INLINE virtual void setPositionLocked(bool b) { mPositionLocked = b; }
  69. LL_INLINE virtual void setFocusLocked(bool b) { mFocusLocked = b; }
  70. virtual void setPositionLag(F32);
  71. virtual void setFocusLag(F32);
  72. virtual void setFocusThreshold(F32);
  73. virtual void setPositionThreshold(F32);
  74. virtual void setDistance(F32);
  75. virtual void setPitch(F32);
  76. virtual void setFocusOffset(const LLVector3&);
  77. virtual void setBehindnessAngle(F32);
  78. virtual void setBehindnessLag(F32);
  79. LL_INLINE virtual F32 getPositionLag() const { return mPositionLag; }
  80. LL_INLINE virtual F32 getFocusLag() const { return mFocusLag; }
  81. LL_INLINE virtual F32 getPositionThreshold() const { return mPositionThreshold; }
  82. LL_INLINE virtual F32 getFocusThreshold() const { return mFocusThreshold; }
  83. LL_INLINE virtual F32 getDistance() const { return mDistance; }
  84. LL_INLINE virtual F32 getPitch() const { return mPitch; }
  85. LL_INLINE virtual LLVector3 getFocusOffset() const { return mFocusOffset; }
  86. LL_INLINE virtual F32 getBehindnessAngle() const { return mBehindnessMaxAngle; }
  87. LL_INLINE virtual F32 getBehindnessLag() const { return mBehindnessLag; }
  88. LL_INLINE virtual LLVector3 getPosition() const { return mPosition; }
  89. LL_INLINE virtual LLVector3 getFocus() const { return mFocus; }
  90. LL_INLINE virtual bool getFocusLocked() const { return mFocusLocked; }
  91. LL_INLINE virtual bool getPositionLocked() const { return mPositionLocked; }
  92. LL_INLINE virtual bool getUseFocus() const { return mUseFocus; }
  93. LL_INLINE virtual bool getUsePosition() const { return mUsePosition; }
  94. protected:
  95. F32 mPositionLag;
  96. F32 mFocusLag;
  97. F32 mFocusThreshold;
  98. F32 mPositionThreshold;
  99. F32 mDistance;
  100. F32 mPitch;
  101. F32 mBehindnessMaxAngle;
  102. F32 mBehindnessLag;
  103. F32 mMaxCameraDistantFromSubject;
  104. LLVector3 mPosition; // where the camera is (in world-space)
  105. LLVector3 mFocus; // what the camera is aimed at (in world-space)
  106. LLVector3 mFocusOffset;
  107. bool mPositionLocked;
  108. bool mFocusLocked;
  109. bool mUsePosition; // specific camera point specified by script
  110. bool mUseFocus; // specific focus point specified by script
  111. };
  112. class LLFollowCam : public LLFollowCamParams
  113. {
  114. protected:
  115. LOG_CLASS(LLFollowCam);
  116. public:
  117. LLFollowCam();
  118. //-------------------------------------------------------------------------
  119. // The following methods must be called every time step. However, if you
  120. // know for sure that your subject matter (what the camera is looking at)
  121. // is not moving, then you can get away with not calling "update" But keep
  122. // in mind that "update" may still be needed after the subject matter has
  123. // stopped moving because the camera may still need to animate itself
  124. // catching up to its ideal resting place.
  125. //-------------------------------------------------------------------------
  126. LL_INLINE void setSubjectPositionAndRotation(const LLVector3 p,
  127. const LLQuaternion r)
  128. {
  129. mSubjectPosition = p;
  130. mSubjectRotation = r;
  131. }
  132. void update();
  133. // Initializes from another instance of LLFollowCamParams
  134. void copyParams(LLFollowCamParams& params);
  135. //-------------------------------------------------------------------------
  136. // This is how to bang the followCam into a specific configuration. Keep in
  137. // mind that it will immediately try to adjust these values according to
  138. // its attributes.
  139. //-------------------------------------------------------------------------
  140. void reset(const LLVector3 position, const LLVector3 focus,
  141. const LLVector3 upVector);
  142. // This should be determined by llAgent
  143. LL_INLINE void setMaxCameraDistantFromSubject(F32 m) { mMaxCameraDistantFromSubject = m; }
  144. LL_INLINE bool isZoomedToMinimumDistance() { return mZoomedToMinimumDistance; }
  145. LL_INLINE LLVector3 getUpVector() { return mUpVector; }
  146. void zoom(S32);
  147. // Overrides for setters and getters
  148. void setPosition(const LLVector3& pos) override;
  149. void setFocus(const LLVector3& focus) override;
  150. void setPositionLocked(bool) override;
  151. void setFocusLocked(bool) override;
  152. void setPitch(F32) override;
  153. void setDistance(F32) override;
  154. // Returns simulated position
  155. LL_INLINE LLVector3 getSimulatedPosition() const
  156. {
  157. return mSubjectPosition + mRelativePos * mSubjectRotation;
  158. }
  159. // Returns simulated focus point
  160. LL_INLINE LLVector3 getSimulatedFocus() const
  161. {
  162. return mSubjectPosition + mRelativeFocus * mSubjectRotation;
  163. }
  164. protected:
  165. void calculatePitchSineAndCosine();
  166. bool updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_position);
  167. protected:
  168. F32 mPitchCos; // Derived from mPitch
  169. F32 mPitchSin; // Derived from mPitch
  170. // Where the camera is (global coordinates), simulated
  171. LLGlobalVec mSimulatedPositionGlobal;
  172. // What the camera is aimed at (global coordinates), simulated
  173. LLGlobalVec mSimulatedFocusGlobal;
  174. F32 mSimulatedDistance;
  175. // This is the position we are looking at
  176. LLVector3 mSubjectPosition;
  177. // This is the rotation we are looking at
  178. LLQuaternion mSubjectRotation;
  179. // The camera up vector in world-space (determines roll)
  180. LLVector3 mUpVector;
  181. LLVector3 mRelativeFocus;
  182. LLVector3 mRelativePos;
  183. LLFrameTimer mTimer;
  184. bool mZoomedToMinimumDistance;
  185. bool mPitchSineAndCosineNeedToBeUpdated;
  186. };
  187. class LLFollowCamMgr
  188. {
  189. protected:
  190. LOG_CLASS(LLFollowCamMgr);
  191. public:
  192. // WARNING: should this method get modified to do anything else than
  193. // removing all follow-camera constraints data, it would be necessary
  194. // to make a new method for calling it from llviewermenu.cpp (for the
  195. // "Release camera" action).
  196. static void cleanupClass();
  197. static void setPositionLag(const LLUUID& source, F32 lag);
  198. static void setFocusLag(const LLUUID& source, F32 lag);
  199. static void setFocusThreshold(const LLUUID& source, F32 threshold);
  200. static void setPositionThreshold(const LLUUID& source, F32 threshold);
  201. static void setDistance(const LLUUID& source, F32 distance);
  202. static void setPitch(const LLUUID& source, F32 pitch);
  203. static void setFocusOffset(const LLUUID& source, const LLVector3& offset);
  204. static void setBehindnessAngle(const LLUUID& source, F32 angle);
  205. static void setBehindnessLag(const LLUUID& source, F32 lag);
  206. static void setPosition(const LLUUID& source, const LLVector3 position);
  207. static void setFocus(const LLUUID& source, const LLVector3 focus);
  208. static void setPositionLocked(const LLUUID& source, bool locked);
  209. static void setFocusLocked(const LLUUID& source, bool locked);
  210. static void setCameraActive(const LLUUID& source, bool active);
  211. LL_INLINE static LLFollowCamParams* getActiveFollowCamParams()
  212. {
  213. return sParamStack.empty() ? NULL : sParamStack.back();
  214. }
  215. static LLFollowCamParams* getParamsForID(const LLUUID& source);
  216. static void removeFollowCamParams(const LLUUID& source);
  217. LL_INLINE static bool isScriptedCameraSource(const LLUUID& source)
  218. {
  219. return sParamMap.count(source) != 0;
  220. }
  221. static void dump();
  222. protected:
  223. typedef fast_hmap<LLUUID, LLFollowCamParams*> param_map_t;
  224. static param_map_t sParamMap;
  225. typedef std::vector<LLFollowCamParams*> param_stack_t;
  226. static param_stack_t sParamStack;
  227. };
  228. // Script-related constants
  229. enum EFollowCamAttributes {
  230. FOLLOWCAM_PITCH = 0,
  231. FOLLOWCAM_FOCUS_OFFSET,
  232. // This HAS to come after FOLLOWCAM_FOCUS_OFFSET in this list:
  233. FOLLOWCAM_FOCUS_OFFSET_X,
  234. FOLLOWCAM_FOCUS_OFFSET_Y,
  235. FOLLOWCAM_FOCUS_OFFSET_Z,
  236. FOLLOWCAM_POSITION_LAG,
  237. FOLLOWCAM_FOCUS_LAG,
  238. FOLLOWCAM_DISTANCE,
  239. FOLLOWCAM_BEHINDNESS_ANGLE,
  240. FOLLOWCAM_BEHINDNESS_LAG,
  241. FOLLOWCAM_POSITION_THRESHOLD,
  242. FOLLOWCAM_FOCUS_THRESHOLD,
  243. FOLLOWCAM_ACTIVE,
  244. FOLLOWCAM_POSITION,
  245. // This HAS to come after FOLLOWCAM_POSITION in this list:
  246. FOLLOWCAM_POSITION_X,
  247. FOLLOWCAM_POSITION_Y,
  248. FOLLOWCAM_POSITION_Z,
  249. FOLLOWCAM_FOCUS,
  250. // This HAS to come after FOLLOWCAM_FOCUS in this list:
  251. FOLLOWCAM_FOCUS_X,
  252. FOLLOWCAM_FOCUS_Y,
  253. FOLLOWCAM_FOCUS_Z,
  254. FOLLOWCAM_POSITION_LOCKED,
  255. FOLLOWCAM_FOCUS_LOCKED,
  256. NUM_FOLLOWCAM_ATTRIBUTES
  257. };
  258. #endif //LL_FOLLOWCAM_H