// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "../Actor.h" #include "Engine/Core/Math/BoundingFrustum.h" #include "Engine/Core/Math/Viewport.h" #include "Engine/Core/Math/Ray.h" #include "Engine/Core/Types/LayersMask.h" #include "Engine/Graphics/Enums.h" #include "Engine/Scripting/ScriptingObjectReference.h" #if USE_EDITOR #include "Engine/Content/AssetReference.h" #include "Engine/Graphics/Models/ModelInstanceEntry.h" #include "Engine/Content/Assets/Model.h" #endif /// /// Describes the camera projection and view. Provides information about how to render scene (viewport location and direction, etc.). /// API_CLASS(Sealed, Attributes="ActorContextMenu(\"New/Camera\"), ActorToolbox(\"Visuals\")") class FLAXENGINE_API Camera : public Actor { DECLARE_SCENE_OBJECT(Camera); // List with all created cameras actors on the scene static Array Cameras; // The current cut-scene camera. Set by the Scene Animation Player to the current shot camera. static Camera* CutSceneCamera; // The overriden main camera. API_FIELD() static ScriptingObjectReference OverrideMainCamera; // Gets the main camera. API_PROPERTY() static Camera* GetMainCamera(); private: BoundingFrustum _frustum; // Camera Settings bool _usePerspective; float _fov; float _customAspectRatio; float _near; float _far; float _orthoSize; float _orthoScale; #if USE_EDITOR AssetReference _previewModel; ModelInstanceEntries _previewModelBuffer; BoundingBox _previewModelBox; int32 _sceneRenderingKey = -1; #endif public: /// /// Gets the frustum. /// API_PROPERTY() FORCE_INLINE BoundingFrustum GetFrustum() const { return _frustum; } public: /// /// Gets the value indicating if camera should use perspective rendering mode, otherwise it will use orthographic projection. /// API_PROPERTY(Attributes="EditorOrder(10), DefaultValue(true), EditorDisplay(\"Camera\")") bool GetUsePerspective() const; /// /// Sets the value indicating if camera should use perspective rendering mode, otherwise it will use orthographic projection. /// API_PROPERTY() void SetUsePerspective(bool value); /// /// Gets the camera's field of view (in degrees). /// API_PROPERTY(Attributes="EditorOrder(20), DefaultValue(60.0f), Limit(0, 179), EditorDisplay(\"Camera\", \"Field Of View\"), VisibleIf(nameof(UsePerspective)), ValueCategory(Utils.ValueCategory.Angle)") float GetFieldOfView() const; /// /// Sets camera's field of view (in degrees). /// API_PROPERTY() void SetFieldOfView(float value); /// /// Gets the custom aspect ratio. 0 if not use custom value. /// API_PROPERTY(Attributes="EditorOrder(50), DefaultValue(0.0f), Limit(0, 10, 0.01f), EditorDisplay(\"Camera\")") float GetCustomAspectRatio() const; /// /// Sets the custom aspect ratio. 0 if not use custom value. /// API_PROPERTY() void SetCustomAspectRatio(float value); /// /// Gets camera's near plane distance. /// API_PROPERTY(Attributes="EditorOrder(30), DefaultValue(10.0f), Limit(0, 1000, 0.05f), EditorDisplay(\"Camera\"), ValueCategory(Utils.ValueCategory.Distance)") float GetNearPlane() const; /// /// Sets camera's near plane distance. /// API_PROPERTY() void SetNearPlane(float value); /// /// Gets camera's far plane distance. /// API_PROPERTY(Attributes="EditorOrder(40), DefaultValue(40000.0f), Limit(0, float.MaxValue, 5), EditorDisplay(\"Camera\"), ValueCategory(Utils.ValueCategory.Distance)") float GetFarPlane() const; /// /// Sets camera's far plane distance. /// API_PROPERTY() void SetFarPlane(float value); /// /// Gets the orthographic projection view height (width is based on the aspect ratio). Use `0` for size to be based on the viewport size. /// API_PROPERTY(Attributes="EditorOrder(59), DefaultValue(0.0f), Limit(0.0f), EditorDisplay(\"Camera\"), VisibleIf(nameof(UsePerspective), true)") float GetOrthographicSize() const; /// /// Sets the orthographic projection view height (width is based on the aspect ratio). Use `0` for size to be based on the viewport size. /// API_PROPERTY() void SetOrthographicSize(float value); /// /// Gets the orthographic projection scale. /// API_PROPERTY(Attributes="EditorOrder(60), DefaultValue(1.0f), Limit(0.0001f, 1000, 0.01f), EditorDisplay(\"Camera\"), VisibleIf(nameof(UsePerspective), true)") float GetOrthographicScale() const; /// /// Sets the orthographic projection scale. /// API_PROPERTY() void SetOrthographicScale(float value); /// /// The layers mask used for rendering using this camera. Can be used to include or exclude specific actor layers from the drawing. /// API_FIELD(Attributes="EditorOrder(100), EditorDisplay(\"Camera\")") LayersMask RenderLayersMask; /// /// Frame rendering flags used to switch between graphics features for this camera. /// API_FIELD(Attributes = "EditorOrder(110), EditorDisplay(\"Camera\")") ViewFlags RenderFlags = ViewFlags::DefaultGame; /// /// Describes frame rendering modes for this camera. /// API_FIELD(Attributes = "EditorOrder(120), EditorDisplay(\"Camera\")") ViewMode RenderMode = ViewMode::Default; public: /// /// Projects the point from 3D world-space to game window coordinates (in screen pixels for default viewport calculated from ). /// /// The input world-space location (XYZ in world). /// The output game window coordinates (XY in screen pixels). API_FUNCTION() void ProjectPoint(const Vector3& worldSpaceLocation, API_PARAM(Out) Float2& gameWindowSpaceLocation) const; /// /// Projects the point from 3D world-space to the camera viewport-space (in screen pixels for given viewport). /// /// The input world-space location (XYZ in world). /// The output camera viewport-space location (XY in screen pixels). /// The viewport. API_FUNCTION() void ProjectPoint(const Vector3& worldSpaceLocation, API_PARAM(Out) Float2& cameraViewportSpaceLocation, API_PARAM(Ref) const Viewport& viewport) const; /// /// Converts a game window-space point into a corresponding point in world space. /// /// The input game window coordinates (XY in screen pixels). /// The input camera-relative depth position (eg. clipping plane). /// The output world-space location (XYZ in world). API_FUNCTION() void UnprojectPoint(const Float2& gameWindowSpaceLocation, float depth, API_PARAM(Out) Vector3& worldSpaceLocation) const; /// /// Converts a camera viewport-space point into a corresponding point in world space. /// /// The input camera viewport-space location (XY in screen pixels). /// The input camera-relative depth position (eg. clipping plane). /// The output world-space location (XYZ in world). /// The viewport. API_FUNCTION() void UnprojectPoint(const Float2& cameraViewportSpaceLocation, float depth, API_PARAM(Out) Vector3& worldSpaceLocation, API_PARAM(Ref) const Viewport& viewport) const; /// /// Checks if the 3d point of the world is in the camera's field of view. /// /// World Position (XYZ). /// Returns true if the point is within the field of view. API_FUNCTION() bool IsPointOnView(const Vector3& worldSpaceLocation) const; /// /// Converts the mouse position to 3D ray. /// /// The mouse position. /// Mouse ray API_FUNCTION() Ray ConvertMouseToRay(const Float2& mousePosition) const; /// /// Converts the mouse position to 3D ray. /// /// The mouse position. /// The viewport. /// Mouse ray API_FUNCTION() Ray ConvertMouseToRay(const Float2& mousePosition, API_PARAM(Ref) const Viewport& viewport) const; /// /// Gets the camera viewport. /// API_PROPERTY() Viewport GetViewport() const; /// /// Calculates the view and the projection matrices for the camera. /// /// The result camera view matrix. /// The result camera projection matrix. API_FUNCTION() void GetMatrices(API_PARAM(Out) Matrix& view, API_PARAM(Out) Matrix& projection) const; /// /// Calculates the view and the projection matrices for the camera. Support using custom viewport. /// /// The result camera view matrix. /// The result camera projection matrix. /// The custom output viewport. API_FUNCTION() void GetMatrices(API_PARAM(Out) Matrix& view, API_PARAM(Out) Matrix& projection, API_PARAM(Ref) const Viewport& viewport) const; /// /// Calculates the view and the projection matrices for the camera. Support using custom viewport and view origin. /// /// The result camera view matrix. /// The result camera projection matrix. /// The custom output viewport. /// The rendering view origin (for relative-to-camera rendering). API_FUNCTION() void GetMatrices(API_PARAM(Out) Matrix& view, API_PARAM(Out) Matrix& projection, API_PARAM(Ref) const Viewport& viewport, API_PARAM(Ref) const Vector3& origin) const; #if USE_EDITOR // Intersection check for editor picking the camera API_FUNCTION() bool IntersectsItselfEditor(API_PARAM(Ref) const Ray& ray, API_PARAM(Out) Real& distance); #endif private: #if USE_EDITOR void OnPreviewModelLoaded(); #endif void UpdateCache(); public: // [Actor] #if USE_EDITOR BoundingBox GetEditorBox() const override; bool HasContentLoaded() const override; void Draw(RenderContext& renderContext) override; void OnDebugDrawSelected() override; #endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; protected: // [Actor] void OnEnable() override; void OnDisable() override; void OnTransformChanged() override; #if USE_EDITOR void BeginPlay(SceneBeginData* data) override; #endif };