From 3ab6110be506e834fb6cbb41c94b93623e77765f Mon Sep 17 00:00:00 2001 From: CCP Zoetrope Date: Thu, 1 Oct 2026 18:52:41 +0000 Subject: [PATCH] Improve trigger volume debug rendering: solid fill + state label Wireframe-only outlines are hard to read from inside a volume. Add a translucent fill to all three volume shapes (box, sphere, ellipsoid) and a text label showing the trigger's name, state, and intensity. Both pick up the volume's existing debug color, which turns green once the tracked position enters the trigger. The debug renderer culls back faces, so each shape draws its fill twice, the second time through a mirrored transform that flips the winding to render the inner faces. Shared via helpers in IEveVolume.h so all three shapes behave the same way. --- trinity/Eve/EveTriggerVolume.cpp | 4 ++++ trinity/Eve/Volume/EveBoxVolume.cpp | 8 ++++++-- trinity/Eve/Volume/EveEllipsoidVolume.cpp | 9 ++++++--- trinity/Eve/Volume/EveSphereVolume.cpp | 8 ++++++-- trinity/Eve/Volume/IEveVolume.h | 24 +++++++++++++++++++++++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/trinity/Eve/EveTriggerVolume.cpp b/trinity/Eve/EveTriggerVolume.cpp index a0ef71bc5..03763602b 100644 --- a/trinity/Eve/EveTriggerVolume.cpp +++ b/trinity/Eve/EveTriggerVolume.cpp @@ -242,6 +242,10 @@ void EveTriggerVolume::RenderDebugInfo( ITr2DebugRenderer2& renderer ) { volume->RenderDebugInfo( renderer, m_worldTransform, color ); } + + // the volume edges are hard to read from inside, so label the volume with the trigger state + const Vector3 center = Transform( m_boundingSphere.center, m_worldTransform ).GetXYZ(); + renderer.DrawText( TRI_DBG_FONT_MEDIUM, center, color, "%s: %s (%.2f)", m_name.c_str(), m_isInside ? "INSIDE" : "outside", m_currentIntensity ); } if( renderer.HasOption( GetRawRoot(), "Trigger Exclusion Volumes" ) ) diff --git a/trinity/Eve/Volume/EveBoxVolume.cpp b/trinity/Eve/Volume/EveBoxVolume.cpp index 1bdf2a8ac..ad12ba225 100644 --- a/trinity/Eve/Volume/EveBoxVolume.cpp +++ b/trinity/Eve/Volume/EveBoxVolume.cpp @@ -40,8 +40,12 @@ bool EveBoxVolume::Initialize() void EveBoxVolume::RenderDebugInfo( ITr2DebugRenderer2& renderer, const Matrix& parentTransform, const Color& baseColor ) { - renderer.DrawBox( this, m_boxTransform * parentTransform, MIN_AABB, MAX_AABB, Tr2DebugRenderer::Wireframe, baseColor * 0.5f ); - renderer.DrawBox( this, m_innerBoxTransform * parentTransform, MIN_AABB, MAX_AABB, Tr2DebugRenderer::Wireframe, baseColor * 0.6f ); + const Matrix boxTransform = m_boxTransform * parentTransform; + const Tr2DebugColor fill = EveVolumeFillColor( baseColor ); + renderer.DrawBox( this, boxTransform, MIN_AABB, MAX_AABB, Tr2DebugRenderer::Solid, fill ); + renderer.DrawBox( this, EveVolumeInsideOut( boxTransform ), MIN_AABB, MAX_AABB, Tr2DebugRenderer::Solid, fill ); + renderer.DrawBox( this, boxTransform, MIN_AABB, MAX_AABB, Tr2DebugRenderer::Wireframe, EveVolumeDebugColor( baseColor * 0.5f ) ); + renderer.DrawBox( this, m_innerBoxTransform * parentTransform, MIN_AABB, MAX_AABB, Tr2DebugRenderer::Wireframe, EveVolumeDebugColor( baseColor * 0.6f ) ); if( m_debugShowIntersection ) { diff --git a/trinity/Eve/Volume/EveEllipsoidVolume.cpp b/trinity/Eve/Volume/EveEllipsoidVolume.cpp index b0d26afd9..0a0552877 100644 --- a/trinity/Eve/Volume/EveEllipsoidVolume.cpp +++ b/trinity/Eve/Volume/EveEllipsoidVolume.cpp @@ -56,11 +56,14 @@ void EveEllipsoidVolume::Setup() void EveEllipsoidVolume::RenderDebugInfo( ITr2DebugRenderer2& renderer, const Matrix& parentTransform, const Color& baseColor ) { - Matrix outerTransform = TransformationMatrix( m_shape, m_rotation, m_position ) * parentTransform; - renderer.DrawSphere( Tr2DebugObjectReference( this, 200 ), outerTransform, 20, Tr2DebugRenderer::Wireframe, baseColor * 0.5f ); + const Matrix outerTransform = TransformationMatrix( m_shape, m_rotation, m_position ) * parentTransform; + const Tr2DebugColor fill = EveVolumeFillColor( baseColor ); + renderer.DrawSphere( Tr2DebugObjectReference( this, 200 ), outerTransform, 20, Tr2DebugRenderer::Solid, fill ); + renderer.DrawSphere( Tr2DebugObjectReference( this, 200 ), EveVolumeInsideOut( outerTransform ), 20, Tr2DebugRenderer::Solid, fill ); + renderer.DrawSphere( Tr2DebugObjectReference( this, 200 ), outerTransform, 20, Tr2DebugRenderer::Wireframe, EveVolumeDebugColor( baseColor * 0.5f ) ); Matrix innerTransform = TransformationMatrix( m_innerShape, m_rotation, m_position ) * parentTransform; - renderer.DrawSphere( Tr2DebugObjectReference( this, 200 ), innerTransform, 20, Tr2DebugRenderer::Wireframe, baseColor * 0.6f ); + renderer.DrawSphere( Tr2DebugObjectReference( this, 200 ), innerTransform, 20, Tr2DebugRenderer::Wireframe, EveVolumeDebugColor( baseColor * 0.6f ) ); if( m_debugShowIntersection ) { diff --git a/trinity/Eve/Volume/EveSphereVolume.cpp b/trinity/Eve/Volume/EveSphereVolume.cpp index e0f9c8e9d..2fc4bc4e0 100644 --- a/trinity/Eve/Volume/EveSphereVolume.cpp +++ b/trinity/Eve/Volume/EveSphereVolume.cpp @@ -19,8 +19,12 @@ EveSphereVolume::~EveSphereVolume() void EveSphereVolume::RenderDebugInfo( ITr2DebugRenderer2& renderer, const Matrix& parentTransform, const Color& baseColor ) { - renderer.DrawSphere( this, TranslationMatrix( m_outerSphere.center ) * parentTransform, m_outerSphere.radius, 20, Tr2DebugRenderer::Wireframe, baseColor * 0.5f ); - renderer.DrawSphere( this, TranslationMatrix( m_outerSphere.center + m_innerSphere.center ) * parentTransform, m_innerSphere.radius, 20, Tr2DebugRenderer::Wireframe, baseColor * 0.6f ); + const Matrix outerTransform = TranslationMatrix( m_outerSphere.center ) * parentTransform; + const Tr2DebugColor fill = EveVolumeFillColor( baseColor ); + renderer.DrawSphere( this, outerTransform, m_outerSphere.radius, 20, Tr2DebugRenderer::Solid, fill ); + renderer.DrawSphere( this, EveVolumeInsideOut( outerTransform ), m_outerSphere.radius, 20, Tr2DebugRenderer::Solid, fill ); + renderer.DrawSphere( this, outerTransform, m_outerSphere.radius, 20, Tr2DebugRenderer::Wireframe, EveVolumeDebugColor( baseColor * 0.5f ) ); + renderer.DrawSphere( this, TranslationMatrix( m_outerSphere.center + m_innerSphere.center ) * parentTransform, m_innerSphere.radius, 20, Tr2DebugRenderer::Wireframe, EveVolumeDebugColor( baseColor * 0.6f ) ); } const CcpMath::Sphere EveSphereVolume::GetBoundingSphere() const diff --git a/trinity/Eve/Volume/IEveVolume.h b/trinity/Eve/Volume/IEveVolume.h index d46188bb7..cbdac0eea 100644 --- a/trinity/Eve/Volume/IEveVolume.h +++ b/trinity/Eve/Volume/IEveVolume.h @@ -7,6 +7,30 @@ BLUE_DECLARE_INTERFACE( IEveVolume ); +// Debug colors shared by the volume shapes. The outline stays faintly visible where the volume is hidden +// behind other geometry, and the fill is a faint tint that also carries through to whatever is inside it. +inline Tr2DebugColor EveVolumeDebugColor( const Color& color ) +{ + Color occluded = color; + occluded.a *= 0.25f; + return Tr2DebugColor( color, occluded ); +} + +inline Tr2DebugColor EveVolumeFillColor( const Color& color ) +{ + Color fill = color; + fill.a *= 0.15f; + return EveVolumeDebugColor( fill ); +} + +// The debug renderer culls back faces, so a solid shape is invisible from inside. Drawing it a second time +// with this transform mirrors it, which reverses the winding so the inner faces render as well: together the +// two draws are a two-sided solid. +inline Matrix EveVolumeInsideOut( const Matrix& transform ) +{ + return ScalingMatrix( -1.0f, 1.0f, 1.0f ) * transform; +} + BLUE_INTERFACE( IEveVolume ) : public IRoot {