BsCamera.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. #pragma once
  2. #include "BsPrerequisites.h"
  3. #include "BsString.h"
  4. #include "BsMatrix4.h"
  5. #include "BsVector3.h"
  6. #include "BsVector2.h"
  7. #include "BsAABox.h"
  8. #include "BsVertexData.h"
  9. #include "BsPlane.h"
  10. #include "BsQuaternion.h"
  11. #include "BsRay.h"
  12. #include "BsComponent.h"
  13. #include "BsCameraProxy.h"
  14. #include "BsConvexVolume.h"
  15. namespace BansheeEngine
  16. {
  17. /**
  18. * @brief Specified projection type to use by the camera.
  19. */
  20. enum ProjectionType
  21. {
  22. PT_ORTHOGRAPHIC,
  23. PT_PERSPECTIVE
  24. };
  25. /**
  26. * @brief Clip planes that form the camera frustum (visible area).
  27. */
  28. enum FrustumPlane
  29. {
  30. FRUSTUM_PLANE_NEAR = 0,
  31. FRUSTUM_PLANE_FAR = 1,
  32. FRUSTUM_PLANE_LEFT = 2,
  33. FRUSTUM_PLANE_RIGHT = 3,
  34. FRUSTUM_PLANE_TOP = 4,
  35. FRUSTUM_PLANE_BOTTOM = 5
  36. };
  37. /**
  38. * @brief Camera determines how is world geometry projected onto a 2D surface. You may
  39. * position and orient it in space, and set other options like aspect ratio and field or view.
  40. */
  41. class BS_EXPORT Camera : public Component
  42. {
  43. public:
  44. Camera(const HSceneObject& parent, RenderTargetPtr target = nullptr,
  45. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  46. virtual ~Camera();
  47. /**
  48. * @brief Returns the viewport used by the camera.
  49. */
  50. ViewportPtr getViewport() const { return mViewport; }
  51. /**
  52. * @brief Sets the camera horizontal field of view. This determines how wide the camera
  53. * viewing angle is along the horizontal axis. Vertical FOV is calculated from the
  54. * horizontal FOV and the aspect.
  55. */
  56. virtual void setHorzFOV(const Radian& fovy);
  57. /**
  58. * @brief Retrieves the camera horizontal field of view.
  59. */
  60. virtual const Radian& getHorzFOV() const;
  61. /**
  62. * @brief Sets the distance from the frustum to the near clipping plane. Anything
  63. * closer than the near clipping plane will not be rendered. Decreasing this value
  64. * decreases depth buffer precision.
  65. */
  66. virtual void setNearClipDistance(float nearDist);
  67. /**
  68. * @brief Retrieves the distance from the frustum to the near clipping plane. Anything
  69. * closer than the near clipping plane will not be rendered. Decreasing this value
  70. * decreases depth buffer precision.
  71. */
  72. virtual float getNearClipDistance() const;
  73. /**
  74. * @brief Sets the distance from the frustum to the far clipping plane. Anything
  75. * farther than the far clipping plane will not be rendered. Increasing this value
  76. * decreases depth buffer precision.
  77. */
  78. virtual void setFarClipDistance(float farDist);
  79. /**
  80. * @brief Retrieves the distance from the frustum to the far clipping plane. Anything
  81. * farther than the far clipping plane will not be rendered. Increasing this value
  82. * decreases depth buffer precision.
  83. */
  84. virtual float getFarClipDistance() const;
  85. /**
  86. * @brief Sets the current viewport aspect ratio (width / height).
  87. */
  88. virtual void setAspectRatio(float ratio);
  89. /**
  90. * @brief Returns current viewport aspect ratio (width / height).
  91. */
  92. virtual float getAspectRatio() const;
  93. /** @brief Manually set the extents of the frustum that will be used when calculating the
  94. * projection matrix. This will prevents extents for being automatically calculated
  95. * from aspect and near plane so it is up to the caller to keep these values
  96. * accurate.
  97. *
  98. * @param left The position where the left clip plane intersect the near clip plane, in view space.
  99. * @param right The position where the right clip plane intersect the near clip plane, in view space.
  100. * @param top The position where the top clip plane intersect the near clip plane, in view space.
  101. * @param bottom The position where the bottom clip plane intersect the near clip plane, in view space.
  102. */
  103. virtual void setFrustumExtents(float left, float right, float top, float bottom);
  104. /**
  105. * @brief Resets frustum extents so they are automatically derived from other values.
  106. * This is only relevant if you have previously set custom extents.
  107. */
  108. virtual void resetFrustumExtents();
  109. /**
  110. * @brief Returns the extents of the frustum in view space at the near plane.
  111. */
  112. virtual void getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const;
  113. /**
  114. * @brief Returns the standard projection matrix that determines how are 3D points
  115. * projected to two dimensions. The layout of this matrix depends on currently
  116. * used render system.
  117. *
  118. * @note You should use this matrix when sending the matrix to the render system to remain
  119. * everything works consistently when other render systems are used.
  120. */
  121. virtual const Matrix4& getProjectionMatrixRS() const;
  122. /**
  123. * @brief Returns the standard projection matrix that determines how are 3D points
  124. * projected to two dimensions. Returned matrix is standard following right-hand
  125. * rules and depth range of [-1, 1].
  126. *
  127. * @note Different render systems will expect different projection matrix layouts, in which
  128. * case use getProjectionMatrixRS.
  129. */
  130. virtual const Matrix4& getProjectionMatrix() const;
  131. /**
  132. * @brief Gets the camera view matrix. Used for positioning/orienting the camera.
  133. */
  134. virtual const Matrix4& getViewMatrix() const;
  135. /**
  136. * @brief Sets whether the camera should use the custom view matrix.
  137. * When this is enabled camera will no longer calculate its view matrix
  138. * based on position/orientation and caller will be resonsible to keep
  139. * the view matrix up to date.
  140. */
  141. virtual void setCustomViewMatrix(bool enable, const Matrix4& viewMatrix = Matrix4::IDENTITY);
  142. /**
  143. * @brief Returns true if a custom view matrix is used.
  144. */
  145. virtual bool isCustomViewMatrixEnabled() const { return mCustomViewMatrix; }
  146. /**
  147. * @brief Sets whether the camera should use the custom projection matrix.
  148. * When this is enabled camera will no longer calculate its projection matrix
  149. * based on field of view, aspect and other parameters and caller will be
  150. * resonsible to keep the projection matrix up to date.
  151. */
  152. virtual void setCustomProjectionMatrix(bool enable, const Matrix4& projectionMatrix = Matrix4::IDENTITY);
  153. /**
  154. * @brief Returns true if a custom projection matrix is used.
  155. */
  156. virtual bool isCustomProjectionMatrixEnabled() const { return mCustomProjMatrix; }
  157. /**
  158. * @brief Returns a convex volume representing the visible area of the camera.
  159. */
  160. virtual const ConvexVolume& getFrustum() const;
  161. /**
  162. * @brief Returns the bounding of the frustum.
  163. */
  164. const AABox& getBoundingBox() const;
  165. /**
  166. * @brief Sets the type of projection used by the camera.
  167. */
  168. virtual void setProjectionType(ProjectionType pt);
  169. /**
  170. * @brief Returns the type of projection used by the camera.
  171. */
  172. virtual ProjectionType getProjectionType() const;
  173. /**
  174. * @brief Sets the orthographic window height, for use with orthographic rendering only.
  175. *
  176. * @param w Width of the window in world units.
  177. * @param h Height of the window in world units.
  178. *
  179. * @note Calling this method will recalculate the aspect ratio, use setOrthoWindowHeight or
  180. * setOrthoWindowWidth alone if you wish to preserve the aspect ratio but just fit one
  181. * or other dimension to a particular size.
  182. */
  183. virtual void setOrthoWindow(float w, float h);
  184. /**
  185. * @brief Sets the orthographic window height, for use with orthographic rendering only.
  186. *
  187. * @param h Height of the window in world units.
  188. *
  189. * @note The width of the window will be calculated from the aspect ratio.
  190. */
  191. virtual void setOrthoWindowHeight(float h);
  192. /**
  193. * @brief Sets the orthographic window width, for use with orthographic rendering only.
  194. *
  195. * @param w Width of the window in world units.
  196. *
  197. * @note The height of the window will be calculated from the aspect ratio.
  198. */
  199. virtual void setOrthoWindowWidth(float w);
  200. /**
  201. * @brief Gets the orthographic window width in world units, for use with orthographic rendering only.
  202. */
  203. virtual float getOrthoWindowHeight() const;
  204. /**
  205. * @brief Gets the orthographic window width in world units, for use with orthographic rendering only.
  206. *
  207. * @note This is calculated from the orthographic height and the aspect ratio.
  208. */
  209. virtual float getOrthoWindowWidth() const;
  210. /**
  211. * @brief This option tells the renderer that this camera should ignore any renderable components.
  212. */
  213. void setIgnoreSceneRenderables(bool value) { mIgnoreSceneRenderables = true; markCoreDirty(); }
  214. /**
  215. * @brief This option tells the renderer that this camera should ignore any renderable components.
  216. */
  217. bool getIgnoreSceneRenderables() const { return mIgnoreSceneRenderables; }
  218. /**
  219. * @brief Gets a priority that determines in which orders the cameras are rendered.
  220. * This only applies to cameras rendering to the same render target.
  221. */
  222. INT32 getPriority() const { return mPriority; }
  223. /**
  224. * @brief Sets a priority that determines in which orders the cameras are rendered.
  225. * This only applies to cameras rendering to the same render target.
  226. *
  227. * @param priority The priority. Higher value means the camera will be rendered sooner.
  228. */
  229. void setPriority(INT32 priority) { mPriority = priority; markCoreDirty(); }
  230. /**
  231. * @brief Retrieves layer bitfield that is used when determining which object should the camera render.
  232. */
  233. UINT64 getLayers() const { return mLayers; }
  234. /**
  235. * @brief Sets layer bitfield that is used when determining which object should the camera render.
  236. */
  237. void setLayers(UINT64 layers) { mLayers = layers; markCoreDirty(); }
  238. static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
  239. /************************************************************************/
  240. /* CORE PROXY */
  241. /************************************************************************/
  242. /**
  243. * @brief Checks is the core dirty flag set. This is used by external systems
  244. * to know when internal data has changed and core thread potentially needs to be notified.
  245. */
  246. bool _isCoreDirty() const { return mCoreDirtyFlags != 0; }
  247. /**
  248. * @brief Marks the core dirty flag as clean.
  249. */
  250. void _markCoreClean() { mCoreDirtyFlags = 0; }
  251. /**
  252. * @brief Creates a new core proxy from the currently set options. Core proxies ensure
  253. * that the core thread has all the necessary data, while avoiding the need
  254. * to manage Camera itself on the core thread.
  255. *
  256. * @note You generally need to update the core thread with a new proxy whenever core
  257. * dirty flag is set.
  258. */
  259. CameraProxyPtr _createProxy() const;
  260. /**
  261. * @brief Returns the currently active proxy object, if any.
  262. */
  263. CameraProxyPtr _getActiveProxy() const { return mActiveProxy; }
  264. /**
  265. * @brief Changes the currently active proxy object.
  266. */
  267. void _setActiveProxy(const CameraProxyPtr& proxy) { mActiveProxy = proxy; }
  268. protected:
  269. /**
  270. * @brief Calculate projection parameters that are used when constructing the projection matrix.
  271. */
  272. virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
  273. /**
  274. * @brief Recalculate frustum if dirty.
  275. */
  276. virtual void updateFrustum() const;
  277. /**
  278. * @brief Recalculate frustum planes if dirty.
  279. */
  280. virtual void updateFrustumPlanes() const;
  281. /**
  282. * @brief Update view matrix from parent position/orientation.
  283. *
  284. * @note Does nothing when custom view matrix is set.
  285. */
  286. virtual void updateView() const;
  287. /**
  288. * @brief Checks if the frustum requires updating.
  289. */
  290. virtual bool isFrustumOutOfDate() const;
  291. /**
  292. * @brief Notify camera that the frustum requires to be updated.
  293. */
  294. virtual void invalidateFrustum() const;
  295. /**
  296. * @brief Marks the core data as dirty.
  297. */
  298. void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
  299. protected:
  300. ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
  301. UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
  302. ProjectionType mProjType; /**< Type of camera projection. */
  303. Radian mHorzFOV; /**< Horizontal field of view represents how wide is the camera angle. */
  304. float mFarDist; /**< Clip any objects further than this. Larger value decreases depth precision at smaller depths. */
  305. float mNearDist; /**< Clip any objects close than this. Smaller value decreases depth precision at larger depths. */
  306. float mAspect; /**< Width/height viewport ratio. */
  307. float mOrthoHeight; /**< Height in world units used for orthographic cameras. */
  308. INT32 mPriority; /**< Determines in what order will the camera be rendered. Higher priority means the camera will be rendered sooner. */
  309. bool mCustomViewMatrix; /**< Is custom view matrix set. */
  310. bool mCustomProjMatrix; /**< Is custom projection matrix set. */
  311. bool mFrustumExtentsManuallySet; /**< Are frustum extents manually set. */
  312. bool mIgnoreSceneRenderables; /**< Should the camera ignore renderable components. */
  313. UINT32 mCoreDirtyFlags; /**< True when internal data has changed and core thread wasn't yet informed. */
  314. CameraProxyPtr mActiveProxy; /**< Active core proxy if any. */
  315. mutable Matrix4 mProjMatrixRS; /**< Cached render-system specific projection matrix. */
  316. mutable Matrix4 mProjMatrix; /**< Cached projection matrix that determines how are 3D points projected to a 2D viewport. */
  317. mutable Matrix4 mViewMatrix; /**< Cached view matrix that determines camera position/orientation. */
  318. mutable ConvexVolume mFrustum; /**< Main clipping planes describing cameras visible area. */
  319. mutable bool mRecalcFrustum; /**< Should frustum be recalculated. */
  320. mutable bool mRecalcFrustumPlanes; /**< Should frustum planes be recalculated. */
  321. mutable float mLeft, mRight, mTop, mBottom; /**< Frustum extents. */
  322. mutable AABox mBoundingBox; /**< Frustum bounding box. */
  323. /************************************************************************/
  324. /* COMPONENT OVERRIDES */
  325. /************************************************************************/
  326. protected:
  327. friend class SceneObject;
  328. public:
  329. /**
  330. * @copydoc Component::update
  331. */
  332. virtual void update() {}
  333. /************************************************************************/
  334. /* RTTI */
  335. /************************************************************************/
  336. public:
  337. friend class CameraRTTI;
  338. static RTTITypeBase* getRTTIStatic();
  339. virtual RTTITypeBase* getRTTI() const;
  340. protected:
  341. Camera() {} // Serialization only
  342. };
  343. }