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