BsCameraHandler.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. #pragma once
  2. #include "BsPrerequisites.h"
  3. #include "BsIReflectable.h"
  4. #include "BsMatrix4.h"
  5. #include "BsVector3.h"
  6. #include "BsVector2.h"
  7. #include "BsVector2I.h"
  8. #include "BsAABox.h"
  9. #include "BsQuaternion.h"
  10. #include "BsRay.h"
  11. #include "BsCoreObject.h"
  12. #include "BsConvexVolume.h"
  13. namespace BansheeEngine
  14. {
  15. /**
  16. * @brief Specified projection type to use by the camera.
  17. */
  18. enum ProjectionType
  19. {
  20. PT_ORTHOGRAPHIC,
  21. PT_PERSPECTIVE
  22. };
  23. /**
  24. * @brief Clip planes that form the camera frustum (visible area).
  25. */
  26. enum FrustumPlane
  27. {
  28. FRUSTUM_PLANE_NEAR = 0,
  29. FRUSTUM_PLANE_FAR = 1,
  30. FRUSTUM_PLANE_LEFT = 2,
  31. FRUSTUM_PLANE_RIGHT = 3,
  32. FRUSTUM_PLANE_TOP = 4,
  33. FRUSTUM_PLANE_BOTTOM = 5
  34. };
  35. /**
  36. * @brief Camera determines how is world geometry projected onto a 2D surface. You may
  37. * position and orient it in space, set options like aspect ratio and field or view
  38. * and it outputs view and projection matrices required for rendering.
  39. */
  40. class BS_EXPORT CameraHandlerBase
  41. {
  42. public:
  43. virtual ~CameraHandlerBase() { }
  44. /**
  45. * @brief Sets the camera horizontal field of view. This determines how wide the camera
  46. * viewing angle is along the horizontal axis. Vertical FOV is calculated from the
  47. * horizontal FOV and the aspect.
  48. */
  49. virtual void setHorzFOV(const Radian& fovy);
  50. /**
  51. * @brief Retrieves the camera horizontal field of view.
  52. */
  53. virtual const Radian& getHorzFOV() const;
  54. /**
  55. * @brief Sets the distance from the frustum to the near clipping plane. Anything
  56. * closer than the near clipping plane will not be rendered. Decreasing this value
  57. * decreases depth buffer precision.
  58. */
  59. virtual void setNearClipDistance(float nearDist);
  60. /**
  61. * @brief Retrieves the distance from the frustum to the near clipping plane. Anything
  62. * closer than the near clipping plane will not be rendered. Decreasing this value
  63. * decreases depth buffer precision.
  64. */
  65. virtual float getNearClipDistance() const;
  66. /**
  67. * @brief Sets the distance from the frustum to the far clipping plane. Anything
  68. * farther than the far clipping plane will not be rendered. Increasing this value
  69. * decreases depth buffer precision.
  70. */
  71. virtual void setFarClipDistance(float farDist);
  72. /**
  73. * @brief Retrieves the distance from the frustum to the far clipping plane. Anything
  74. * farther than the far clipping plane will not be rendered. Increasing this value
  75. * decreases depth buffer precision.
  76. */
  77. virtual float getFarClipDistance() const;
  78. /**
  79. * @brief Sets the current viewport aspect ratio (width / height).
  80. */
  81. virtual void setAspectRatio(float ratio);
  82. /**
  83. * @brief Returns current viewport aspect ratio (width / height).
  84. */
  85. virtual float getAspectRatio() const;
  86. /**
  87. * @brief Sets camera world space position.
  88. */
  89. virtual void setPosition(const Vector3& position);
  90. /**
  91. * @brief Retrieves camera world space position.
  92. */
  93. virtual Vector3 getPosition() const { return mPosition; }
  94. /**
  95. * @brief Sets camera world space rotation.
  96. */
  97. virtual void setRotation(const Quaternion& rotation);
  98. /**
  99. * @brief Retrieves camera world space rotation.
  100. */
  101. virtual Quaternion getRotation() const { return mRotation; }
  102. /** @brief Manually set the extents of the frustum that will be used when calculating the
  103. * projection matrix. This will prevents extents for being automatically calculated
  104. * from aspect and near plane so it is up to the caller to keep these values
  105. * accurate.
  106. *
  107. * @param left The position where the left clip plane intersect the near clip plane, in view space.
  108. * @param right The position where the right clip plane intersect the near clip plane, in view space.
  109. * @param top The position where the top clip plane intersect the near clip plane, in view space.
  110. * @param bottom The position where the bottom clip plane intersect the near clip plane, in view space.
  111. */
  112. virtual void setFrustumExtents(float left, float right, float top, float bottom);
  113. /**
  114. * @brief Resets frustum extents so they are automatically derived from other values.
  115. * This is only relevant if you have previously set custom extents.
  116. */
  117. virtual void resetFrustumExtents();
  118. /**
  119. * @brief Returns the extents of the frustum in view space at the near plane.
  120. */
  121. virtual void getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const;
  122. /**
  123. * @brief Returns the standard projection matrix that determines how are 3D points
  124. * projected to two dimensions. The layout of this matrix depends on currently
  125. * used render system.
  126. *
  127. * @note You should use this matrix when sending the matrix to the render system to remain
  128. * everything works consistently when other render systems are used.
  129. */
  130. virtual const Matrix4& getProjectionMatrixRS() const;
  131. /**
  132. * @brief Returns the inverse of the render-system specific projection matrix.
  133. *
  134. * @see getProjectionMatrixRS
  135. */
  136. virtual const Matrix4& getProjectionMatrixRSInv() const;
  137. /**
  138. * @brief Returns the standard projection matrix that determines how are 3D points
  139. * projected to two dimensions. Returned matrix is standard following right-hand
  140. * rules and depth range of [-1, 1].
  141. *
  142. * @note Different render systems will expect different projection matrix layouts, in which
  143. * case use getProjectionMatrixRS.
  144. */
  145. virtual const Matrix4& getProjectionMatrix() const;
  146. /**
  147. * @brief Returns the inverse of the projection matrix.
  148. *
  149. * @see getProjectionMatrix
  150. */
  151. virtual const Matrix4& getProjectionMatrixInv() const;
  152. /**
  153. * @brief Gets the camera view matrix. Used for positioning/orienting the camera.
  154. */
  155. virtual const Matrix4& getViewMatrix() const;
  156. /**
  157. * @brief Returns the inverse of the view matrix.
  158. *
  159. * @see getViewMatrix
  160. */
  161. virtual const Matrix4& getViewMatrixInv() const;
  162. /**
  163. * @brief Sets whether the camera should use the custom view matrix.
  164. * When this is enabled camera will no longer calculate its view matrix
  165. * based on position/orientation and caller will be resonsible to keep
  166. * the view matrix up to date.
  167. */
  168. virtual void setCustomViewMatrix(bool enable, const Matrix4& viewMatrix = Matrix4::IDENTITY);
  169. /**
  170. * @brief Returns true if a custom view matrix is used.
  171. */
  172. virtual bool isCustomViewMatrixEnabled() const { return mCustomViewMatrix; }
  173. /**
  174. * @brief Sets whether the camera should use the custom projection matrix.
  175. * When this is enabled camera will no longer calculate its projection matrix
  176. * based on field of view, aspect and other parameters and caller will be
  177. * resonsible to keep the projection matrix up to date.
  178. */
  179. virtual void setCustomProjectionMatrix(bool enable, const Matrix4& projectionMatrix = Matrix4::IDENTITY);
  180. /**
  181. * @brief Returns true if a custom projection matrix is used.
  182. */
  183. virtual bool isCustomProjectionMatrixEnabled() const { return mCustomProjMatrix; }
  184. /**
  185. * @brief Returns a convex volume representing the visible area of the camera,
  186. * in local space.
  187. */
  188. virtual const ConvexVolume& getFrustum() const;
  189. /**
  190. * @brief Returns a convex volume representing the visible area of the camera,
  191. * in world space.
  192. */
  193. virtual ConvexVolume getWorldFrustum() const;
  194. /**
  195. * @brief Returns the bounding of the frustum.
  196. */
  197. const AABox& getBoundingBox() const;
  198. /**
  199. * @brief Sets the type of projection used by the camera.
  200. */
  201. virtual void setProjectionType(ProjectionType pt);
  202. /**
  203. * @brief Returns the type of projection used by the camera.
  204. */
  205. virtual ProjectionType getProjectionType() const;
  206. /**
  207. * @brief Sets the orthographic window height, for use with orthographic rendering only.
  208. *
  209. * @param w Width of the window in world units.
  210. * @param h Height of the window in world units.
  211. *
  212. * @note Calling this method will recalculate the aspect ratio, use setOrthoWindowHeight or
  213. * setOrthoWindowWidth alone if you wish to preserve the aspect ratio but just fit one
  214. * or other dimension to a particular size.
  215. */
  216. virtual void setOrthoWindow(float w, float h);
  217. /**
  218. * @brief Sets the orthographic window height, for use with orthographic rendering only.
  219. *
  220. * @param h Height of the window in world units.
  221. *
  222. * @note The width of the window will be calculated from the aspect ratio.
  223. */
  224. virtual void setOrthoWindowHeight(float h);
  225. /**
  226. * @brief Sets the orthographic window width, for use with orthographic rendering only.
  227. *
  228. * @param w Width of the window in world units.
  229. *
  230. * @note The height of the window will be calculated from the aspect ratio.
  231. */
  232. virtual void setOrthoWindowWidth(float w);
  233. /**
  234. * @brief Gets the orthographic window width in world units, for use with orthographic rendering only.
  235. */
  236. virtual float getOrthoWindowHeight() const;
  237. /**
  238. * @brief Gets the orthographic window width in world units, for use with orthographic rendering only.
  239. *
  240. * @note This is calculated from the orthographic height and the aspect ratio.
  241. */
  242. virtual float getOrthoWindowWidth() const;
  243. /**
  244. * @brief This option tells the renderer that this camera should ignore any renderable components.
  245. */
  246. void setIgnoreSceneRenderables(bool value) { mIgnoreSceneRenderables = true; _markCoreDirty(); }
  247. /**
  248. * @brief This option tells the renderer that this camera should ignore any renderable components.
  249. */
  250. bool getIgnoreSceneRenderables() const { return mIgnoreSceneRenderables; }
  251. /**
  252. * @brief Gets a priority that determines in which orders the cameras are rendered.
  253. * This only applies to cameras rendering to the same render target.
  254. */
  255. INT32 getPriority() const { return mPriority; }
  256. /**
  257. * @brief Sets a priority that determines in which orders the cameras are rendered.
  258. * This only applies to cameras rendering to the same render target.
  259. *
  260. * @param priority The priority. Higher value means the camera will be rendered sooner.
  261. */
  262. void setPriority(INT32 priority) { mPriority = priority; _markCoreDirty(); }
  263. /**
  264. * @brief Retrieves layer bitfield that is used when determining which object should the camera render.
  265. */
  266. UINT64 getLayers() const { return mLayers; }
  267. /**
  268. * @brief Sets layer bitfield that is used when determining which object should the camera render.
  269. */
  270. void setLayers(UINT64 layers) { mLayers = layers; _markCoreDirty(); }
  271. /**
  272. * @brief Converts a point in world space to screen coordinates (in pixels
  273. * corresponding to the render target attached to the camera).
  274. */
  275. Vector2I worldToScreenPoint(const Vector3& worldPoint) const;
  276. /**
  277. * @brief Converts a point in world space to normalized clip coordinates
  278. * (in [0, 1] range).
  279. */
  280. Vector2 worldToClipPoint(const Vector3& worldPoint) const;
  281. /**
  282. * @brief Converts a point in world space to point relative to camera's
  283. * coordinate system (view space).
  284. */
  285. Vector3 worldToViewPoint(const Vector3& worldPoint) const;
  286. /**
  287. * @brief Converts a point in screen space (pixels corresponding to
  288. * render target attached to the camera) to a point in world space.
  289. */
  290. Vector3 screenToWorldPoint(const Vector2I& screenPoint) const;
  291. /**
  292. * @brief Converts a point in screen space (pixels corresponding to
  293. * render target attached to the camera) to a point relative to
  294. * camera's coordinate system (view space).
  295. */
  296. Vector3 screenToViewPoint(const Vector2I& screenPoint) const;
  297. /**
  298. * @brief Converts a point in screen space (pixels corresponding to
  299. * render target attached to the camera) to normalized clip
  300. * coordinates (in [0, 1] range).
  301. */
  302. Vector2 screenToClipPoint(const Vector2I& screenPoint) const;
  303. /**
  304. * @brief Converts a point relative to camera's coordinate system (view space)
  305. * into a point in world space.
  306. */
  307. Vector3 viewToWorldPoint(const Vector3& viewPoint) const;
  308. /**
  309. * @brief Converts a point relative to camera's coordinate system (view space)
  310. * into a point in screen space (pixels corresponding to render target
  311. * attached to the camera.
  312. */
  313. Vector2I viewToScreenPoint(const Vector3& viewPoint) const;
  314. /**
  315. * @brief Converts a point relative to camera's coordinate system (view space)
  316. * into normalized clip coordinates (in [0, 1] range).
  317. */
  318. Vector2 viewToClipPoint(const Vector3& viewPoint) const;
  319. /**
  320. * @brief Converts a point in normalized clip coordinates ([0, 1] range) to
  321. * a point in world space.
  322. */
  323. Vector3 clipToWorldPoint(const Vector2& clipPoint) const;
  324. /**
  325. * @brief Converts a point in normalized clip coordinates ([0, 1] range) to
  326. * a point relative to camera's coordinate system (view space).
  327. */
  328. Vector3 clipToViewPoint(const Vector2& clipPoint) const;
  329. /**
  330. * @brief Converts a point in normalized clip coordinates ([0, 1] range) to
  331. * a point in screen space (pixels corresponding to render target attached
  332. * to the camera)
  333. */
  334. Vector2I clipToScreenPoint(const Vector2& clipPoint) const;
  335. /**
  336. * @brief Converts a point in screen space (pixels corresponding to
  337. * render target attached to the camera) to a ray in world space
  338. * originating at the selected point on the camera near plane.
  339. */
  340. Ray screenPointToRay(const Vector2I& screenPoint) const;
  341. /**
  342. * @brief Projects a point from view to clip space.
  343. */
  344. Vector3 projectPoint(const Vector3& point) const;
  345. /**
  346. * @brief Un-projects a point in clip space to view space.
  347. */
  348. Vector3 unprojectPoint(const Vector3& point) const;
  349. static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
  350. protected:
  351. CameraHandlerBase(RenderTargetPtr target = nullptr,
  352. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  353. /**
  354. * @brief Calculate projection parameters that are used when constructing the projection matrix.
  355. */
  356. virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
  357. /**
  358. * @brief Recalculate frustum if dirty.
  359. */
  360. virtual void updateFrustum() const;
  361. /**
  362. * @brief Recalculate frustum planes if dirty.
  363. */
  364. virtual void updateFrustumPlanes() const;
  365. /**
  366. * @brief Update view matrix from parent position/orientation.
  367. *
  368. * @note Does nothing when custom view matrix is set.
  369. */
  370. virtual void updateView() const;
  371. /**
  372. * @brief Checks if the frustum requires updating.
  373. */
  374. virtual bool isFrustumOutOfDate() const;
  375. /**
  376. * @brief Notify camera that the frustum requires to be updated.
  377. */
  378. virtual void invalidateFrustum() const;
  379. /**
  380. * @brief Returns a rectangle that defines the viewport position and size, in pixels.
  381. */
  382. virtual Rect2I getViewportRect() const = 0;
  383. /**
  384. * @copydoc CoreObject::markCoreDirty
  385. */
  386. virtual void _markCoreDirty() { }
  387. protected:
  388. UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
  389. Vector3 mPosition; /**< World space position. */
  390. Quaternion mRotation; /**< World space rotation. */
  391. ProjectionType mProjType; /**< Type of camera projection. */
  392. Radian mHorzFOV; /**< Horizontal field of view represents how wide is the camera angle. */
  393. float mFarDist; /**< Clip any objects further than this. Larger value decreases depth precision at smaller depths. */
  394. float mNearDist; /**< Clip any objects close than this. Smaller value decreases depth precision at larger depths. */
  395. float mAspect; /**< Width/height viewport ratio. */
  396. float mOrthoHeight; /**< Height in world units used for orthographic cameras. */
  397. INT32 mPriority; /**< Determines in what order will the camera be rendered. Higher priority means the camera will be rendered sooner. */
  398. bool mCustomViewMatrix; /**< Is custom view matrix set. */
  399. bool mCustomProjMatrix; /**< Is custom projection matrix set. */
  400. bool mFrustumExtentsManuallySet; /**< Are frustum extents manually set. */
  401. bool mIgnoreSceneRenderables; /**< Should the camera ignore renderable components. */
  402. mutable Matrix4 mProjMatrixRS; /**< Cached render-system specific projection matrix. */
  403. mutable Matrix4 mProjMatrix; /**< Cached projection matrix that determines how are 3D points projected to a 2D viewport. */
  404. mutable Matrix4 mViewMatrix; /**< Cached view matrix that determines camera position/orientation. */
  405. mutable Matrix4 mProjMatrixRSInv;
  406. mutable Matrix4 mProjMatrixInv;
  407. mutable Matrix4 mViewMatrixInv;
  408. mutable ConvexVolume mFrustum; /**< Main clipping planes describing cameras visible area. */
  409. mutable bool mRecalcFrustum; /**< Should frustum be recalculated. */
  410. mutable bool mRecalcFrustumPlanes; /**< Should frustum planes be recalculated. */
  411. mutable bool mRecalcView; /**< Should view matrix be recalculated. */
  412. mutable float mLeft, mRight, mTop, mBottom; /**< Frustum extents. */
  413. mutable AABox mBoundingBox; /**< Frustum bounding box. */
  414. };
  415. /**
  416. * @copydoc CameraHandlerBase
  417. */
  418. class BS_EXPORT CameraHandlerCore : public CoreObjectCore, public CameraHandlerBase
  419. {
  420. public:
  421. ~CameraHandlerCore();
  422. /**
  423. * @brief Returns the viewport used by the camera.
  424. */
  425. SPtr<ViewportCore> getViewport() const { return mViewport; }
  426. protected:
  427. friend class CameraHandler;
  428. CameraHandlerCore(SPtr<RenderTargetCore> target = nullptr,
  429. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  430. CameraHandlerCore(const SPtr<ViewportCore>& viewport);
  431. /**
  432. * @copydoc CoreObjectCore::initialize
  433. */
  434. void initialize();
  435. /**
  436. * @copydoc CameraHandlerBase
  437. */
  438. virtual Rect2I getViewportRect() const;
  439. /**
  440. * @copydoc CoreObject::syncToCore
  441. */
  442. void syncToCore(const CoreSyncData& data);
  443. SPtr<ViewportCore> mViewport;
  444. };
  445. /**
  446. * @copydoc CameraHandlerBase
  447. */
  448. class BS_EXPORT CameraHandler : public IReflectable, public CoreObject, public CameraHandlerBase
  449. {
  450. public:
  451. /**
  452. * @brief Returns the viewport used by the camera.
  453. */
  454. ViewportPtr getViewport() const { return mViewport; }
  455. /**
  456. * @brief Retrieves an implementation of a camera handler usable only from the
  457. * core thread.
  458. */
  459. SPtr<CameraHandlerCore> getCore() const;
  460. /**
  461. * @brief Creates a new camera that renders to the specified portion of the provided render target.
  462. */
  463. static CameraHandlerPtr create(RenderTargetPtr target = nullptr,
  464. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  465. protected:
  466. CameraHandler(RenderTargetPtr target = nullptr,
  467. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  468. /**
  469. * @copydoc CameraHandlerBase
  470. */
  471. virtual Rect2I getViewportRect() const;
  472. /**
  473. * @copydoc CoreObject::createCore
  474. */
  475. SPtr<CoreObjectCore> createCore() const;
  476. /**
  477. * @copydoc CoreObject::markCoreDirty
  478. */
  479. void _markCoreDirty();
  480. /**
  481. * @copydoc CoreObject::syncToCore
  482. */
  483. CoreSyncData syncToCore(FrameAlloc* allocator);
  484. /**
  485. * @copydoc CoreObject::getCoreDependencies
  486. */
  487. void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
  488. /**
  489. * @brief Creates a new camera without initializing it.
  490. */
  491. static CameraHandlerPtr createEmpty();
  492. ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
  493. /************************************************************************/
  494. /* RTTI */
  495. /************************************************************************/
  496. public:
  497. friend class CameraHandlerRTTI;
  498. static RTTITypeBase* getRTTIStatic();
  499. virtual RTTITypeBase* getRTTI() const;
  500. };
  501. }