BsCamera.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "Reflection/BsIReflectable.h"
  6. #include "Math/BsMatrix4.h"
  7. #include "Math/BsVector3.h"
  8. #include "Math/BsVector2.h"
  9. #include "Math/BsVector2I.h"
  10. #include "Math/BsAABox.h"
  11. #include "Math/BsQuaternion.h"
  12. #include "Math/BsRay.h"
  13. #include "CoreThread/BsCoreObject.h"
  14. #include "Math/BsConvexVolume.h"
  15. #include "Renderer/BsRenderSettings.h"
  16. #include "Scene/BsSceneActor.h"
  17. namespace bs
  18. {
  19. /** @addtogroup Renderer-Internal
  20. * @{
  21. */
  22. /** Signals which portion of a Camera is dirty. */
  23. enum class CameraDirtyFlag
  24. {
  25. // First few bits reserved by ActorDiryFlag
  26. RenderSettings = 1 << 4
  27. };
  28. /** @} */
  29. /** @addtogroup Implementation
  30. * @{
  31. */
  32. /**
  33. * Camera determines how is world geometry projected onto a 2D surface. You may position and orient it in space, set
  34. * options like aspect ratio and field or view and it outputs view and projection matrices required for rendering.
  35. *
  36. * @note This class contains funcionality common to both core and non-core versions of the camera.
  37. */
  38. class BS_CORE_EXPORT CameraBase : public SceneActor
  39. {
  40. public:
  41. virtual ~CameraBase() { }
  42. /** @copydoc SceneActor::setTransform */
  43. void setTransform(const Transform& transform) override;
  44. /**
  45. * Determines the camera horizontal field of view. This determines how wide the camera viewing angle is along the
  46. * horizontal axis. Vertical FOV is calculated from the horizontal FOV and the aspect ratio.
  47. */
  48. virtual void setHorzFOV(const Radian& fovy);
  49. /** @copydoc setHorzFOV() */
  50. virtual const Radian& getHorzFOV() const;
  51. /**
  52. * Determines the distance from the frustum to the near clipping plane. Anything closer than the near clipping plane will
  53. * not be rendered. Decreasing this value decreases depth buffer precision.
  54. */
  55. virtual void setNearClipDistance(float nearDist);
  56. /** @copydoc setNearClipDistance() */
  57. virtual float getNearClipDistance() const;
  58. /**
  59. * Determines the distance from the frustum to the far clipping plane. Anything farther than the far clipping plane will
  60. * not be rendered. Increasing this value decreases depth buffer precision.
  61. */
  62. virtual void setFarClipDistance(float farDist);
  63. /** @copydoc setFarClipDistance() */
  64. virtual float getFarClipDistance() const;
  65. /** Determines the current viewport aspect ratio (width / height). */
  66. virtual void setAspectRatio(float ratio);
  67. /** @copydoc setAspectRatio() */
  68. virtual float getAspectRatio() const;
  69. /** Manually set the extents of the frustum that will be used when calculating the projection matrix. This will
  70. * prevents extents for being automatically calculated from aspect and near plane so it is up to the caller to keep
  71. * these values accurate.
  72. *
  73. * @param[in] left The position where the left clip plane intersect the near clip plane, in view space.
  74. * @param[in] right The position where the right clip plane intersect the near clip plane, in view space.
  75. * @param[in] top The position where the top clip plane intersect the near clip plane, in view space.
  76. * @param[in] bottom The position where the bottom clip plane intersect the near clip plane, in view space.
  77. */
  78. virtual void setFrustumExtents(float left, float right, float top, float bottom);
  79. /**
  80. * Resets frustum extents so they are automatically derived from other values. This is only relevant if you have
  81. * previously set custom extents.
  82. */
  83. virtual void resetFrustumExtents();
  84. /** Returns the extents of the frustum in view space at the near plane. */
  85. virtual void getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const;
  86. /**
  87. * Returns the standard projection matrix that determines how are 3D points projected to two dimensions. The layout
  88. * of this matrix depends on currently used render system.
  89. *
  90. * @note
  91. * You should use this matrix when sending the matrix to the render system to make sure everything works
  92. * consistently when other render systems are used.
  93. */
  94. virtual const Matrix4& getProjectionMatrixRS() const;
  95. /** Returns the inverse of the render-system specific projection matrix. See getProjectionMatrixRS(). */
  96. virtual const Matrix4& getProjectionMatrixRSInv() const;
  97. /**
  98. * Returns the standard projection matrix that determines how are 3D points projected to two dimensions. Returned
  99. * matrix is standard following right-hand rules and depth range of [-1, 1]. In case you need a render-system specific
  100. * projection matrix call getProjectionMatrixRS().
  101. */
  102. virtual const Matrix4& getProjectionMatrix() const;
  103. /** Returns the inverse of the projection matrix. See getProjectionMatrix(). */
  104. virtual const Matrix4& getProjectionMatrixInv() const;
  105. /** Gets the camera view matrix. Used for positioning/orienting the camera. */
  106. virtual const Matrix4& getViewMatrix() const;
  107. /** Returns the inverse of the view matrix. See getViewMatrix(). */
  108. virtual const Matrix4& getViewMatrixInv() const;
  109. /**
  110. * Sets whether the camera should use the custom view matrix. When this is enabled camera will no longer calculate
  111. * its view matrix based on position/orientation and caller will be resonsible to keep the view matrix up to date.
  112. */
  113. virtual void setCustomViewMatrix(bool enable, const Matrix4& viewMatrix = Matrix4::IDENTITY);
  114. /** Returns true if a custom view matrix is used. */
  115. virtual bool isCustomViewMatrixEnabled() const { return mCustomViewMatrix; }
  116. /**
  117. * Sets whether the camera should use the custom projection matrix. When this is enabled camera will no longer
  118. * calculate its projection matrix based on field of view, aspect and other parameters and caller will be resonsible
  119. * to keep the projection matrix up to date.
  120. */
  121. virtual void setCustomProjectionMatrix(bool enable, const Matrix4& projectionMatrix = Matrix4::IDENTITY);
  122. /** Returns true if a custom projection matrix is used. */
  123. virtual bool isCustomProjectionMatrixEnabled() const { return mCustomProjMatrix; }
  124. /** Returns a convex volume representing the visible area of the camera, in local space. */
  125. virtual const ConvexVolume& getFrustum() const;
  126. /** Returns a convex volume representing the visible area of the camera, in world space. */
  127. virtual ConvexVolume getWorldFrustum() const;
  128. /** Returns the bounding of the frustum. */
  129. const AABox& getBoundingBox() const;
  130. /**
  131. * Determines the type of projection used by the camera. Projection type controls how is 3D geometry projected onto a
  132. * 2D plane.
  133. */
  134. virtual void setProjectionType(ProjectionType pt);
  135. /** @copydoc setProjectionType() */
  136. virtual ProjectionType getProjectionType() const;
  137. /**
  138. * Sets the orthographic window height, for use with orthographic rendering only.
  139. *
  140. * @param[in] w Width of the window in world units.
  141. * @param[in] h Height of the window in world units.
  142. *
  143. * @note
  144. * Calling this method will recalculate the aspect ratio, use setOrthoWindowHeight() or setOrthoWindowWidth() alone
  145. * if you wish to preserve the aspect ratio but just fit one or other dimension to a particular size.
  146. */
  147. virtual void setOrthoWindow(float w, float h);
  148. /**
  149. * Determines the orthographic window height, for use with orthographic rendering only. The width of the window
  150. * will be calculated from the aspect ratio. Value is specified in world units.
  151. */
  152. virtual void setOrthoWindowHeight(float h);
  153. /** @copydoc setOrthoWindowHeight() */
  154. virtual float getOrthoWindowHeight() const;
  155. /**
  156. * Determines the orthographic window width, for use with orthographic rendering only. The height of the window
  157. * will be calculated from the aspect ratio. Value is specified in world units.
  158. */
  159. virtual void setOrthoWindowWidth(float w);
  160. /** @copydoc setOrthoWindowWidth() */
  161. virtual float getOrthoWindowWidth() const;
  162. /**
  163. * Determines a priority that determines in which orders the cameras are rendered. This only applies to cameras rendering
  164. * to the same render target. Higher value means the camera will be rendered sooner.
  165. */
  166. void setPriority(INT32 priority) { mPriority = priority; _markCoreDirty(); }
  167. /** @copydoc setPriority() */
  168. INT32 getPriority() const { return mPriority; }
  169. /** Determines layer bitfield that is used when determining which object should the camera render. */
  170. void setLayers(UINT64 layers) { mLayers = layers; _markCoreDirty(); }
  171. /** @copydoc setLayers() */
  172. UINT64 getLayers() const { return mLayers; }
  173. /**
  174. * Determines number of samples to use when rendering to this camera. Values larger than 1 will enable MSAA
  175. * rendering.
  176. */
  177. void setMSAACount(UINT32 count) { mMSAA = count; _markCoreDirty(); }
  178. /** @copydoc setMSAACount() */
  179. UINT32 getMSAACount() const { return mMSAA; }
  180. /**
  181. * Settings that control rendering for this view. They determine how will the renderer process this view, which
  182. * effects will be enabled, and what properties will those effects use.
  183. */
  184. void setRenderSettings(const SPtr<RenderSettings>& settings)
  185. { mRenderSettings = settings; _markCoreDirty((ActorDirtyFlag)CameraDirtyFlag::RenderSettings); }
  186. /** @copydoc setRenderSettings() */
  187. const SPtr<RenderSettings>& getRenderSettings() const { return mRenderSettings; }
  188. /**
  189. * Converts a point in world space to screen coordinates.
  190. *
  191. * @param[in] worldPoint 3D point in world space.
  192. * @return 2D point on the render target attached to the camera's viewport, in pixels.
  193. */
  194. Vector2I worldToScreenPoint(const Vector3& worldPoint) const;
  195. /**
  196. * Converts a point in world space to normalized device coordinates.
  197. *
  198. * @param[in] worldPoint 3D point in world space.
  199. * @return 2D point in normalized device coordinates ([-1, 1] range), relative to the camera's viewport.
  200. */
  201. Vector2 worldToNdcPoint(const Vector3& worldPoint) const;
  202. /**
  203. * Converts a point in world space to view space coordinates.
  204. *
  205. * @param[in] worldPoint 3D point in world space.
  206. * @return 3D point relative to the camera's coordinate system.
  207. */
  208. Vector3 worldToViewPoint(const Vector3& worldPoint) const;
  209. /**
  210. * Converts a point in screen space to a point in world space.
  211. *
  212. * @param[in] screenPoint 2D point on the render target attached to the camera's viewport, in pixels.
  213. * @param[in] depth Depth to place the world point at, in world coordinates. The depth is applied to the
  214. * vector going from camera origin to the point on the near plane.
  215. * @return 3D point in world space.
  216. */
  217. Vector3 screenToWorldPoint(const Vector2I& screenPoint, float depth = 0.5f) const;
  218. /**
  219. * Converts a point in screen space (pixels corresponding to render target attached to the camera) to a point in
  220. * world space.
  221. *
  222. * @param[in] screenPoint Point to transform.
  223. * @param[in] deviceDepth Depth to place the world point at, in normalized device coordinates.
  224. * @return 3D point in world space.
  225. */
  226. Vector3 screenToWorldPointDeviceDepth(const Vector2I& screenPoint, float deviceDepth = 0.5f) const;
  227. /**
  228. * Converts a point in screen space to a point in view space.
  229. *
  230. * @param[in] screenPoint 2D point on the render target attached to the camera's viewport, in pixels.
  231. * @param[in] depth Depth to place the world point at, in device depth. The depth is applied to the
  232. * vector going from camera origin to the point on the near plane.
  233. * @return 3D point relative to the camera's coordinate system.
  234. */
  235. Vector3 screenToViewPoint(const Vector2I& screenPoint, float depth = 0.5f) const;
  236. /**
  237. * Converts a point in screen space to normalized device coordinates.
  238. *
  239. * @param[in] screenPoint 2D point on the render target attached to the camera's viewport, in pixels.
  240. * @return 2D point in normalized device coordinates ([-1, 1] range), relative to
  241. * the camera's viewport.
  242. */
  243. Vector2 screenToNdcPoint(const Vector2I& screenPoint) const;
  244. /**
  245. * Converts a point in view space to world space.
  246. *
  247. * @param[in] viewPoint 3D point relative to the camera's coordinate system.
  248. * @return 3D point in world space.
  249. */
  250. Vector3 viewToWorldPoint(const Vector3& viewPoint) const;
  251. /**
  252. * Converts a point in view space to screen space.
  253. *
  254. * @param[in] viewPoint 3D point relative to the camera's coordinate system.
  255. * @return 2D point on the render target attached to the camera's viewport, in pixels.
  256. */
  257. Vector2I viewToScreenPoint(const Vector3& viewPoint) const;
  258. /**
  259. * Converts a point in view space to normalized device coordinates.
  260. *
  261. * @param[in] viewPoint 3D point relative to the camera's coordinate system.
  262. * @return 2D point in normalized device coordinates ([-1, 1] range), relative to
  263. * the camera's viewport.
  264. */
  265. Vector2 viewToNdcPoint(const Vector3& viewPoint) const;
  266. /**
  267. * Converts a point in normalized device coordinates to world space.
  268. *
  269. * @param[in] ndcPoint 2D point in normalized device coordinates ([-1, 1] range), relative to
  270. * the camera's viewport.
  271. * @param[in] depth Depth to place the world point at. The depth is applied to the
  272. * vector going from camera origin to the point on the near plane.
  273. * @return 3D point in world space.
  274. */
  275. Vector3 ndcToWorldPoint(const Vector2& ndcPoint, float depth = 0.5f) const;
  276. /**
  277. * Converts a point in normalized device coordinates to view space.
  278. *
  279. * @param[in] ndcPoint 2D point in normalized device coordinates ([-1, 1] range), relative to
  280. * the camera's viewport.
  281. * @param[in] depth Depth to place the world point at. The depth is applied to the
  282. * vector going from camera origin to the point on the near plane.
  283. * @return 3D point relative to the camera's coordinate system.
  284. */
  285. Vector3 ndcToViewPoint(const Vector2& ndcPoint, float depth = 0.5f) const;
  286. /**
  287. * Converts a point in normalized device coordinates to screen space.
  288. *
  289. * @param[in] ndcPoint 2D point in normalized device coordinates ([-1, 1] range), relative to
  290. * the camera's viewport.
  291. * @return 2D point on the render target attached to the camera's viewport, in pixels.
  292. */
  293. Vector2I ndcToScreenPoint(const Vector2& ndcPoint) const;
  294. /**
  295. * Converts a point in screen space to a ray in world space.
  296. *
  297. * @param[in] screenPoint 2D point on the render target attached to the camera's viewport, in pixels.
  298. * @return Ray in world space, originating at the selected point on the camera near plane.
  299. */
  300. Ray screenPointToRay(const Vector2I& screenPoint) const;
  301. /**
  302. * Projects a point in view space to normalized device coordinates. Similar to viewToNdcPoint() but preserves
  303. * the depth component.
  304. *
  305. * @param[in] point 3D point relative to the camera's coordinate system.
  306. * @return 3D point in normalized device coordinates ([-1, 1] range), relative to the
  307. * camera's viewport. Z value range depends on active render API.
  308. */
  309. Vector3 projectPoint(const Vector3& point) const;
  310. /** Un-projects a point in normalized device space to view space.
  311. *
  312. * @param[in] point 3D point in normalized device coordinates ([-1, 1] range), relative to the
  313. * camera's viewport. Z value range depends on active render API.
  314. * @return 3D point relative to the camera's coordinate system.
  315. */
  316. Vector3 unprojectPoint(const Vector3& point) const;
  317. static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
  318. protected:
  319. CameraBase();
  320. /** Calculate projection parameters that are used when constructing the projection matrix. */
  321. virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
  322. /** Recalculate frustum if dirty. */
  323. virtual void updateFrustum() const;
  324. /** Recalculate frustum planes if dirty. */
  325. virtual void updateFrustumPlanes() const;
  326. /**
  327. * Update view matrix from parent position/orientation.
  328. *
  329. * @note Does nothing when custom view matrix is set.
  330. */
  331. virtual void updateView() const;
  332. /** Checks if the frustum requires updating. */
  333. virtual bool isFrustumOutOfDate() const;
  334. /** Notify camera that the frustum requires to be updated. */
  335. virtual void invalidateFrustum() const;
  336. /** Returns a rectangle that defines the viewport position and size, in pixels. */
  337. virtual Rect2I getViewportRect() const = 0;
  338. protected:
  339. UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
  340. ProjectionType mProjType; /**< Type of camera projection. */
  341. Radian mHorzFOV; /**< Horizontal field of view represents how wide is the camera angle. */
  342. float mFarDist; /**< Clip any objects further than this. Larger value decreases depth precision at smaller depths. */
  343. float mNearDist; /**< Clip any objects close than this. Smaller value decreases depth precision at larger depths. */
  344. float mAspect; /**< Width/height viewport ratio. */
  345. float mOrthoHeight; /**< Height in world units used for orthographic cameras. */
  346. INT32 mPriority; /**< Determines in what order will the camera be rendered. Higher priority means the camera will be rendered sooner. */
  347. bool mCustomViewMatrix; /**< Is custom view matrix set. */
  348. bool mCustomProjMatrix; /**< Is custom projection matrix set. */
  349. UINT8 mMSAA; /**< Number of samples to render the scene with. */
  350. SPtr<RenderSettings> mRenderSettings; /**< Settings used to control rendering for this camera. */
  351. bool mFrustumExtentsManuallySet; /**< Are frustum extents manually set. */
  352. mutable Matrix4 mProjMatrixRS; /**< Cached render-system specific projection matrix. */
  353. mutable Matrix4 mProjMatrix; /**< Cached projection matrix that determines how are 3D points projected to a 2D viewport. */
  354. mutable Matrix4 mViewMatrix; /**< Cached view matrix that determines camera position/orientation. */
  355. mutable Matrix4 mProjMatrixRSInv;
  356. mutable Matrix4 mProjMatrixInv;
  357. mutable Matrix4 mViewMatrixInv;
  358. mutable ConvexVolume mFrustum; /**< Main clipping planes describing cameras visible area. */
  359. mutable bool mRecalcFrustum : 1; /**< Should frustum be recalculated. */
  360. mutable bool mRecalcFrustumPlanes : 1; /**< Should frustum planes be recalculated. */
  361. mutable bool mRecalcView : 1; /**< Should view matrix be recalculated. */
  362. mutable float mLeft, mRight, mTop, mBottom; /**< Frustum extents. */
  363. mutable AABox mBoundingBox; /**< Frustum bounding box. */
  364. };
  365. /** @} */
  366. /** @addtogroup Renderer-Internal
  367. * @{
  368. */
  369. /** @copydoc CameraBase */
  370. class BS_CORE_EXPORT Camera : public IReflectable, public CoreObject, public CameraBase
  371. {
  372. public:
  373. /** Returns the viewport used by the camera. */
  374. SPtr<Viewport> getViewport() const { return mViewport; }
  375. /**
  376. * Determines whether this is the main application camera. Main camera controls the final render surface that is
  377. * displayed to the user.
  378. */
  379. void setMain(bool main) { mMain = main; }
  380. /** @copydoc setMain() */
  381. bool isMain() const { return mMain; }
  382. /** Retrieves an implementation of a camera handler usable only from the core thread. */
  383. SPtr<ct::Camera> getCore() const;
  384. /** Creates a new camera that renders to the specified portion of the provided render target. */
  385. static SPtr<Camera> create(SPtr<RenderTarget> target = nullptr,
  386. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  387. /**
  388. * @name Internal
  389. * @{
  390. */
  391. /** @copydoc CoreObject::initialize */
  392. void initialize() override;
  393. /** @copydoc CoreObject::destroy */
  394. void destroy() override;
  395. /** @} */
  396. protected:
  397. Camera(SPtr<RenderTarget> target = nullptr,
  398. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  399. /** @copydoc CameraBase */
  400. Rect2I getViewportRect() const override;
  401. /** @copydoc CoreObject::createCore */
  402. SPtr<ct::CoreObject> createCore() const override;
  403. /** @copydoc CameraBase::_markCoreDirty */
  404. void _markCoreDirty(ActorDirtyFlag flag = ActorDirtyFlag::Everything) override;
  405. /** @copydoc CoreObject::syncToCore */
  406. CoreSyncData syncToCore(FrameAlloc* allocator) override;
  407. /** @copydoc CoreObject::getCoreDependencies */
  408. void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
  409. /** Creates a new camera without initializing it. */
  410. static SPtr<Camera> createEmpty();
  411. SPtr<Viewport> mViewport; /**< Viewport that describes 2D rendering surface. */
  412. bool mMain;
  413. /************************************************************************/
  414. /* RTTI */
  415. /************************************************************************/
  416. public:
  417. friend class CameraRTTI;
  418. static RTTITypeBase* getRTTIStatic();
  419. RTTITypeBase* getRTTI() const override;
  420. };
  421. namespace ct
  422. {
  423. /** @copydoc CameraBase */
  424. class BS_CORE_EXPORT Camera : public CoreObject, public CameraBase
  425. {
  426. public:
  427. ~Camera();
  428. /** Returns the viewport used by the camera. */
  429. SPtr<Viewport> getViewport() const { return mViewport; }
  430. /** Sets an ID that can be used for uniquely identifying this object by the renderer. */
  431. void setRendererId(UINT32 id) { mRendererId = id; }
  432. /** Retrieves an ID that can be used for uniquely identifying this object by the renderer. */
  433. UINT32 getRendererId() const { return mRendererId; }
  434. protected:
  435. friend class bs::Camera;
  436. Camera(SPtr<RenderTarget> target = nullptr,
  437. float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
  438. Camera(const SPtr<Viewport>& viewport);
  439. /** @copydoc CoreObject::initialize */
  440. void initialize() override;
  441. /** @copydoc CameraBase */
  442. Rect2I getViewportRect() const override;
  443. /** @copydoc CoreObject::syncToCore */
  444. void syncToCore(const CoreSyncData& data) override;
  445. UINT32 mRendererId;
  446. SPtr<Viewport> mViewport;
  447. };
  448. }
  449. /** @} */
  450. }