From a0bb3f29957374f7367d4e8deb76c699eaecb33e Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Fri, 7 Jul 2023 17:32:46 -0500 Subject: [PATCH] Add light debug view flag to draw light shapes --- Source/Editor/Viewport/EditorViewport.cs | 1 + Source/Engine/Graphics/Enums.h | 5 +++ Source/Engine/Level/Actors/Light.cpp | 8 +++++ Source/Engine/Level/Actors/Light.h | 2 ++ Source/Engine/Level/Actors/PointLight.cpp | 10 ++++++ Source/Engine/Level/Actors/PointLight.h | 1 + Source/Engine/Level/Actors/SpotLight.cpp | 33 ++++++++++++++++++++ Source/Engine/Level/Actors/SpotLight.h | 1 + Source/Engine/Level/Scene/SceneRendering.cpp | 10 ++++++ Source/Engine/Level/Scene/SceneRendering.h | 18 +++++++++++ 10 files changed, 89 insertions(+) diff --git a/Source/Editor/Viewport/EditorViewport.cs b/Source/Editor/Viewport/EditorViewport.cs index b4fb8f8f1..3281d130a 100644 --- a/Source/Editor/Viewport/EditorViewport.cs +++ b/Source/Editor/Viewport/EditorViewport.cs @@ -1538,6 +1538,7 @@ namespace FlaxEditor.Viewport new ViewFlagOptions(ViewFlags.MotionBlur, "Motion Blur"), new ViewFlagOptions(ViewFlags.ContactShadows, "Contact Shadows"), new ViewFlagOptions(ViewFlags.PhysicsDebug, "Physics Debug"), + new ViewFlagOptions(ViewFlags.LightsDebug, "Lights Debug"), new ViewFlagOptions(ViewFlags.DebugDraw, "Debug Draw"), }; diff --git a/Source/Engine/Graphics/Enums.h b/Source/Engine/Graphics/Enums.h index 3ef462925..4d1422f96 100644 --- a/Source/Engine/Graphics/Enums.h +++ b/Source/Engine/Graphics/Enums.h @@ -1031,6 +1031,11 @@ API_ENUM(Attributes="Flags") enum class ViewFlags : uint64 /// Sky = 1 << 26, + /// + /// Shows/hides light debug shapes. + /// + LightsDebug = 1 << 27, + /// /// Default flags for Game. /// diff --git a/Source/Engine/Level/Actors/Light.cpp b/Source/Engine/Level/Actors/Light.cpp index 594ebdc2b..5e86f6e7e 100644 --- a/Source/Engine/Level/Actors/Light.cpp +++ b/Source/Engine/Level/Actors/Light.cpp @@ -26,6 +26,7 @@ void Light::OnEnable() GetSceneRendering()->AddActor(this, _sceneRenderingKey); #if USE_EDITOR GetSceneRendering()->AddViewportIcon(this); + GetSceneRendering()->AddLightsDebug(this); #endif // Base @@ -36,6 +37,7 @@ void Light::OnDisable() { #if USE_EDITOR GetSceneRendering()->RemoveViewportIcon(this); + GetSceneRendering()->RemoveLightsDebug(this); #endif GetSceneRendering()->RemoveActor(this, _sceneRenderingKey); @@ -43,6 +45,12 @@ void Light::OnDisable() Actor::OnDisable(); } +#if USE_EDITOR +void Light::DrawLightsDebug(RenderView& view) +{ +} +#endif + void Light::Serialize(SerializeStream& stream, const void* otherObj) { // Base diff --git a/Source/Engine/Level/Actors/Light.h b/Source/Engine/Level/Actors/Light.h index dab613c71..86ca59ef5 100644 --- a/Source/Engine/Level/Actors/Light.h +++ b/Source/Engine/Level/Actors/Light.h @@ -66,6 +66,8 @@ public: const Vector3 size(50); return BoundingBox(_transform.Translation - size, _transform.Translation + size); } + + virtual void DrawLightsDebug(RenderView& view); #endif void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; diff --git a/Source/Engine/Level/Actors/PointLight.cpp b/Source/Engine/Level/Actors/PointLight.cpp index 49c0f4c88..0e7ea79ec 100644 --- a/Source/Engine/Level/Actors/PointLight.cpp +++ b/Source/Engine/Level/Actors/PointLight.cpp @@ -143,6 +143,16 @@ void PointLight::OnDebugDrawSelected() LightWithShadow::OnDebugDrawSelected(); } +void PointLight::DrawLightsDebug(RenderView& view) +{ + const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius); + if (!view.CullingFrustum.Intersects(sphere)) + return; + + // Draw influence range + DEBUG_DRAW_WIRE_SPHERE(_sphere, Color::Yellow, 0, true); +} + #endif void PointLight::OnLayerChanged() diff --git a/Source/Engine/Level/Actors/PointLight.h b/Source/Engine/Level/Actors/PointLight.h index d3e170a03..50df19232 100644 --- a/Source/Engine/Level/Actors/PointLight.h +++ b/Source/Engine/Level/Actors/PointLight.h @@ -95,6 +95,7 @@ public: #if USE_EDITOR void OnDebugDraw() override; void OnDebugDrawSelected() override; + void DrawLightsDebug(RenderView& view) override; #endif void OnLayerChanged() override; void Serialize(SerializeStream& stream, const void* otherObj) override; diff --git a/Source/Engine/Level/Actors/SpotLight.cpp b/Source/Engine/Level/Actors/SpotLight.cpp index 26f1700d5..557d69cd9 100644 --- a/Source/Engine/Level/Actors/SpotLight.cpp +++ b/Source/Engine/Level/Actors/SpotLight.cpp @@ -203,6 +203,11 @@ void SpotLight::OnDebugDrawSelected() DEBUG_DRAW_LINE(position, position + forward * radius + right * discRadius, color, 0, true); DEBUG_DRAW_LINE(position, position + forward * radius - right * discRadius, color, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius + up * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius - up * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius + right * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius - right * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_CIRCLE(position + forward * radius, forward, discRadius, color, 0, true); DEBUG_DRAW_CIRCLE(position + forward * radius, forward, falloffDiscRadius, color * 0.6f, 0, true); @@ -210,6 +215,34 @@ void SpotLight::OnDebugDrawSelected() LightWithShadow::OnDebugDrawSelected(); } +void SpotLight::DrawLightsDebug(RenderView& view) +{ + const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius); + if (!view.CullingFrustum.Intersects(sphere)) + return; + + const auto color = Color::Yellow; + Vector3 right = _transform.GetRight(); + Vector3 up = _transform.GetUp(); + Vector3 forward = GetDirection(); + float radius = GetScaledRadius(); + float discRadius = radius * Math::Tan(_outerConeAngle * DegreesToRadians); + float falloffDiscRadius = radius * Math::Tan(_innerConeAngle * DegreesToRadians); + Vector3 position = GetPosition(); + + DEBUG_DRAW_LINE(position, position + forward * radius + up * discRadius, color, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius - up * discRadius, color, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius + right * discRadius, color, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius - right * discRadius, color, 0, true); + + DEBUG_DRAW_LINE(position, position + forward * radius + up * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius - up * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius + right * falloffDiscRadius, color * 0.6f, 0, true); + DEBUG_DRAW_LINE(position, position + forward * radius - right * falloffDiscRadius, color * 0.6f, 0, true); + + DEBUG_DRAW_CIRCLE(position + forward * radius, forward, discRadius, color, 0, true); + DEBUG_DRAW_CIRCLE(position + forward * radius, forward, falloffDiscRadius, color * 0.6f, 0, true); +} #endif void SpotLight::Serialize(SerializeStream& stream, const void* otherObj) diff --git a/Source/Engine/Level/Actors/SpotLight.h b/Source/Engine/Level/Actors/SpotLight.h index 6bb0daf8d..e6179a522 100644 --- a/Source/Engine/Level/Actors/SpotLight.h +++ b/Source/Engine/Level/Actors/SpotLight.h @@ -127,6 +127,7 @@ public: #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; diff --git a/Source/Engine/Level/Scene/SceneRendering.cpp b/Source/Engine/Level/Scene/SceneRendering.cpp index 48420ed49..65773b6c0 100644 --- a/Source/Engine/Level/Scene/SceneRendering.cpp +++ b/Source/Engine/Level/Scene/SceneRendering.cpp @@ -96,6 +96,16 @@ void SceneRendering::Draw(RenderContextBatch& renderContextBatch, DrawCategory c physicsDebugData[i](view); } } + + // Draw light shapes + if (EnumHasAnyFlags(view.Flags, ViewFlags::LightsDebug)) + { + const LightsDebugCallback* lightsDebugData = LightsDebug.Get(); + for (int32 i = 0; i < LightsDebug.Count(); i++) + { + lightsDebugData[i](view); + } + } } #endif } diff --git a/Source/Engine/Level/Scene/SceneRendering.h b/Source/Engine/Level/Scene/SceneRendering.h index ef9fc6c3c..0afe4ea3c 100644 --- a/Source/Engine/Level/Scene/SceneRendering.h +++ b/Source/Engine/Level/Scene/SceneRendering.h @@ -65,6 +65,7 @@ class FLAXENGINE_API SceneRendering { #if USE_EDITOR typedef Function PhysicsDebugCallback; + typedef Function LightsDebugCallback; friend class ViewportIconsRendererService; #endif public: @@ -95,6 +96,7 @@ public: private: #if USE_EDITOR Array PhysicsDebug; + Array LightsDebug; Array ViewportIcons; #endif @@ -153,6 +155,22 @@ public: PhysicsDebug.Remove(f); } + template + FORCE_INLINE void AddLightsDebug(T* obj) + { + LightsDebugCallback f; + f.Bind(obj); + LightsDebug.Add(f); + } + + template + void RemoveLightsDebug(T* obj) + { + LightsDebugCallback f; + f.Bind(obj); + LightsDebug.Remove(f); + } + FORCE_INLINE void AddViewportIcon(Actor* obj) { ViewportIcons.Add(obj);