From e0aeae05beab89353fb0a43fcb85febd765350a6 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 28 Sep 2021 11:08:19 +0200 Subject: [PATCH] Add `DebugDraw.DrawCone` and `DebugDraw.DrawWireCone` --- Source/Engine/Debug/DebugDraw.cpp | 67 +++++++++++++++++++++++++++++++ Source/Engine/Debug/DebugDraw.h | 30 ++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/Source/Engine/Debug/DebugDraw.cpp b/Source/Engine/Debug/DebugDraw.cpp index 401ad0959..9632a7618 100644 --- a/Source/Engine/Debug/DebugDraw.cpp +++ b/Source/Engine/Debug/DebugDraw.cpp @@ -45,6 +45,8 @@ #define DEBUG_DRAW_CYLINDER_RESOLUTION 12 #define DEBUG_DRAW_CYLINDER_VERTICES (DEBUG_DRAW_CYLINDER_RESOLUTION * 4) // +#define DEBUG_DRAW_CONE_RESOLUTION 32 +// #define DEBUG_DRAW_TRIANGLE_SPHERE_RESOLUTION 12 struct DebugSphereCache @@ -1489,6 +1491,51 @@ namespace } } } + + void DrawCone(Array* list, const Vector3& position, const Quaternion& orientation, float radius, float angleXY, float angleXZ, const Color& color, float duration) + { + const float tolerance = 0.001f; + const float angle1 = Math::Clamp(angleXY, tolerance, PI - tolerance); + const float angle2 = Math::Clamp(angleXZ, tolerance, PI - tolerance); + + const float sinX1 = Math::Sin(0.5f * angle1); + const float sinY2 = Math::Sin(0.5f * angle2); + const float sinSqX1 = sinX1 * sinX1; + const float sinSqY2 = sinY2 * sinY2; + + DebugTriangle t; + t.Color = Color32(color); + t.TimeLeft = duration; + const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(position); + t.V0 = world.GetTranslation(); + + Vector3 vertices[DEBUG_DRAW_CONE_RESOLUTION]; + for (uint32 i = 0; i < DEBUG_DRAW_CONE_RESOLUTION; i++) + { + const float alpha = (float)i / (float)DEBUG_DRAW_CONE_RESOLUTION; + const float azimuth = alpha * TWO_PI; + + const float phi = Math::Atan2(Math::Sin(azimuth) * sinY2, Math::Cos(azimuth) * sinX1); + const float sinPhi = Math::Sin(phi); + const float cosPhi = Math::Cos(phi); + const float sinSqPhi = sinPhi * sinPhi; + const float cosSqPhi = cosPhi * cosPhi; + + const float rSq = sinSqX1 * sinSqY2 / (sinSqX1 * sinSqPhi + sinSqY2 * cosSqPhi); + const float r = Math::Sqrt(rSq); + const float s = Math::Sqrt(1 - rSq); + + Vector3 vertex = Vector3(2 * s * (r * cosPhi), 2 * s * (r * sinPhi), 1 - 2 * rSq) * radius; + Vector3::Transform(vertex, world, vertices[i]); + } + + for (uint32 i = 0; i < DEBUG_DRAW_CONE_RESOLUTION; i++) + { + t.V1 = vertices[i]; + t.V2 = vertices[(i + 1) % DEBUG_DRAW_CONE_RESOLUTION]; + list->Add(t); + } + } } void DebugDraw::DrawCylinder(const Vector3& position, const Quaternion& orientation, float radius, float height, const Color& color, float duration, bool depthTest) @@ -1511,6 +1558,26 @@ void DebugDraw::DrawWireCylinder(const Vector3& position, const Quaternion& orie ::DrawCylinder(list, position, orientation, radius, height, color, duration); } +void DebugDraw::DrawCone(const Vector3& position, const Quaternion& orientation, float radius, float angleXY, float angleXZ, const Color& color, float duration, bool depthTest) +{ + Array* list; + if (depthTest) + list = duration > 0 ? &Context->DebugDrawDepthTest.DefaultTriangles : &Context->DebugDrawDepthTest.OneFrameTriangles; + else + list = duration > 0 ? &Context->DebugDrawDefault.DefaultTriangles : &Context->DebugDrawDefault.OneFrameTriangles; + ::DrawCone(list, position, orientation, radius, angleXY, angleXZ, color, duration); +} + +void DebugDraw::DrawWireCone(const Vector3& position, const Quaternion& orientation, float radius, float angleXY, float angleXZ, const Color& color, float duration, bool depthTest) +{ + Array* list; + if (depthTest) + list = duration > 0 ? &Context->DebugDrawDepthTest.DefaultWireTriangles : &Context->DebugDrawDepthTest.OneFrameWireTriangles; + else + list = duration > 0 ? &Context->DebugDrawDefault.DefaultWireTriangles : &Context->DebugDrawDefault.OneFrameWireTriangles; + ::DrawCone(list, position, orientation, radius, angleXY, angleXZ, color, duration); +} + void DebugDraw::DrawWireArrow(const Vector3& position, const Quaternion& orientation, float scale, const Color& color, float duration, bool depthTest) { Vector3 direction, up, right; diff --git a/Source/Engine/Debug/DebugDraw.h b/Source/Engine/Debug/DebugDraw.h index b8a073ec6..281dddd4c 100644 --- a/Source/Engine/Debug/DebugDraw.h +++ b/Source/Engine/Debug/DebugDraw.h @@ -356,6 +356,32 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(DebugDraw); /// If set to true depth test will be performed, otherwise depth will be ignored. API_FUNCTION() static void DrawWireCylinder(const Vector3& position, const Quaternion& orientation, float radius, float height, const Color& color, float duration = 0.0f, bool depthTest = true); + /// + /// Draws the cone. + /// + /// The center position. + /// The orientation. + /// The radius. + /// The angle (in radians) of the cone over the XY axis (cone forward is over X). + /// The angle (in radians) of the cone over the XZ axis (cone forward is over X). + /// The color. + /// The duration (in seconds). Use 0 to draw it only once. + /// If set to true depth test will be performed, otherwise depth will be ignored. + API_FUNCTION() static void DrawCone(const Vector3& position, const Quaternion& orientation, float radius, float angleXY, float angleXZ, const Color& color, float duration = 0.0f, bool depthTest = true); + + /// + /// Draws the wireframe cone. + /// + /// The center position. + /// The orientation. + /// The radius. + /// The angle (in radians) of the cone over the XY axis (cone forward is over X). + /// The angle (in radians) of the cone over the XZ axis (cone forward is over X). + /// The color. + /// The duration (in seconds). Use 0 to draw it only once. + /// If set to true depth test will be performed, otherwise depth will be ignored. + API_FUNCTION() static void DrawWireCone(const Vector3& position, const Quaternion& orientation, float radius, float angleXY, float angleXZ, const Color& color, float duration = 0.0f, bool depthTest = true); + /// /// Draws the wireframe arrow. /// @@ -427,6 +453,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(DebugDraw); #define DEBUG_DRAW_TUBE(position, orientation, radius, length, color, duration, depthTest) DebugDraw::DrawTube(position, orientation, radius, length, color, duration, depthTest) #define DEBUG_DRAW_BOX(box, color, duration, depthTest) DebugDraw::DrawBox(box, color, duration, depthTest) #define DEBUG_DRAW_CYLINDER(position, orientation, radius, height, color, duration, depthTest) DebugDraw::DrawCylinder(position, orientation, radius, height, color, duration, depthTest) +#define DEBUG_DRAW_CONE(position, orientation, radius, angleXY, angleXZ, color, duration, depthTest) DebugDraw::DrawCone(position, orientation, radius, angleXY, angleXZ, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TRIANGLE(v0, v1, v2, color, duration, depthTest) DebugDraw::DrawWireTriangle(v0, v1, v2, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TRIANGLES(vertices, color, duration, depthTest) DebugDraw::DrawWireTriangles(vertices, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TRIANGLES_EX(vertices, indices, color, duration, depthTest) DebugDraw::DrawWireTriangles(vertices, indices, color, duration, depthTest) @@ -435,6 +462,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(DebugDraw); #define DEBUG_DRAW_WIRE_SPHERE(sphere, color, duration, depthTest) DebugDraw::DrawWireSphere(sphere, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TUBE(position, orientation, radius, length, color, duration, depthTest) DebugDraw::DrawWireTube(position, orientation, radius, length, color, duration, depthTest) #define DEBUG_DRAW_WIRE_CYLINDER(position, orientation, radius, height, color, duration, depthTest) DebugDraw::DrawWireCylinder(position, orientation, radius, height, color, duration, depthTest) +#define DEBUG_DRAW_WIRE_CONE(position, orientation, radius, angleXY, angleXZ, color, duration, depthTest) DebugDraw::DrawWireCone(position, orientation, radius, angleXY, angleXZ, color, duration, depthTest) #define DEBUG_DRAW_WIRE_ARROW(position, orientation, scale, color, duration, depthTest) DebugDraw::DrawWireArrow(position, orientation, scale, color, duration, depthTest) #define DEBUG_DRAW_TEXT(text, position, color, size, duration) DebugDraw::DrawText(text, position, color, size, duration) @@ -451,6 +479,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(DebugDraw); #define DEBUG_DRAW_TUBE(position, orientation, radius, length, color, duration, depthTest) #define DEBUG_DRAW_BOX(box, color, duration, depthTest) #define DEBUG_DRAW_CYLINDER(position, orientation, radius, height, color, duration, depthTest) +#define DEBUG_DRAW_CONE(position, orientation, radius, angleXY, angleXZ, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TRIANGLE(v0, v1, v2, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TRIANGLES(vertices, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TRIANGLES_EX(vertices, indices, color, duration, depthTest) @@ -459,6 +488,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(DebugDraw); #define DEBUG_DRAW_WIRE_SPHERE(sphere, color, duration, depthTest) #define DEBUG_DRAW_WIRE_TUBE(position, orientation, radius, length, color, duration, depthTest) #define DEBUG_DRAW_WIRE_CYLINDER(position, orientation, radius, height, color, duration, depthTest) +#define DEBUG_DRAW_WIRE_CONE(position, orientation, radius, angleXY, angleXZ, color, duration, depthTest) #define DEBUG_DRAW_WIRE_ARROW(position, orientation, scale, color, duration, depthTest) #define DEBUG_DRAW_TEXT(text, position, color, size, duration)