// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "../Actor.h" #include "Engine/Content/Assets/CubeTexture.h" #include "Engine/Content/AssetReference.h" #include "Engine/Graphics/Enums.h" /// /// Environment Probe can capture space around the objects to provide reflections. /// API_CLASS(Attributes="ActorContextMenu(\"New/Visuals/Environment Probe\"), ActorToolbox(\"Visuals\")") class FLAXENGINE_API EnvironmentProbe : public Actor { DECLARE_SCENE_OBJECT(EnvironmentProbe); public: /// /// The environment probe update mode. /// API_ENUM() enum class ProbeUpdateMode { // Probe can be updated manually (eg. in Editor or from script). Manual = 0, // Probe will be automatically updated when is moved. WhenMoved = 1, // Probe will be automatically updated in real-time (only if in view and frequency depending on distance to the camera). Realtime = 2, }; private: float _radius; bool _isUsingCustomProbe; int32 _sceneRenderingKey = -1; AssetReference _probe; GPUTexture* _probeTexture = nullptr; public: ~EnvironmentProbe(); public: /// /// The reflections texture resolution. /// API_FIELD(Attributes = "EditorOrder(0), EditorDisplay(\"Probe\")") ProbeCubemapResolution CubemapResolution = ProbeCubemapResolution::UseGraphicsSettings; /// /// The reflections brightness. /// API_FIELD(Attributes="EditorOrder(10), Limit(0, 1000, 0.01f), EditorDisplay(\"Probe\")") float Brightness = 1.0f; /// /// The probe update mode. /// API_FIELD(Attributes="EditorOrder(30), EditorDisplay(\"Probe\")") ProbeUpdateMode UpdateMode = ProbeUpdateMode::Manual; /// /// The probe capture camera near plane distance. /// API_FIELD(Attributes="EditorOrder(30), Limit(0, float.MaxValue, 0.01f), EditorDisplay(\"Probe\")") float CaptureNearPlane = 10.0f; public: /// /// Gets the probe radius. /// API_PROPERTY(Attributes="EditorOrder(20), DefaultValue(3000.0f), Limit(0), EditorDisplay(\"Probe\")") float GetRadius() const; /// /// Sets the probe radius. /// API_PROPERTY() void SetRadius(float value); /// /// Gets probe scaled radius. /// API_PROPERTY() float GetScaledRadius() const; /// /// Gets the probe texture used during rendering (baked or custom one). /// API_PROPERTY() GPUTexture* GetProbe() const; /// /// True if probe is using custom cube texture (not baked). /// API_PROPERTY() bool IsUsingCustomProbe() const; /// /// Setup probe data structure /// /// Rendering context /// Packed probe data to set void SetupProbeData(const RenderContext& renderContext, struct ProbeData* data) const; /// /// Gets the custom probe (null if using baked one or none). /// API_PROPERTY(Attributes="EditorOrder(40), DefaultValue(null), EditorDisplay(\"Probe\")") CubeTexture* GetCustomProbe() const; /// /// Sets the custom probe (null to disable that feature). /// /// Probe cube texture asset to use API_PROPERTY() void SetCustomProbe(CubeTexture* probe); public: /// /// Bakes that probe. It won't be performed now but on async graphics rendering task. /// /// The timeout in seconds left to bake it (aka startup time). API_FUNCTION() void Bake(float timeout = 0); /// /// Action fired when probe has been baked. Copies data to the texture memory (GPU-only for real-time probes). /// /// The GPU context to use for probe data copying. /// The new probe data (GPU texture). void SetProbeData(GPUContext* context, GPUTexture* data); /// /// Action fired when probe has been baked. Imports data to the texture asset (virtual if running in game). /// /// The new probe data. void SetProbeData(TextureData& data); private: void UpdateBounds(); public: // [Actor] #if USE_EDITOR BoundingBox GetEditorBox() const override { const Vector3 size(50); return BoundingBox(_transform.Translation - size, _transform.Translation + size); } #endif void Draw(RenderContext& renderContext) override; #if USE_EDITOR void OnDebugDrawSelected() override; #endif void OnLayerChanged() override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; bool HasContentLoaded() const override; bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override; protected: // [Actor] void OnEnable() override; void OnDisable() override; void OnTransformChanged() override; };