// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Light.h" #include "Engine/Content/Assets/IESProfile.h" #include "Engine/Content/AssetReference.h" /// /// Spot light emits light from the point in a given direction. /// API_CLASS(Attributes="ActorContextMenu(\"New/Lights/Spot Light\"), ActorToolbox(\"Lights\")") class FLAXENGINE_API SpotLight : public LightWithShadow { DECLARE_SCENE_OBJECT(SpotLight); private: Vector3 _direction; float _radius; float _outerConeAngle; float _innerConeAngle; float _cosOuterCone; float _cosInnerCone; float _invCosConeDifference; public: /// /// Light source bulb radius /// API_FIELD(Attributes="EditorOrder(2), DefaultValue(0.0f), EditorDisplay(\"Light\"), Limit(0, 1000, 0.01f)") float SourceRadius = 0.0f; /// /// Controls the radial falloff of light when UseInverseSquaredFalloff is disabled. /// API_FIELD(Attributes="EditorOrder(13), DefaultValue(8.0f), EditorDisplay(\"Light\"), Limit(2, 16, 0.01f), VisibleIf(nameof(UseInverseSquaredFalloff), true)") float FallOffExponent = 8.0f; /// /// Whether to use physically based inverse squared distance falloff, where Radius is only clamping the light's contribution. /// API_FIELD(Attributes="EditorOrder(14), DefaultValue(false), EditorDisplay(\"Light\")") bool UseInverseSquaredFalloff = false; /// /// IES texture (light profiles from real world measured data) /// API_FIELD(Attributes="EditorOrder(211), DefaultValue(null), EditorDisplay(\"IES Profile\", \"IES Texture\")") AssetReference IESTexture; /// /// Enable/disable using light brightness from IES profile /// API_FIELD(Attributes="EditorOrder(212), DefaultValue(false), EditorDisplay(\"IES Profile\", \"Use IES Brightness\")") bool UseIESBrightness = false; /// /// Global scale for IES brightness contribution /// API_FIELD(Attributes="EditorOrder(213), DefaultValue(1.0f), Limit(0, 10000, 0.01f), EditorDisplay(\"IES Profile\", \"Brightness Scale\")") float IESBrightnessScale = 1.0f; public: /// /// Computes light brightness value /// /// Brightness float ComputeBrightness() const; /// /// Gets scaled light radius /// float GetScaledRadius() const; /// /// Gets light radius /// API_PROPERTY(Attributes="EditorOrder(1), DefaultValue(1000.0f), EditorDisplay(\"Light\"), Tooltip(\"Light radius\"), Limit(0, 10000, 0.1f)") FORCE_INLINE float GetRadius() const { return _radius; } /// /// Sets light radius /// /// New radius API_PROPERTY() void SetRadius(float value); /// /// Gets the spot light's outer cone angle (in degrees) /// /// Outer angle (in degrees) API_PROPERTY(Attributes="EditorOrder(22), DefaultValue(43.0f), EditorDisplay(\"Light\"), Limit(1, 89, 0.1f)") FORCE_INLINE float GetOuterConeAngle() const { return _outerConeAngle; } /// /// Sets the spot light's outer cone angle (in degrees) /// /// Value to assign API_PROPERTY() void SetOuterConeAngle(float value); /// /// Sets the spot light's inner cone angle (in degrees) /// /// Inner angle (in degrees) API_PROPERTY(Attributes="EditorOrder(21), DefaultValue(10.0f), EditorDisplay(\"Light\"), Limit(1, 89, 0.1f)") FORCE_INLINE float GetInnerConeAngle() const { return _innerConeAngle; } /// /// Sets the spot light's inner cone angle (in degrees) /// /// Value to assign API_PROPERTY() void SetInnerConeAngle(float value); private: void UpdateBounds(); public: // [LightWithShadow] void Draw(RenderContext& renderContext) override; #if USE_EDITOR void OnDebugDraw() override; void OnDebugDrawSelected() override; void DrawLightsDebug(RenderView& view) override; #endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override; protected: // [LightWithShadow] void OnTransformChanged() override; };