| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599 |
- #pragma once
- #include "BsPrerequisites.h"
- #include "BsIReflectable.h"
- #include "BsMatrix4.h"
- #include "BsVector3.h"
- #include "BsVector2.h"
- #include "BsVector2I.h"
- #include "BsAABox.h"
- #include "BsQuaternion.h"
- #include "BsRay.h"
- #include "BsCoreObject.h"
- #include "BsConvexVolume.h"
- namespace BansheeEngine
- {
- /**
- * @brief Specified projection type to use by the camera.
- */
- enum ProjectionType
- {
- PT_ORTHOGRAPHIC,
- PT_PERSPECTIVE
- };
- /**
- * @brief Clip planes that form the camera frustum (visible area).
- */
- enum FrustumPlane
- {
- FRUSTUM_PLANE_NEAR = 0,
- FRUSTUM_PLANE_FAR = 1,
- FRUSTUM_PLANE_LEFT = 2,
- FRUSTUM_PLANE_RIGHT = 3,
- FRUSTUM_PLANE_TOP = 4,
- FRUSTUM_PLANE_BOTTOM = 5
- };
- /**
- * @brief Camera determines how is world geometry projected onto a 2D surface. You may
- * position and orient it in space, set options like aspect ratio and field or view
- * and it outputs view and projection matrices required for rendering.
- */
- class BS_EXPORT CameraHandlerBase
- {
- public:
- virtual ~CameraHandlerBase() { }
- /**
- * @brief Sets the camera horizontal field of view. This determines how wide the camera
- * viewing angle is along the horizontal axis. Vertical FOV is calculated from the
- * horizontal FOV and the aspect.
- */
- virtual void setHorzFOV(const Radian& fovy);
- /**
- * @brief Retrieves the camera horizontal field of view.
- */
- virtual const Radian& getHorzFOV() const;
- /**
- * @brief Sets the distance from the frustum to the near clipping plane. Anything
- * closer than the near clipping plane will not be rendered. Decreasing this value
- * decreases depth buffer precision.
- */
- virtual void setNearClipDistance(float nearDist);
- /**
- * @brief Retrieves the distance from the frustum to the near clipping plane. Anything
- * closer than the near clipping plane will not be rendered. Decreasing this value
- * decreases depth buffer precision.
- */
- virtual float getNearClipDistance() const;
- /**
- * @brief Sets the distance from the frustum to the far clipping plane. Anything
- * farther than the far clipping plane will not be rendered. Increasing this value
- * decreases depth buffer precision.
- */
- virtual void setFarClipDistance(float farDist);
- /**
- * @brief Retrieves the distance from the frustum to the far clipping plane. Anything
- * farther than the far clipping plane will not be rendered. Increasing this value
- * decreases depth buffer precision.
- */
- virtual float getFarClipDistance() const;
- /**
- * @brief Sets the current viewport aspect ratio (width / height).
- */
- virtual void setAspectRatio(float ratio);
- /**
- * @brief Returns current viewport aspect ratio (width / height).
- */
- virtual float getAspectRatio() const;
- /**
- * @brief Sets camera world space position.
- */
- virtual void setPosition(const Vector3& position);
- /**
- * @brief Retrieves camera world space position.
- */
- virtual Vector3 getPosition() const { return mPosition; }
- /**
- * @brief Sets camera world space rotation.
- */
- virtual void setRotation(const Quaternion& rotation);
- /**
- * @brief Retrieves camera world space rotation.
- */
- virtual Quaternion getRotation() const { return mRotation; }
- /** @brief Manually set the extents of the frustum that will be used when calculating the
- * projection matrix. This will prevents extents for being automatically calculated
- * from aspect and near plane so it is up to the caller to keep these values
- * accurate.
- *
- * @param left The position where the left clip plane intersect the near clip plane, in view space.
- * @param right The position where the right clip plane intersect the near clip plane, in view space.
- * @param top The position where the top clip plane intersect the near clip plane, in view space.
- * @param bottom The position where the bottom clip plane intersect the near clip plane, in view space.
- */
- virtual void setFrustumExtents(float left, float right, float top, float bottom);
- /**
- * @brief Resets frustum extents so they are automatically derived from other values.
- * This is only relevant if you have previously set custom extents.
- */
- virtual void resetFrustumExtents();
- /**
- * @brief Returns the extents of the frustum in view space at the near plane.
- */
- virtual void getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const;
- /**
- * @brief Returns the standard projection matrix that determines how are 3D points
- * projected to two dimensions. The layout of this matrix depends on currently
- * used render system.
- *
- * @note You should use this matrix when sending the matrix to the render system to remain
- * everything works consistently when other render systems are used.
- */
- virtual const Matrix4& getProjectionMatrixRS() const;
- /**
- * @brief Returns the inverse of the render-system specific projection matrix.
- *
- * @see getProjectionMatrixRS
- */
- virtual const Matrix4& getProjectionMatrixRSInv() const;
- /**
- * @brief Returns the standard projection matrix that determines how are 3D points
- * projected to two dimensions. Returned matrix is standard following right-hand
- * rules and depth range of [-1, 1].
- *
- * @note Different render systems will expect different projection matrix layouts, in which
- * case use getProjectionMatrixRS.
- */
- virtual const Matrix4& getProjectionMatrix() const;
- /**
- * @brief Returns the inverse of the projection matrix.
- *
- * @see getProjectionMatrix
- */
- virtual const Matrix4& getProjectionMatrixInv() const;
- /**
- * @brief Gets the camera view matrix. Used for positioning/orienting the camera.
- */
- virtual const Matrix4& getViewMatrix() const;
- /**
- * @brief Returns the inverse of the view matrix.
- *
- * @see getViewMatrix
- */
- virtual const Matrix4& getViewMatrixInv() const;
- /**
- * @brief Sets whether the camera should use the custom view matrix.
- * When this is enabled camera will no longer calculate its view matrix
- * based on position/orientation and caller will be resonsible to keep
- * the view matrix up to date.
- */
- virtual void setCustomViewMatrix(bool enable, const Matrix4& viewMatrix = Matrix4::IDENTITY);
- /**
- * @brief Returns true if a custom view matrix is used.
- */
- virtual bool isCustomViewMatrixEnabled() const { return mCustomViewMatrix; }
-
- /**
- * @brief Sets whether the camera should use the custom projection matrix.
- * When this is enabled camera will no longer calculate its projection matrix
- * based on field of view, aspect and other parameters and caller will be
- * resonsible to keep the projection matrix up to date.
- */
- virtual void setCustomProjectionMatrix(bool enable, const Matrix4& projectionMatrix = Matrix4::IDENTITY);
- /**
- * @brief Returns true if a custom projection matrix is used.
- */
- virtual bool isCustomProjectionMatrixEnabled() const { return mCustomProjMatrix; }
- /**
- * @brief Returns a convex volume representing the visible area of the camera,
- * in local space.
- */
- virtual const ConvexVolume& getFrustum() const;
- /**
- * @brief Returns a convex volume representing the visible area of the camera,
- * in world space.
- */
- virtual ConvexVolume getWorldFrustum() const;
- /**
- * @brief Returns the bounding of the frustum.
- */
- const AABox& getBoundingBox() const;
- /**
- * @brief Sets the type of projection used by the camera.
- */
- virtual void setProjectionType(ProjectionType pt);
- /**
- * @brief Returns the type of projection used by the camera.
- */
- virtual ProjectionType getProjectionType() const;
- /**
- * @brief Sets the orthographic window height, for use with orthographic rendering only.
- *
- * @param w Width of the window in world units.
- * @param h Height of the window in world units.
- *
- * @note Calling this method will recalculate the aspect ratio, use setOrthoWindowHeight or
- * setOrthoWindowWidth alone if you wish to preserve the aspect ratio but just fit one
- * or other dimension to a particular size.
- */
- virtual void setOrthoWindow(float w, float h);
- /**
- * @brief Sets the orthographic window height, for use with orthographic rendering only.
- *
- * @param h Height of the window in world units.
- *
- * @note The width of the window will be calculated from the aspect ratio.
- */
- virtual void setOrthoWindowHeight(float h);
- /**
- * @brief Sets the orthographic window width, for use with orthographic rendering only.
- *
- * @param w Width of the window in world units.
- *
- * @note The height of the window will be calculated from the aspect ratio.
- */
- virtual void setOrthoWindowWidth(float w);
- /**
- * @brief Gets the orthographic window width in world units, for use with orthographic rendering only.
- */
- virtual float getOrthoWindowHeight() const;
- /**
- * @brief Gets the orthographic window width in world units, for use with orthographic rendering only.
- *
- * @note This is calculated from the orthographic height and the aspect ratio.
- */
- virtual float getOrthoWindowWidth() const;
- /**
- * @brief This option tells the renderer that this camera should ignore any renderable components.
- */
- void setIgnoreSceneRenderables(bool value) { mIgnoreSceneRenderables = true; _markCoreDirty(); }
- /**
- * @brief This option tells the renderer that this camera should ignore any renderable components.
- */
- bool getIgnoreSceneRenderables() const { return mIgnoreSceneRenderables; }
- /**
- * @brief Gets a priority that determines in which orders the cameras are rendered.
- * This only applies to cameras rendering to the same render target.
- */
- INT32 getPriority() const { return mPriority; }
- /**
- * @brief Sets a priority that determines in which orders the cameras are rendered.
- * This only applies to cameras rendering to the same render target.
- *
- * @param priority The priority. Higher value means the camera will be rendered sooner.
- */
- void setPriority(INT32 priority) { mPriority = priority; _markCoreDirty(); }
- /**
- * @brief Retrieves layer bitfield that is used when determining which object should the camera render.
- */
- UINT64 getLayers() const { return mLayers; }
- /**
- * @brief Sets layer bitfield that is used when determining which object should the camera render.
- */
- void setLayers(UINT64 layers) { mLayers = layers; _markCoreDirty(); }
- /**
- * @brief Converts a point in world space to screen coordinates (in pixels
- * corresponding to the render target attached to the camera).
- */
- Vector2I worldToScreenPoint(const Vector3& worldPoint) const;
- /**
- * @brief Converts a point in world space to normalized clip coordinates
- * (in [0, 1] range).
- */
- Vector2 worldToClipPoint(const Vector3& worldPoint) const;
- /**
- * @brief Converts a point in world space to point relative to camera's
- * coordinate system (view space).
- */
- Vector3 worldToViewPoint(const Vector3& worldPoint) const;
- /**
- * @brief Converts a point in screen space (pixels corresponding to
- * render target attached to the camera) to a point in world space.
- */
- Vector3 screenToWorldPoint(const Vector2I& screenPoint) const;
- /**
- * @brief Converts a point in screen space (pixels corresponding to
- * render target attached to the camera) to a point relative to
- * camera's coordinate system (view space).
- */
- Vector3 screenToViewPoint(const Vector2I& screenPoint) const;
- /**
- * @brief Converts a point in screen space (pixels corresponding to
- * render target attached to the camera) to normalized clip
- * coordinates (in [0, 1] range).
- */
- Vector2 screenToClipPoint(const Vector2I& screenPoint) const;
- /**
- * @brief Converts a point relative to camera's coordinate system (view space)
- * into a point in world space.
- */
- Vector3 viewToWorldPoint(const Vector3& viewPoint) const;
- /**
- * @brief Converts a point relative to camera's coordinate system (view space)
- * into a point in screen space (pixels corresponding to render target
- * attached to the camera.
- */
- Vector2I viewToScreenPoint(const Vector3& viewPoint) const;
- /**
- * @brief Converts a point relative to camera's coordinate system (view space)
- * into normalized clip coordinates (in [0, 1] range).
- */
- Vector2 viewToClipPoint(const Vector3& viewPoint) const;
- /**
- * @brief Converts a point in normalized clip coordinates ([0, 1] range) to
- * a point in world space.
- */
- Vector3 clipToWorldPoint(const Vector2& clipPoint) const;
- /**
- * @brief Converts a point in normalized clip coordinates ([0, 1] range) to
- * a point relative to camera's coordinate system (view space).
- */
- Vector3 clipToViewPoint(const Vector2& clipPoint) const;
- /**
- * @brief Converts a point in normalized clip coordinates ([0, 1] range) to
- * a point in screen space (pixels corresponding to render target attached
- * to the camera)
- */
- Vector2I clipToScreenPoint(const Vector2& clipPoint) const;
- /**
- * @brief Converts a point in screen space (pixels corresponding to
- * render target attached to the camera) to a ray in world space
- * originating at the selected point on the camera near plane.
- */
- Ray screenPointToRay(const Vector2I& screenPoint) const;
- /**
- * @brief Projects a point from view to clip space.
- */
- Vector3 projectPoint(const Vector3& point) const;
- /**
- * @brief Un-projects a point in clip space to view space.
- */
- Vector3 unprojectPoint(const Vector3& point) const;
- static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
- protected:
- CameraHandlerBase(RenderTargetPtr target = nullptr,
- float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
- /**
- * @brief Calculate projection parameters that are used when constructing the projection matrix.
- */
- virtual void calcProjectionParameters(float& left, float& right, float& bottom, float& top) const;
- /**
- * @brief Recalculate frustum if dirty.
- */
- virtual void updateFrustum() const;
- /**
- * @brief Recalculate frustum planes if dirty.
- */
- virtual void updateFrustumPlanes() const;
- /**
- * @brief Update view matrix from parent position/orientation.
- *
- * @note Does nothing when custom view matrix is set.
- */
- virtual void updateView() const;
- /**
- * @brief Checks if the frustum requires updating.
- */
- virtual bool isFrustumOutOfDate() const;
- /**
- * @brief Notify camera that the frustum requires to be updated.
- */
- virtual void invalidateFrustum() const;
- /**
- * @brief Returns a rectangle that defines the viewport position and size, in pixels.
- */
- virtual Rect2I getViewportRect() const = 0;
- /**
- * @copydoc CoreObject::markCoreDirty
- */
- virtual void _markCoreDirty() { }
- protected:
- UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
- Vector3 mPosition; /**< World space position. */
- Quaternion mRotation; /**< World space rotation. */
- ProjectionType mProjType; /**< Type of camera projection. */
- Radian mHorzFOV; /**< Horizontal field of view represents how wide is the camera angle. */
- float mFarDist; /**< Clip any objects further than this. Larger value decreases depth precision at smaller depths. */
- float mNearDist; /**< Clip any objects close than this. Smaller value decreases depth precision at larger depths. */
- float mAspect; /**< Width/height viewport ratio. */
- float mOrthoHeight; /**< Height in world units used for orthographic cameras. */
- INT32 mPriority; /**< Determines in what order will the camera be rendered. Higher priority means the camera will be rendered sooner. */
- bool mCustomViewMatrix; /**< Is custom view matrix set. */
- bool mCustomProjMatrix; /**< Is custom projection matrix set. */
- bool mFrustumExtentsManuallySet; /**< Are frustum extents manually set. */
- bool mIgnoreSceneRenderables; /**< Should the camera ignore renderable components. */
- mutable Matrix4 mProjMatrixRS; /**< Cached render-system specific projection matrix. */
- mutable Matrix4 mProjMatrix; /**< Cached projection matrix that determines how are 3D points projected to a 2D viewport. */
- mutable Matrix4 mViewMatrix; /**< Cached view matrix that determines camera position/orientation. */
- mutable Matrix4 mProjMatrixRSInv;
- mutable Matrix4 mProjMatrixInv;
- mutable Matrix4 mViewMatrixInv;
- mutable ConvexVolume mFrustum; /**< Main clipping planes describing cameras visible area. */
- mutable bool mRecalcFrustum; /**< Should frustum be recalculated. */
- mutable bool mRecalcFrustumPlanes; /**< Should frustum planes be recalculated. */
- mutable bool mRecalcView; /**< Should view matrix be recalculated. */
- mutable float mLeft, mRight, mTop, mBottom; /**< Frustum extents. */
- mutable AABox mBoundingBox; /**< Frustum bounding box. */
- };
- /**
- * @copydoc CameraHandlerBase
- */
- class BS_EXPORT CameraHandlerCore : public CoreObjectCore, public CameraHandlerBase
- {
- public:
- ~CameraHandlerCore();
- /**
- * @brief Returns the viewport used by the camera.
- */
- SPtr<ViewportCore> getViewport() const { return mViewport; }
- protected:
- friend class CameraHandler;
- CameraHandlerCore(SPtr<RenderTargetCore> target = nullptr,
- float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
- CameraHandlerCore(const SPtr<ViewportCore>& viewport);
- /**
- * @copydoc CoreObjectCore::initialize
- */
- void initialize();
- /**
- * @copydoc CameraHandlerBase
- */
- virtual Rect2I getViewportRect() const;
- /**
- * @copydoc CoreObject::syncToCore
- */
- void syncToCore(const CoreSyncData& data);
- SPtr<ViewportCore> mViewport;
- };
- /**
- * @copydoc CameraHandlerBase
- */
- class BS_EXPORT CameraHandler : public IReflectable, public CoreObject, public CameraHandlerBase
- {
- public:
- /**
- * @brief Returns the viewport used by the camera.
- */
- ViewportPtr getViewport() const { return mViewport; }
- /**
- * @brief Retrieves an implementation of a camera handler usable only from the
- * core thread.
- */
- SPtr<CameraHandlerCore> getCore() const;
- /**
- * @brief Creates a new camera that renders to the specified portion of the provided render target.
- */
- static CameraHandlerPtr create(RenderTargetPtr target = nullptr,
- float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
- protected:
- CameraHandler(RenderTargetPtr target = nullptr,
- float left = 0.0f, float top = 0.0f, float width = 1.0f, float height = 1.0f);
- /**
- * @copydoc CameraHandlerBase
- */
- virtual Rect2I getViewportRect() const;
- /**
- * @copydoc CoreObject::createCore
- */
- SPtr<CoreObjectCore> createCore() const;
- /**
- * @copydoc CoreObject::markCoreDirty
- */
- void _markCoreDirty();
- /**
- * @copydoc CoreObject::syncToCore
- */
- CoreSyncData syncToCore(FrameAlloc* allocator);
- /**
- * @copydoc CoreObject::getCoreDependencies
- */
- void getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies);
- /**
- * @brief Creates a new camera without initializing it.
- */
- static CameraHandlerPtr createEmpty();
- ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
- /************************************************************************/
- /* RTTI */
- /************************************************************************/
- public:
- friend class CameraHandlerRTTI;
- static RTTITypeBase* getRTTIStatic();
- virtual RTTITypeBase* getRTTI() const;
- };
- }
|