diff --git a/examples/testbed/framework/draw.cpp b/examples/testbed/framework/draw.cpp new file mode 100644 index 0000000..de2d05f --- /dev/null +++ b/examples/testbed/framework/draw.cpp @@ -0,0 +1,522 @@ +/* +* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#include + +#if defined (U_OPENGL_2) +#include +#elif defined (U_OPENGL_4) +#include +#else +#endif + +#include + +Camera* g_camera = nullptr; +Draw* g_draw = nullptr; +u32 g_drawFlags = 0; + +Draw::Draw() +{ + m_points = new DrawPoints(); + m_lines = new DrawLines(); + m_triangles = new DrawTriangles(); + m_wire = new DrawWire(); + m_solid = new DrawSolid(); +} + +Draw::~Draw() +{ + delete m_points; + delete m_lines; + delete m_triangles; + delete m_wire; + delete m_solid; +} + +void Draw::DrawPoint(const b3Vec3& p, float32 size, const b3Color& color) +{ + m_points->Vertex(p, size, color); +} + +void Draw::DrawSegment(const b3Vec3& p1, const b3Vec3& p2, const b3Color& color) +{ + m_lines->Vertex(p1, color); + m_lines->Vertex(p2, color); +} + +void Draw::DrawTriangle(const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color) +{ + DrawSegment(p1, p2, color); + DrawSegment(p2, p3, color); + DrawSegment(p3, p1, color); +} + +void Draw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color) +{ + m_triangles->Vertex(p1, color, normal); + m_triangles->Vertex(p2, color, normal); + m_triangles->Vertex(p3, color, normal); + + b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); + DrawTriangle(p1, p2, p3, edgeColor); +} + +void Draw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Color& color1, const b3Vec3& p2, const b3Color& color2, const b3Vec3& p3, const b3Color& color3) +{ + m_triangles->Vertex(p1, color1, normal); + m_triangles->Vertex(p2, color2, normal); + m_triangles->Vertex(p3, color3, normal); + + b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); + DrawTriangle(p1, p2, p3, edgeColor); +} + +void Draw::DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) +{ + b3Vec3 p1 = vertices[count - 1]; + for (u32 i = 0; i < count; ++i) + { + b3Vec3 p2 = vertices[i]; + + m_lines->Vertex(p1, color); + m_lines->Vertex(p2, color); + + p1 = p2; + } +} + +void Draw::DrawSolidPolygon(const b3Vec3& normal, const b3Vec3* vertices, u32 count, const b3Color& color) +{ + b3Color fillColor(color.r, color.g, color.b, color.a); + + b3Vec3 p1 = vertices[0]; + for (u32 i = 1; i < count - 1; ++i) + { + b3Vec3 p2 = vertices[i]; + b3Vec3 p3 = vertices[i + 1]; + + m_triangles->Vertex(p1, fillColor, normal); + m_triangles->Vertex(p2, fillColor, normal); + m_triangles->Vertex(p3, fillColor, normal); + } + + b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f); + DrawPolygon(vertices, count, frameColor); +} + +void Draw::DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) +{ + // Build a tangent vector to normal. + b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f)); + b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f)); + + // Handle edge cases (zero cross product). + b3Vec3 n1; + if (b3LengthSquared(u) > b3LengthSquared(v)) + { + n1 = u; + } + else + { + n1 = v; + } + + n1.Normalize(); + + // Build a quaternion to rotate the tangent about the normal. + u32 kEdgeCount = 20; + float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount); + b3Quat q(normal, kAngleInc); + + b3Vec3 p1 = center + radius * n1; + for (u32 i = 0; i < kEdgeCount; ++i) + { + b3Vec3 n2 = b3Mul(q, n1); + b3Vec3 p2 = center + radius * n2; + + m_lines->Vertex(p1, color); + m_lines->Vertex(p2, color); + + n1 = n2; + p1 = p2; + } +} + +void Draw::DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) +{ + b3Color fillColor(color.r, color.g, color.b, color.a); + b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f); + + // Build a tangent vector to normal. + b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f)); + b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f)); + + // Handle edge cases (zero cross product). + b3Vec3 n1; + if (b3LengthSquared(u) > b3LengthSquared(v)) + { + n1 = u; + } + else + { + n1 = v; + } + + n1.Normalize(); + + // Build a quaternion to rotate the tangent about the normal. + const u32 kEdgeCount = 20; + const float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount); + b3Quat q(normal, kAngleInc); + + b3Vec3 p1 = center + radius * n1; + for (u32 i = 0; i < kEdgeCount; ++i) + { + b3Vec3 n2 = b3Mul(q, n1); + b3Vec3 p2 = center + radius * n2; + + m_triangles->Vertex(center, fillColor, normal); + m_triangles->Vertex(p1, fillColor, normal); + m_triangles->Vertex(p2, fillColor, normal); + + m_lines->Vertex(p1, frameColor); + m_lines->Vertex(p2, frameColor); + + n1 = n2; + p1 = p2; + } +} + +void Draw::DrawSphere(const b3Vec3& center, float32 radius, const b3Color& color) +{ + b3Transform xf; + xf.SetIdentity(); + xf.position = center; + + m_wire->DrawSphere(radius, color, xf); +} + +void Draw::DrawSolidSphere(const b3Vec3& center, float32 radius, const b3Color& color) +{ + b3Transform xf; + xf.SetIdentity(); + xf.position = center; + + m_solid->DrawSphere(radius, color, xf); +} + +void Draw::DrawCapsule(const b3Vec3& c1, const b3Vec3& c2, float32 radius, const b3Color& color) +{ + float32 height = b3Length(c1 - c2); + + { + b3Transform xfc; + xfc.rotation.SetIdentity(); + xfc.position = c1; + m_wire->DrawSphere(radius, color, xfc); + } + + if (height > 0.0f) + { + DrawSegment(c1, c2, color); + + { + b3Transform xfc; + xfc.rotation.SetIdentity(); + xfc.position = c2; + m_wire->DrawSphere(radius, color, xfc); + } + } +} + +void Draw::DrawSolidCapsule(const b3Vec3& c1, const b3Vec3& c2, float32 radius, const b3Color& c) +{ + float32 height = b3Length(c1 - c2); + + { + b3Transform xfc; + xfc.rotation.SetIdentity(); + xfc.position = c1; + m_solid->DrawSphere(radius, c, xfc); + } + + if (height > 0.0f) + { + { + b3Mat33 R; + R.y = (1.0f / height) * (c1 - c2); + R.z = b3Perp(R.y); + R.x = b3Cross(R.y, R.z); + + b3Transform xfc; + xfc.position = 0.5f * (c1 + c2); + xfc.rotation = R; + + m_solid->DrawCylinder(radius, height, c, xfc); + } + + { + b3Transform xfc; + xfc.rotation.SetIdentity(); + xfc.position = c2; + m_solid->DrawSphere(radius, c, xfc); + } + } +} + +void Draw::DrawTransform(const b3Transform& xf) +{ + float32 lenght = 1.0f; + + b3Color red(1.0f, 0.0f, 0.0f, 1.0f); + b3Color green(0.0f, 1.0f, 0.0f, 1.0f); + b3Color blue(0.0f, 0.0f, 1.0f, 1.0f); + + b3Vec3 position = xf.position; + b3Mat33 rotation = xf.rotation; + + b3Vec3 A = position + lenght * rotation.x; + b3Vec3 B = position + lenght * rotation.y; + b3Vec3 C = position + lenght * rotation.z; + + DrawSegment(position, A, red); + DrawSegment(position, B, green); + DrawSegment(position, C, blue); +} + +void Draw::DrawAABB(const b3AABB3& aabb, const b3Color& color) +{ + b3Vec3 lower = aabb.m_lower; + b3Vec3 upper = aabb.m_upper; + + b3Vec3 vs[8]; + + vs[0] = lower; + vs[1] = b3Vec3(lower.x, upper.y, lower.z); + vs[2] = b3Vec3(upper.x, upper.y, lower.z); + vs[3] = b3Vec3(upper.x, lower.y, lower.z); + + vs[4] = upper; + vs[5] = b3Vec3(upper.x, lower.y, upper.z); + vs[6] = b3Vec3(lower.x, lower.y, upper.z); + vs[7] = b3Vec3(lower.x, upper.y, upper.z); + + DrawSegment(vs[0], vs[1], color); + DrawSegment(vs[1], vs[2], color); + DrawSegment(vs[2], vs[3], color); + DrawSegment(vs[3], vs[0], color); + + DrawSegment(vs[4], vs[5], color); + DrawSegment(vs[5], vs[6], color); + DrawSegment(vs[6], vs[7], color); + DrawSegment(vs[7], vs[4], color); + + DrawSegment(vs[2], vs[4], color); + DrawSegment(vs[5], vs[3], color); + + DrawSegment(vs[6], vs[0], color); + DrawSegment(vs[1], vs[7], color); +} + +void Draw::DrawString(const b3Color& color, const char* text, ...) +{ + va_list args; + va_start(args, text); + + ImGui::SetNextWindowPos(ImVec2(0.0f, 40.0f)); + ImGui::SetNextWindowSize(ImVec2(g_camera->m_width, g_camera->m_height)); + + ImGui::Begin("Overlay", NULL, ImVec2(0.0f, 0.0f), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); + ImGui::TextColoredV(ImVec4(color.r, color.g, color.b, color.a), text, args); + ImGui::End(); + + va_end(args); +} + +void Draw::DrawSolidSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf) +{ + b3Transform xfc; + xfc.rotation = xf.rotation; + xfc.position = xf * s->m_center; + m_solid->DrawSphere(s->m_radius, c, xfc); +} + +void Draw::DrawSolidCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf) +{ + b3Vec3 c1 = s->m_centers[0]; + b3Vec3 c2 = s->m_centers[1]; + float32 height = b3Length(c1 - c2); + float32 radius = s->m_radius; + + { + b3Transform xfc; + xfc.rotation = xf.rotation; + xfc.position = xf * c1; + m_solid->DrawSphere(radius, c, xfc); + } + + if (height > 0.0f) + { + { + b3Mat33 R; + R.y = (1.0f / height) * (c1 - c2); + R.z = b3Perp(R.y); + R.x = b3Cross(R.y, R.z); + + b3Transform xfc; + xfc.position = xf * (0.5f * (c1 + c2)); + xfc.rotation = xf.rotation * R; + + m_solid->DrawCylinder(radius, height, c, xfc); + } + + { + b3Transform xfc; + xfc.rotation = xf.rotation; + xfc.position = xf * c2; + m_solid->DrawSphere(radius, c, xfc); + } + } +} + +void Draw::DrawSolidHull(const b3HullShape* s, const b3Color& c, const b3Transform& xf) +{ + const b3Hull* hull = s->m_hull; + + for (u32 i = 0; i < hull->faceCount; ++i) + { + const b3Face* face = hull->GetFace(i); + const b3HalfEdge* begin = hull->GetEdge(face->edge); + + b3Vec3 n = xf.rotation * hull->planes[i].normal; + + const b3HalfEdge* edge = hull->GetEdge(begin->next); + do + { + u32 i1 = begin->origin; + u32 i2 = edge->origin; + const b3HalfEdge* next = hull->GetEdge(edge->next); + u32 i3 = next->origin; + + b3Vec3 p1 = xf * hull->vertices[i1]; + b3Vec3 p2 = xf * hull->vertices[i2]; + b3Vec3 p3 = xf * hull->vertices[i3]; + + m_triangles->Vertex(p1, c, n); + m_triangles->Vertex(p2, c, n); + m_triangles->Vertex(p3, c, n); + + edge = next; + } while (hull->GetEdge(edge->next) != begin); + } +} + +void Draw::DrawSolidMesh(const b3MeshShape* s, const b3Color& c, const b3Transform& xf) +{ + const b3Mesh* mesh = s->m_mesh; + for (u32 i = 0; i < mesh->triangleCount; ++i) + { + const b3Triangle* t = mesh->triangles + i; + + b3Vec3 p1 = xf * mesh->vertices[t->v1]; + b3Vec3 p2 = xf * mesh->vertices[t->v2]; + b3Vec3 p3 = xf * mesh->vertices[t->v3]; + + b3Vec3 n1 = b3Cross(p2 - p1, p3 - p1); + n1.Normalize(); + + m_triangles->Vertex(p1, c, n1); + m_triangles->Vertex(p2, c, n1); + m_triangles->Vertex(p3, c, n1); + + b3Vec3 n2 = -n1; + + m_triangles->Vertex(p1, c, n2); + m_triangles->Vertex(p3, c, n2); + m_triangles->Vertex(p2, c, n2); + } +} + +void Draw::DrawSolidShape(const b3Shape* s, const b3Color& c, const b3Transform& xf) +{ + switch (s->GetType()) + { + case e_sphereShape: + { + DrawSolidSphere((b3SphereShape*)s, c, xf); + break; + } + case e_capsuleShape: + { + DrawSolidCapsule((b3CapsuleShape*)s, c, xf); + break; + } + case e_hullShape: + { + DrawSolidHull((b3HullShape*)s, c, xf); + break; + } + case e_meshShape: + { + DrawSolidMesh((b3MeshShape*)s, c, xf); + break; + } + default: + { + break; + } + } +} + +void Draw::DrawSolidShapes(const b3World& world) +{ + for (b3Body* b = world.GetBodyList().m_head; b; b = b->GetNext()) + { + b3Color c; + if (b->IsAwake() == false) + { + c = b3Color(0.5f, 0.25f, 0.25f, 1.0f); + } + else if (b->GetType() == e_staticBody) + { + c = b3Color(0.5f, 0.5f, 0.5f, 1.0f); + } + else if (b->GetType() == e_dynamicBody) + { + c = b3Color(1.0f, 0.5f, 0.5f, 1.0f); + } + else + { + c = b3Color(0.5f, 0.5f, 1.0f, 1.0f); + } + + b3Transform xf = b->GetTransform(); + for (b3Shape* s = b->GetShapeList().m_head; s; s = s->GetNext()) + { + DrawSolidShape(s, c, xf); + } + } +} + +void Draw::Flush() +{ + m_triangles->Flush(); + m_lines->Flush(); + m_points->Flush(); +} \ No newline at end of file diff --git a/examples/testbed/framework/debug_draw.h b/examples/testbed/framework/draw.h similarity index 86% rename from examples/testbed/framework/debug_draw.h rename to examples/testbed/framework/draw.h index 9730b73..458c7b6 100644 --- a/examples/testbed/framework/debug_draw.h +++ b/examples/testbed/framework/draw.h @@ -16,8 +16,8 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef DEBUG_DRAW_H -#define DEBUG_DRAW_H +#ifndef DRAW_H +#define DRAW_H #include @@ -168,12 +168,19 @@ inline Ray3 Camera::ConvertScreenToWorld(const b3Vec2& ps) const } // -class DebugDraw : public b3Draw +enum DrawFlags +{ + e_pointsFlag = 0x0001, + e_linesFlag = 0x0002, + e_trianglesFlag = 0x0004 +}; + +class Draw : public b3Draw { public: - DebugDraw(); - ~DebugDraw(); - + Draw(); + ~Draw(); + void DrawPoint(const b3Vec3& p, float32 size, const b3Color& color); void DrawSegment(const b3Vec3& p1, const b3Vec3& p2, const b3Color& color); @@ -203,35 +210,40 @@ public: void DrawAABB(const b3AABB3& aabb, const b3Color& color); void DrawTransform(const b3Transform& xf); - - // + void DrawString(const b3Color& color, const char* string, ...); - void DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf); + void DrawSolidSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf); - void DrawCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf); + void DrawSolidCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf); - void DrawHull(const b3HullShape* s, const b3Color& c, const b3Transform& xf); + void DrawSolidHull(const b3HullShape* s, const b3Color& c, const b3Transform& xf); - void DrawMesh(const b3MeshShape* s, const b3Color& c, const b3Transform& xf); + void DrawSolidMesh(const b3MeshShape* s, const b3Color& c, const b3Transform& xf); - void DrawShape(const b3Shape* s, const b3Color& c, const b3Transform& xf); + void DrawSolidShape(const b3Shape* s, const b3Color& c, const b3Transform& xf); - void Draw(const b3World& world); + void DrawSolidShapes(const b3World& world); - void Submit(); + void Flush(); private: - friend struct DrawShapes; + friend struct DrawPoints; + friend struct DrawLines; + friend struct DrawTriangles; DrawPoints* m_points; DrawLines* m_lines; DrawTriangles* m_triangles; + + friend struct DrawWire; + friend struct DrawSolid; + DrawWire* m_wire; DrawSolid* m_solid; }; -extern DebugDraw* g_debugDraw; extern Camera* g_camera; -extern const char* g_overlayName; +extern Draw* g_draw; +extern u32 g_drawFlags; #endif \ No newline at end of file diff --git a/examples/testbed/framework/debug_draw_2.cpp b/examples/testbed/framework/draw_gl2.h similarity index 67% rename from examples/testbed/framework/debug_draw_2.cpp rename to examples/testbed/framework/draw_gl2.h index ea83e7d..88ade7d 100644 --- a/examples/testbed/framework/debug_draw_2.cpp +++ b/examples/testbed/framework/draw_gl2.h @@ -16,19 +16,16 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include +#ifndef DRAW_GL2_H +#define DRAW_GL2_H + +#include #include -#include #include #include -// -DebugDraw* g_debugDraw = nullptr; -Camera* g_camera = nullptr; -const char* g_overlayName = nullptr; - #define BUFFER_OFFSET(i) ((char*)NULL + (i)) static void AssertGL() @@ -176,7 +173,7 @@ struct DrawPoints { if (m_count == e_vertexCapacity) { - Submit(); + Flush(); } m_vertices[m_count] = v; @@ -185,13 +182,19 @@ struct DrawPoints ++m_count; } - void Submit() + void Flush() { if (m_count == 0) { return; } + if ((g_drawFlags & DrawFlags::e_pointsFlag) == 0) + { + m_count = 0; + return; + } + glUseProgram(m_programId); b3Mat44 m1 = g_camera->BuildViewMatrix(); @@ -306,7 +309,7 @@ struct DrawLines { if (m_count == e_vertexCapacity) { - Submit(); + Flush(); } m_vertices[m_count] = v; @@ -314,13 +317,19 @@ struct DrawLines ++m_count; } - void Submit() + void Flush() { if (m_count == 0) { return; } + if ((g_drawFlags & DrawFlags::e_linesFlag) == 0) + { + m_count = 0; + return; + } + glUseProgram(m_programId); b3Mat44 m1 = g_camera->BuildViewMatrix(); @@ -435,7 +444,7 @@ struct DrawTriangles { if (m_count == e_vertexCapacity) { - Submit(); + Flush(); } m_vertices[m_count] = v; @@ -444,12 +453,18 @@ struct DrawTriangles ++m_count; } - void Submit() + void Flush() { if (m_count == 0) { return; } + + if ((g_drawFlags & DrawFlags::e_trianglesFlag) == 0) + { + m_count = 0; + return; + } glUseProgram(m_programId); @@ -631,6 +646,11 @@ struct DrawWire void DrawSphere(float32 radius, const b3Color& c, const b3Transform& xf) { + if ((g_drawFlags & DrawFlags::e_linesFlag) == 0) + { + return; + } + glUseProgram(m_programId); b3Mat44 m1 = MakeMat44(xf); @@ -920,6 +940,11 @@ struct DrawSolid void DrawCylinder(float32 radius, float32 height, const b3Color& c, const b3Transform& xf) { + if ((g_drawFlags & DrawFlags::e_trianglesFlag) == 0) + { + return; + } + glUseProgram(m_programId); b3Mat44 m1 = MakeMat44(xf); @@ -958,6 +983,11 @@ struct DrawSolid void DrawSphere(float32 radius, const b3Color& c, const b3Transform& xf) { + if ((g_drawFlags & DrawFlags::e_trianglesFlag) == 0) + { + return; + } + glUseProgram(m_programId); b3Mat44 m1 = MakeMat44(xf); @@ -1005,494 +1035,4 @@ struct DrawSolid DrawSolidCylinder m_cylinder; }; -DebugDraw::DebugDraw() -{ - m_points = new DrawPoints(); - m_lines = new DrawLines(); - m_triangles = new DrawTriangles(); - m_wire = new DrawWire(); - m_solid = new DrawSolid(); -} - -DebugDraw::~DebugDraw() -{ - delete m_points; - delete m_lines; - delete m_triangles; - delete m_wire; - delete m_solid; -} - -void DebugDraw::DrawPoint(const b3Vec3& p, float32 size, const b3Color& color) -{ - m_points->Vertex(p, size, color); -} - -void DebugDraw::DrawSegment(const b3Vec3& p1, const b3Vec3& p2, const b3Color& color) -{ - m_lines->Vertex(p1, color); - m_lines->Vertex(p2, color); -} - -void DebugDraw::DrawTriangle(const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color) -{ - DrawSegment(p1, p2, color); - DrawSegment(p2, p3, color); - DrawSegment(p3, p1, color); -} - -void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color) -{ - m_triangles->Vertex(p1, color, normal); - m_triangles->Vertex(p2, color, normal); - m_triangles->Vertex(p3, color, normal); - - b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p1, p2, p3, edgeColor); -} - -void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Color& color1, const b3Vec3& p2, const b3Color& color2, const b3Vec3& p3, const b3Color& color3) -{ - m_triangles->Vertex(p1, color1, normal); - m_triangles->Vertex(p2, color2, normal); - m_triangles->Vertex(p3, color3, normal); - - b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p1, p2, p3, edgeColor); -} - -void DebugDraw::DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) -{ - b3Vec3 p1 = vertices[count - 1]; - for (u32 i = 0; i < count; ++i) - { - b3Vec3 p2 = vertices[i]; - - m_lines->Vertex(p1, color); - m_lines->Vertex(p2, color); - - p1 = p2; - } -} - -void DebugDraw::DrawSolidPolygon(const b3Vec3& normal, const b3Vec3* vertices, u32 count, const b3Color& color) -{ - b3Color fillColor(color.r, color.g, color.b, color.a); - - b3Vec3 p1 = vertices[0]; - for (u32 i = 1; i < count - 1; ++i) - { - b3Vec3 p2 = vertices[i]; - b3Vec3 p3 = vertices[i + 1]; - - m_triangles->Vertex(p1, fillColor, normal); - m_triangles->Vertex(p2, fillColor, normal); - m_triangles->Vertex(p3, fillColor, normal); - } - - b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f); - DrawPolygon(vertices, count, frameColor); -} - -void DebugDraw::DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) -{ - // Build a tangent vector to normal. - b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f)); - b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f)); - - // Handle edge cases (zero cross product). - b3Vec3 n1; - if (b3LengthSquared(u) > b3LengthSquared(v)) - { - n1 = u; - } - else - { - n1 = v; - } - - n1.Normalize(); - - // Build a quaternion to rotate the tangent about the normal. - u32 kEdgeCount = 20; - float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount); - b3Quat q(normal, kAngleInc); - - b3Vec3 p1 = center + radius * n1; - for (u32 i = 0; i < kEdgeCount; ++i) - { - b3Vec3 n2 = b3Mul(q, n1); - b3Vec3 p2 = center + radius * n2; - - m_lines->Vertex(p1, color); - m_lines->Vertex(p2, color); - - n1 = n2; - p1 = p2; - } -} - -void DebugDraw::DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) -{ - b3Color fillColor(color.r, color.g, color.b, color.a); - b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f); - - // Build a tangent vector to normal. - b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f)); - b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f)); - - // Handle edge cases (zero cross product). - b3Vec3 n1; - if (b3LengthSquared(u) > b3LengthSquared(v)) - { - n1 = u; - } - else - { - n1 = v; - } - - n1.Normalize(); - - // Build a quaternion to rotate the tangent about the normal. - const u32 kEdgeCount = 20; - const float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount); - b3Quat q(normal, kAngleInc); - - b3Vec3 p1 = center + radius * n1; - for (u32 i = 0; i < kEdgeCount; ++i) - { - b3Vec3 n2 = b3Mul(q, n1); - b3Vec3 p2 = center + radius * n2; - - m_triangles->Vertex(center, fillColor, normal); - m_triangles->Vertex(p1, fillColor, normal); - m_triangles->Vertex(p2, fillColor, normal); - - m_lines->Vertex(p1, frameColor); - m_lines->Vertex(p2, frameColor); - - n1 = n2; - p1 = p2; - } -} - -void DebugDraw::DrawSphere(const b3Vec3& center, float32 radius, const b3Color& color) -{ - b3Transform xf; - xf.SetIdentity(); - xf.position = center; - - m_wire->DrawSphere(radius, color, xf); -} - -void DebugDraw::DrawSolidSphere(const b3Vec3& center, float32 radius, const b3Color& color) -{ - b3Transform xf; - xf.SetIdentity(); - xf.position = center; - - m_solid->DrawSphere(radius, color, xf); -} - -void DebugDraw::DrawCapsule(const b3Vec3& c1, const b3Vec3& c2, float32 radius, const b3Color& color) -{ - float32 height = b3Length(c1 - c2); - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c1; - m_wire->DrawSphere(radius, color, xfc); - } - - if (height > 0.0f) - { - DrawSegment(c1, c2, color); - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c2; - m_wire->DrawSphere(radius, color, xfc); - } - } -} - -void DebugDraw::DrawSolidCapsule(const b3Vec3& c1, const b3Vec3& c2, float32 radius, const b3Color& c) -{ - float32 height = b3Length(c1 - c2); - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c1; - m_solid->DrawSphere(radius, c, xfc); - } - - if (height > 0.0f) - { - { - b3Mat33 R; - R.y = (1.0f / height) * (c1 - c2); - R.z = b3Perp(R.y); - R.x = b3Cross(R.y, R.z); - - b3Transform xfc; - xfc.position = 0.5f * (c1 + c2); - xfc.rotation = R; - - m_solid->DrawCylinder(radius, height, c, xfc); - } - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c2; - m_solid->DrawSphere(radius, c, xfc); - } - } -} - -void DebugDraw::DrawTransform(const b3Transform& xf) -{ - float32 lenght = 1.0f; - - b3Color red(1.0f, 0.0f, 0.0f, 1.0f); - b3Color green(0.0f, 1.0f, 0.0f, 1.0f); - b3Color blue(0.0f, 0.0f, 1.0f, 1.0f); - - b3Vec3 position = xf.position; - b3Mat33 rotation = xf.rotation; - - b3Vec3 A = position + lenght * rotation.x; - b3Vec3 B = position + lenght * rotation.y; - b3Vec3 C = position + lenght * rotation.z; - - DrawSegment(position, A, red); - DrawSegment(position, B, green); - DrawSegment(position, C, blue); -} - -void DebugDraw::DrawAABB(const b3AABB3& aabb, const b3Color& color) -{ - b3Vec3 lower = aabb.m_lower; - b3Vec3 upper = aabb.m_upper; - - b3Vec3 vs[8]; - - vs[0] = lower; - vs[1] = b3Vec3(lower.x, upper.y, lower.z); - vs[2] = b3Vec3(upper.x, upper.y, lower.z); - vs[3] = b3Vec3(upper.x, lower.y, lower.z); - - vs[4] = upper; - vs[5] = b3Vec3(upper.x, lower.y, upper.z); - vs[6] = b3Vec3(lower.x, lower.y, upper.z); - vs[7] = b3Vec3(lower.x, upper.y, upper.z); - - DrawSegment(vs[0], vs[1], color); - DrawSegment(vs[1], vs[2], color); - DrawSegment(vs[2], vs[3], color); - DrawSegment(vs[3], vs[0], color); - - DrawSegment(vs[4], vs[5], color); - DrawSegment(vs[5], vs[6], color); - DrawSegment(vs[6], vs[7], color); - DrawSegment(vs[7], vs[4], color); - - DrawSegment(vs[2], vs[4], color); - DrawSegment(vs[5], vs[3], color); - - DrawSegment(vs[6], vs[0], color); - DrawSegment(vs[1], vs[7], color); -} - -void DebugDraw::DrawString(const b3Color& color, const char* text, ...) -{ - va_list args; - va_start(args, text); - - ImGui::SetNextWindowPos(ImVec2(0.0f, 40.0f)); - ImGui::SetNextWindowSize(ImVec2(g_camera->m_width, g_camera->m_height)); - - ImGui::Begin(g_overlayName, NULL, ImVec2(0.0f, 0.0f), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - ImGui::TextColoredV(ImVec4(color.r, color.g, color.b, color.a), text, args); - ImGui::End(); - - va_end(args); -} - -void DebugDraw::DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf) -{ - b3Transform xfc; - xfc.rotation = xf.rotation; - xfc.position = xf * s->m_center; - m_solid->DrawSphere(s->m_radius, c, xfc); -} - -void DebugDraw::DrawCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf) -{ - b3Vec3 c1 = s->m_centers[0]; - b3Vec3 c2 = s->m_centers[1]; - float32 height = b3Length(c1 - c2); - float32 radius = s->m_radius; - - { - b3Transform xfc; - xfc.rotation = xf.rotation; - xfc.position = xf * c1; - m_solid->DrawSphere(radius, c, xfc); - } - - if (height > 0.0f) - { - { - b3Mat33 R; - R.y = (1.0f / height) * (c1 - c2); - R.z = b3Perp(R.y); - R.x = b3Cross(R.y, R.z); - - b3Transform xfc; - xfc.position = xf * (0.5f * (c1 + c2)); - xfc.rotation = xf.rotation * R; - - m_solid->DrawCylinder(radius, height, c, xfc); - } - - { - b3Transform xfc; - xfc.rotation = xf.rotation; - xfc.position = xf * c2; - m_solid->DrawSphere(radius, c, xfc); - } - } -} - -void DebugDraw::DrawHull(const b3HullShape* s, const b3Color& c, const b3Transform& xf) -{ - const b3Hull* hull = s->m_hull; - - for (u32 i = 0; i < hull->faceCount; ++i) - { - const b3Face* face = hull->GetFace(i); - const b3HalfEdge* begin = hull->GetEdge(face->edge); - - b3Vec3 n = xf.rotation * hull->planes[i].normal; - - const b3HalfEdge* edge = hull->GetEdge(begin->next); - do - { - u32 i1 = begin->origin; - u32 i2 = edge->origin; - const b3HalfEdge* next = hull->GetEdge(edge->next); - u32 i3 = next->origin; - - b3Vec3 p1 = xf * hull->vertices[i1]; - b3Vec3 p2 = xf * hull->vertices[i2]; - b3Vec3 p3 = xf * hull->vertices[i3]; - - m_triangles->Vertex(p1, c, n); - m_triangles->Vertex(p2, c, n); - m_triangles->Vertex(p3, c, n); - - edge = next; - } while (hull->GetEdge(edge->next) != begin); - } -} - -void DebugDraw::DrawMesh(const b3MeshShape* s, const b3Color& c, const b3Transform& xf) -{ - const b3Mesh* mesh = s->m_mesh; - for (u32 i = 0; i < mesh->triangleCount; ++i) - { - const b3Triangle* t = mesh->triangles + i; - - b3Vec3 p1 = xf * mesh->vertices[t->v1]; - b3Vec3 p2 = xf * mesh->vertices[t->v2]; - b3Vec3 p3 = xf * mesh->vertices[t->v3]; - - b3Vec3 n1 = b3Cross(p2 - p1, p3 - p1); - n1.Normalize(); - - m_triangles->Vertex(p1, c, n1); - m_triangles->Vertex(p2, c, n1); - m_triangles->Vertex(p3, c, n1); - - b3Vec3 n2 = -n1; - - m_triangles->Vertex(p1, c, n2); - m_triangles->Vertex(p3, c, n2); - m_triangles->Vertex(p2, c, n2); - } -} - -void DebugDraw::DrawShape(const b3Shape* s, const b3Color& c, const b3Transform& xf) -{ - switch (s->GetType()) - { - case e_sphereShape: - { - DrawSphere((b3SphereShape*)s, c, xf); - break; - } - case e_capsuleShape: - { - DrawCapsule((b3CapsuleShape*)s, c, xf); - break; - } - case e_hullShape: - { - DrawHull((b3HullShape*)s, c, xf); - break; - } - case e_meshShape: - { - DrawMesh((b3MeshShape*)s, c, xf); - break; - } - default: - { - break; - } - } -} - -void DebugDraw::Draw(const b3World& world) -{ - for (b3Body* b = world.GetBodyList().m_head; b; b = b->GetNext()) - { - b3Color c; - if (b->IsAwake() == false) - { - c = b3Color(0.5f, 0.25f, 0.25f, 1.0f); - } - else if (b->GetType() == e_staticBody) - { - c = b3Color(0.5f, 0.5f, 0.5f, 1.0f); - } - else if (b->GetType() == e_dynamicBody) - { - c = b3Color(1.0f, 0.5f, 0.5f, 1.0f); - } - else - { - c = b3Color(0.5f, 0.5f, 1.0f, 1.0f); - } - - b3Transform xf = b->GetTransform(); - for (b3Shape* s = b->GetShapeList().m_head; s; s = s->GetNext()) - { - DrawShape(s, c, xf); - } - } - - g_debugDraw->Submit(); -} - -void DebugDraw::Submit() -{ - m_triangles->Submit(); - m_lines->Submit(); - m_points->Submit(); -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/examples/testbed/framework/debug_draw_4.cpp b/examples/testbed/framework/draw_gl4.h similarity index 67% rename from examples/testbed/framework/debug_draw_4.cpp rename to examples/testbed/framework/draw_gl4.h index bf4caf7..d324c5a 100644 --- a/examples/testbed/framework/debug_draw_4.cpp +++ b/examples/testbed/framework/draw_gl4.h @@ -16,19 +16,13 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#include +#include #include -#include #include #include -// -DebugDraw* g_debugDraw = nullptr; -Camera* g_camera = nullptr; -const char* g_overlayName = nullptr; - #define BUFFER_OFFSET(i) ((char*)NULL + (i)) static void AssertGL() @@ -190,7 +184,7 @@ struct DrawPoints { if (m_count == e_vertexCapacity) { - Submit(); + Flush(); } m_vertices[m_count] = v; @@ -199,12 +193,18 @@ struct DrawPoints ++m_count; } - void Submit() + void Flush() { if (m_count == 0) { return; } + + if ((g_drawFlags & DrawFlags::e_pointsFlag) == 0) + { + m_count = 0; + return; + } glUseProgram(m_programId); @@ -322,7 +322,7 @@ struct DrawLines { if (m_count == e_vertexCapacity) { - Submit(); + Flush(); } m_vertices[m_count] = v; @@ -330,12 +330,18 @@ struct DrawLines ++m_count; } - void Submit() + void Flush() { if (m_count == 0) { return; } + + if ((g_drawFlags & DrawFlags::e_linesFlag) == 0) + { + m_count = 0; + return; + } glUseProgram(m_programId); @@ -459,7 +465,7 @@ struct DrawTriangles { if (m_count == e_vertexCapacity) { - Submit(); + Flush(); } m_vertices[m_count] = v; @@ -468,13 +474,19 @@ struct DrawTriangles ++m_count; } - void Submit() + void Flush() { if (m_count == 0) { return; } + if ((g_drawFlags & DrawFlags::e_trianglesFlag) == 0) + { + m_count = 0; + return; + } + glUseProgram(m_programId); b3Mat44 m1 = g_camera->BuildViewMatrix(); @@ -648,6 +660,11 @@ struct DrawWire void DrawSphere(float32 radius, const b3Color& c, const b3Transform& xf) { + if ((g_drawFlags & DrawFlags::e_linesFlag) == 0) + { + return; + } + glUseProgram(m_programId); b3Mat44 m1 = MakeMat44(xf); @@ -936,6 +953,11 @@ struct DrawSolid void DrawCylinder(float32 radius, float32 height, const b3Color& c, const b3Transform& xf) { + if ((g_drawFlags & DrawFlags::e_trianglesFlag) == 0) + { + return; + } + glUseProgram(m_programId); b3Mat44 m1 = MakeMat44(xf); @@ -970,6 +992,11 @@ struct DrawSolid void DrawSphere(float32 radius, const b3Color& c, const b3Transform& xf) { + if ((g_drawFlags & DrawFlags::e_trianglesFlag) == 0) + { + return; + } + glUseProgram(m_programId); b3Mat44 m1 = MakeMat44(xf); @@ -1011,496 +1038,4 @@ struct DrawSolid DrawSolidSphere m_sphere; DrawSolidCylinder m_cylinder; -}; - -DebugDraw::DebugDraw() -{ - m_points = new DrawPoints(); - m_lines = new DrawLines(); - m_triangles = new DrawTriangles(); - m_wire = new DrawWire(); - m_solid = new DrawSolid(); -} - -DebugDraw::~DebugDraw() -{ - delete m_points; - delete m_lines; - delete m_triangles; - delete m_wire; - delete m_solid; -} - -void DebugDraw::DrawPoint(const b3Vec3& p, float32 size, const b3Color& color) -{ - m_points->Vertex(p, size, color); -} - -void DebugDraw::DrawSegment(const b3Vec3& p1, const b3Vec3& p2, const b3Color& color) -{ - m_lines->Vertex(p1, color); - m_lines->Vertex(p2, color); -} - -void DebugDraw::DrawTriangle(const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color) -{ - DrawSegment(p1, p2, color); - DrawSegment(p2, p3, color); - DrawSegment(p3, p1, color); -} - -void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Vec3& p2, const b3Vec3& p3, const b3Color& color) -{ - m_triangles->Vertex(p1, color, normal); - m_triangles->Vertex(p2, color, normal); - m_triangles->Vertex(p3, color, normal); - - b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p1, p2, p3, edgeColor); -} - -void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const b3Color& color1, const b3Vec3& p2, const b3Color& color2, const b3Vec3& p3, const b3Color& color3) -{ - m_triangles->Vertex(p1, color1, normal); - m_triangles->Vertex(p2, color2, normal); - m_triangles->Vertex(p3, color3, normal); - - b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p1, p2, p3, edgeColor); -} - -void DebugDraw::DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) -{ - b3Vec3 p1 = vertices[count - 1]; - for (u32 i = 0; i < count; ++i) - { - b3Vec3 p2 = vertices[i]; - - m_lines->Vertex(p1, color); - m_lines->Vertex(p2, color); - - p1 = p2; - } -} - -void DebugDraw::DrawSolidPolygon(const b3Vec3& normal, const b3Vec3* vertices, u32 count, const b3Color& color) -{ - b3Color fillColor(color.r, color.g, color.b, color.a); - - b3Vec3 p1 = vertices[0]; - for (u32 i = 1; i < count - 1; ++i) - { - b3Vec3 p2 = vertices[i]; - b3Vec3 p3 = vertices[i + 1]; - - m_triangles->Vertex(p1, fillColor, normal); - m_triangles->Vertex(p2, fillColor, normal); - m_triangles->Vertex(p3, fillColor, normal); - } - - b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f); - DrawPolygon(vertices, count, frameColor); -} - -void DebugDraw::DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) -{ - // Build a tangent vector to normal. - b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f)); - b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f)); - - // Handle edge cases (zero cross product). - b3Vec3 n1; - if (b3LengthSquared(u) > b3LengthSquared(v)) - { - n1 = u; - } - else - { - n1 = v; - } - - n1.Normalize(); - - // Build a quaternion to rotate the tangent about the normal. - u32 kEdgeCount = 20; - float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount); - b3Quat q(normal, kAngleInc); - - b3Vec3 p1 = center + radius * n1; - for (u32 i = 0; i < kEdgeCount; ++i) - { - b3Vec3 n2 = b3Mul(q, n1); - b3Vec3 p2 = center + radius * n2; - - m_lines->Vertex(p1, color); - m_lines->Vertex(p2, color); - - n1 = n2; - p1 = p2; - } -} - -void DebugDraw::DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) -{ - b3Color fillColor(color.r, color.g, color.b, color.a); - b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f); - - // Build a tangent vector to normal. - b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f)); - b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f)); - - // Handle edge cases (zero cross product). - b3Vec3 n1; - if (b3LengthSquared(u) > b3LengthSquared(v)) - { - n1 = u; - } - else - { - n1 = v; - } - - n1.Normalize(); - - // Build a quaternion to rotate the tangent about the normal. - const u32 kEdgeCount = 20; - const float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount); - b3Quat q(normal, kAngleInc); - - b3Vec3 p1 = center + radius * n1; - for (u32 i = 0; i < kEdgeCount; ++i) - { - b3Vec3 n2 = b3Mul(q, n1); - b3Vec3 p2 = center + radius * n2; - - m_triangles->Vertex(center, fillColor, normal); - m_triangles->Vertex(p1, fillColor, normal); - m_triangles->Vertex(p2, fillColor, normal); - - m_lines->Vertex(p1, frameColor); - m_lines->Vertex(p2, frameColor); - - n1 = n2; - p1 = p2; - } -} - -void DebugDraw::DrawSphere(const b3Vec3& center, float32 radius, const b3Color& color) -{ - b3Transform xf; - xf.SetIdentity(); - xf.position = center; - - m_wire->DrawSphere(radius, color, xf); -} - -void DebugDraw::DrawSolidSphere(const b3Vec3& center, float32 radius, const b3Color& color) -{ - b3Transform xf; - xf.SetIdentity(); - xf.position = center; - - m_solid->DrawSphere(radius, color, xf); -} - -void DebugDraw::DrawCapsule(const b3Vec3& c1, const b3Vec3& c2, float32 radius, const b3Color& color) -{ - float32 height = b3Length(c1 - c2); - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c1; - m_wire->DrawSphere(radius, color, xfc); - } - - if (height > 0.0f) - { - DrawSegment(c1, c2, color); - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c2; - m_wire->DrawSphere(radius, color, xfc); - } - } -} - -void DebugDraw::DrawSolidCapsule(const b3Vec3& c1, const b3Vec3& c2, float32 radius, const b3Color& c) -{ - float32 height = b3Length(c1 - c2); - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c1; - m_solid->DrawSphere(radius, c, xfc); - } - - if (height > 0.0f) - { - { - b3Mat33 R; - R.y = (1.0f / height) * (c1 - c2); - R.z = b3Perp(R.y); - R.x = b3Cross(R.y, R.z); - - b3Transform xfc; - xfc.position = 0.5f * (c1 + c2); - xfc.rotation = R; - - m_solid->DrawCylinder(radius, height, c, xfc); - } - - { - b3Transform xfc; - xfc.rotation.SetIdentity(); - xfc.position = c2; - m_solid->DrawSphere(radius, c, xfc); - } - } -} - -void DebugDraw::DrawTransform(const b3Transform& xf) -{ - float32 lenght = 1.0f; - - b3Color red(1.0f, 0.0f, 0.0f, 1.0f); - b3Color green(0.0f, 1.0f, 0.0f, 1.0f); - b3Color blue(0.0f, 0.0f, 1.0f, 1.0f); - - b3Vec3 position = xf.position; - b3Mat33 rotation = xf.rotation; - - b3Vec3 A = position + lenght * rotation.x; - b3Vec3 B = position + lenght * rotation.y; - b3Vec3 C = position + lenght * rotation.z; - - DrawSegment(position, A, red); - DrawSegment(position, B, green); - DrawSegment(position, C, blue); -} - -void DebugDraw::DrawAABB(const b3AABB3& aabb, const b3Color& color) -{ - b3Vec3 lower = aabb.m_lower; - b3Vec3 upper = aabb.m_upper; - - b3Vec3 vs[8]; - - vs[0] = lower; - vs[1] = b3Vec3(lower.x, upper.y, lower.z); - vs[2] = b3Vec3(upper.x, upper.y, lower.z); - vs[3] = b3Vec3(upper.x, lower.y, lower.z); - - vs[4] = upper; - vs[5] = b3Vec3(upper.x, lower.y, upper.z); - vs[6] = b3Vec3(lower.x, lower.y, upper.z); - vs[7] = b3Vec3(lower.x, upper.y, upper.z); - - DrawSegment(vs[0], vs[1], color); - DrawSegment(vs[1], vs[2], color); - DrawSegment(vs[2], vs[3], color); - DrawSegment(vs[3], vs[0], color); - - DrawSegment(vs[4], vs[5], color); - DrawSegment(vs[5], vs[6], color); - DrawSegment(vs[6], vs[7], color); - DrawSegment(vs[7], vs[4], color); - - DrawSegment(vs[2], vs[4], color); - DrawSegment(vs[5], vs[3], color); - - DrawSegment(vs[6], vs[0], color); - DrawSegment(vs[1], vs[7], color); -} - -void DebugDraw::DrawString(const b3Color& color, const char* text, ...) -{ - va_list args; - va_start(args, text); - - ImGui::SetNextWindowPos(ImVec2(0.0f, 40.0f)); - ImGui::SetNextWindowSize(ImVec2(g_camera->m_width, g_camera->m_height)); - - ImGui::Begin(g_overlayName, NULL, ImVec2(0.0f, 0.0f), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - ImGui::TextColoredV(ImVec4(color.r, color.g, color.b, color.a), text, args); - ImGui::End(); - - va_end(args); -} - -void DebugDraw::DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf) -{ - b3Transform xfc; - xfc.rotation = xf.rotation; - xfc.position = xf * s->m_center; - m_solid->DrawSphere(s->m_radius, c, xfc); -} - -void DebugDraw::DrawCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf) -{ - b3Vec3 c1 = s->m_centers[0]; - b3Vec3 c2 = s->m_centers[1]; - float32 height = b3Length(c1 - c2); - float32 radius = s->m_radius; - - { - b3Transform xfc; - xfc.rotation = xf.rotation; - xfc.position = xf * c1; - m_solid->DrawSphere(radius, c, xfc); - } - - if (height > 0.0f) - { - { - b3Mat33 R; - R.y = (1.0f / height) * (c1 - c2); - R.z = b3Perp(R.y); - R.x = b3Cross(R.y, R.z); - - b3Transform xfc; - xfc.position = xf * (0.5f * (c1 + c2)); - xfc.rotation = xf.rotation * R; - - m_solid->DrawCylinder(radius, height, c, xfc); - } - - { - b3Transform xfc; - xfc.rotation = xf.rotation; - xfc.position = xf * c2; - m_solid->DrawSphere(radius, c, xfc); - } - } -} - -void DebugDraw::DrawHull(const b3HullShape* s, const b3Color& c, const b3Transform& xf) -{ - const b3Hull* hull = s->m_hull; - - for (u32 i = 0; i < hull->faceCount; ++i) - { - const b3Face* face = hull->GetFace(i); - const b3HalfEdge* begin = hull->GetEdge(face->edge); - - b3Vec3 n = xf.rotation * hull->planes[i].normal; - - const b3HalfEdge* edge = hull->GetEdge(begin->next); - do - { - u32 i1 = begin->origin; - u32 i2 = edge->origin; - const b3HalfEdge* next = hull->GetEdge(edge->next); - u32 i3 = next->origin; - - b3Vec3 p1 = xf * hull->vertices[i1]; - b3Vec3 p2 = xf * hull->vertices[i2]; - b3Vec3 p3 = xf * hull->vertices[i3]; - - m_triangles->Vertex(p1, c, n); - m_triangles->Vertex(p2, c, n); - m_triangles->Vertex(p3, c, n); - - edge = next; - } while (hull->GetEdge(edge->next) != begin); - } -} - -void DebugDraw::DrawMesh(const b3MeshShape* s, const b3Color& c, const b3Transform& xf) -{ - const b3Mesh* mesh = s->m_mesh; - for (u32 i = 0; i < mesh->triangleCount; ++i) - { - const b3Triangle* t = mesh->triangles + i; - - b3Vec3 p1 = xf * mesh->vertices[t->v1]; - b3Vec3 p2 = xf * mesh->vertices[t->v2]; - b3Vec3 p3 = xf * mesh->vertices[t->v3]; - - b3Vec3 n1 = b3Cross(p2 - p1, p3 - p1); - n1.Normalize(); - - m_triangles->Vertex(p1, c, n1); - m_triangles->Vertex(p2, c, n1); - m_triangles->Vertex(p3, c, n1); - - b3Vec3 n2 = -n1; - - m_triangles->Vertex(p1, c, n2); - m_triangles->Vertex(p3, c, n2); - m_triangles->Vertex(p2, c, n2); - } -} - -void DebugDraw::DrawShape(const b3Shape* s, const b3Color& c, const b3Transform& xf) -{ - switch (s->GetType()) - { - case e_sphereShape: - { - DrawSphere((b3SphereShape*)s, c, xf); - break; - } - case e_capsuleShape: - { - DrawCapsule((b3CapsuleShape*)s, c, xf); - break; - } - case e_hullShape: - { - DrawHull((b3HullShape*)s, c, xf); - break; - } - case e_meshShape: - { - DrawMesh((b3MeshShape*)s, c, xf); - break; - } - default: - { - break; - } - } -} - -void DebugDraw::Draw(const b3World& world) -{ - for (b3Body* b = world.GetBodyList().m_head; b; b = b->GetNext()) - { - b3Color c; - if (b->IsAwake() == false) - { - c = b3Color(0.5f, 0.25f, 0.25f, 1.0f); - } - else if (b->GetType() == e_staticBody) - { - c = b3Color(0.5f, 0.5f, 0.5f, 1.0f); - } - else if (b->GetType() == e_dynamicBody) - { - c = b3Color(1.0f, 0.5f, 0.5f, 1.0f); - } - else - { - c = b3Color(0.5f, 0.5f, 1.0f, 1.0f); - } - - b3Transform xf = b->GetTransform(); - for (b3Shape* s = b->GetShapeList().m_head; s; s = s->GetNext()) - { - DrawShape(s, c, xf); - } - } - - g_debugDraw->Submit(); -} - -void DebugDraw::Submit() -{ - m_triangles->Submit(); - m_lines->Submit(); - m_points->Submit(); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/examples/testbed/framework/main.cpp b/examples/testbed/framework/main.cpp index b5f071b..f7d0478 100644 --- a/examples/testbed/framework/main.cpp +++ b/examples/testbed/framework/main.cpp @@ -99,27 +99,34 @@ static void Run() int w, h; glfwGetWindowSize(g_window, &w, &h); g_controller->Event_SetWindowSize(u32(w), u32(h)); - - double frameTime = 0.0; - + while (glfwWindowShouldClose(g_window) == 0) { - double time1 = glfwGetTime(); + g_profiler->Begin(); + + g_profiler->PushEvent("Frame"); g_view->Command_PreDraw(); - g_view->Command_Draw(); + if (g_settings->drawProfile) + { + const b3Array& records = g_profilerRecorder->GetRecords(); + for (u32 i = 0; i < records.Count(); ++i) + { + const ProfilerRecord& r = records[i]; + g_draw->DrawString(b3Color_white, "%s %.4f (%.4f) [ms]", r.name, r.elapsed, r.maxElapsed); + } + } - g_debugDraw->DrawString(b3Color_yellow, "%.2f [ms]", 1000.0 * frameTime); + g_view->Command_Draw(); g_model->Command_Step(); g_view->Command_PostDraw(); - double time2 = glfwGetTime(); + g_profiler->PopEvent(); - double fraction = 0.9; - frameTime = fraction * frameTime + (1.0 - fraction) * (time2 - time1); + g_profiler->End(g_profilerListener); glfwSwapBuffers(g_window); glfwPollEvents(); diff --git a/examples/testbed/framework/model.cpp b/examples/testbed/framework/model.cpp index 7fc1bf3..1f43563 100644 --- a/examples/testbed/framework/model.cpp +++ b/examples/testbed/framework/model.cpp @@ -20,12 +20,13 @@ Model::Model() { - g_debugDraw = &m_debugDraw; - g_camera = &m_camera; - g_overlayName = "Overlay"; - g_profiler = &m_profiler; - g_profilerListener = &m_profilerListener; g_settings = &m_settings; + g_testSettings = &m_testSettings; + g_draw = &m_draw; + g_camera = &m_camera; + g_profiler = &m_profiler; + g_profilerRecorder = &m_profilerListener.m_recorderProfiler; + g_profilerListener = &m_profilerListener; m_test = nullptr; @@ -44,38 +45,44 @@ Model::Model() Model::~Model() { - g_debugDraw = nullptr; + g_testSettings = nullptr; + g_draw = nullptr; g_camera = nullptr; - g_overlayName = nullptr; g_profiler = nullptr; + g_profilerRecorder = nullptr; g_profilerListener = nullptr; - g_settings = nullptr; + g_testSettings = nullptr; delete m_test; } void Model::Command_Step() { + g_drawFlags = 0; + g_drawFlags += m_settings.drawPoints * DrawFlags::e_pointsFlag; + g_drawFlags += m_settings.drawLines * DrawFlags::e_linesFlag; + g_drawFlags += m_settings.drawTriangles * DrawFlags::e_trianglesFlag; + + glViewport(0, 0, GLsizei(m_camera.m_width), GLsizei(m_camera.m_height)); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if (m_settings.testID != m_settings.lastTestID) { delete m_test; m_settings.lastTestID = m_settings.testID; m_test = g_tests[m_settings.testID].create(); + m_settings.pause = true; - Action_DefaultCamera(); } - glViewport(0, 0, GLsizei(m_camera.m_width), GLsizei(m_camera.m_height)); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (m_settings.pause) { - m_debugDraw.DrawString(b3Color_white, "*PAUSED*"); + m_draw.DrawString(b3Color_white, "*PAUSED*"); } else { - m_debugDraw.DrawString(b3Color_white, "*PLAYING*"); + m_draw.DrawString(b3Color_white, "*PLAYING*"); } if (m_settings.drawGrid) @@ -84,7 +91,7 @@ void Model::Command_Step() b3Vec3 pn(0.0f, 1.0f, 0.0f); b3Vec3 p(0.0f, 0.0f, 0.0f); - m_debugDraw.DrawCircle(pn, p, 1.0f, color); + m_draw.DrawCircle(pn, p, 1.0f, color); int n = 20; @@ -108,13 +115,13 @@ void Model::Command_Step() vs[2] += t; vs[3] += t; - m_debugDraw.DrawPolygon(vs, 4, color); + m_draw.DrawPolygon(vs, 4, color); } } } // - m_settings.inv_hertz = m_settings.hertz != 0.0f ? 1.0f / m_settings.hertz : 0.0f; + m_testSettings.inv_hertz = m_testSettings.hertz != 0.0f ? 1.0f / m_testSettings.hertz : 0.0f; if (m_settings.pause) { @@ -124,25 +131,11 @@ void Model::Command_Step() } else { - m_settings.inv_hertz = 0.0f; + m_testSettings.inv_hertz = 0.0f; } } - m_profiler.Begin(); - m_test->Step(); - m_profiler.End(g_profilerListener); - - if (m_settings.drawProfile) - { - const b3Array& records = m_profilerListener.m_recorderProfiler.GetRecords(); - for (u32 i = 0; i < records.Count(); ++i) - { - const ProfilerRecord& r = records[i]; - m_debugDraw.DrawString(b3Color_white, "%s %.4f (%.4f) [ms]", r.name, r.elapsed, r.maxElapsed); - } - } - - m_debugDraw.Submit(); + m_draw.Flush(); } \ No newline at end of file diff --git a/examples/testbed/framework/model.h b/examples/testbed/framework/model.h index 1675f03..18506bb 100644 --- a/examples/testbed/framework/model.h +++ b/examples/testbed/framework/model.h @@ -19,10 +19,43 @@ #ifndef MODEL_H #define MODEL_H -#include +#include #include #include +struct Settings +{ + Settings() + { + lastTestID = -1; + testID = 0; + pause = false; + singleStep = false; + drawPoints = true; + drawLines = true; + drawTriangles = true; + drawGrid = true; + drawProfile = false; + drawStats = false; + } + + int lastTestID; + int testID; + + bool pause; + bool singleStep; + + bool drawPoints; + bool drawLines; + bool drawTriangles; + bool drawGrid; + bool drawProfile; + bool drawStats; +}; + +// +extern Settings* g_settings; + class Model { public: @@ -62,12 +95,15 @@ private: friend class View; friend class Controller; - DebugDraw m_debugDraw; + // UI State + Settings m_settings; + TestSettings m_testSettings; + + // App State + Draw m_draw; Camera m_camera; Profiler m_profiler; TestbedListener m_profilerListener; - - Settings m_settings; Test* m_test; }; diff --git a/examples/testbed/framework/recorder_profiler.cpp b/examples/testbed/framework/recorder_profiler.cpp index 0327635..8b126cb 100644 --- a/examples/testbed/framework/recorder_profiler.cpp +++ b/examples/testbed/framework/recorder_profiler.cpp @@ -18,6 +18,8 @@ #include +RecorderProfiler* g_profilerRecorder = nullptr; + void RecorderProfiler::BeginEvents() { for (u32 i = 0; i < m_records.Count(); ++i) diff --git a/examples/testbed/framework/recorder_profiler.h b/examples/testbed/framework/recorder_profiler.h index 2f822f6..5291901 100644 --- a/examples/testbed/framework/recorder_profiler.h +++ b/examples/testbed/framework/recorder_profiler.h @@ -47,4 +47,6 @@ private: b3StackArray m_records; }; +extern RecorderProfiler* g_profilerRecorder; + #endif \ No newline at end of file diff --git a/examples/testbed/framework/test.cpp b/examples/testbed/framework/test.cpp index 2b37e70..ba892ca 100644 --- a/examples/testbed/framework/test.cpp +++ b/examples/testbed/framework/test.cpp @@ -17,6 +17,7 @@ */ #include +#include extern u32 b3_allocCalls, b3_maxAllocCalls; extern u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters; @@ -34,22 +35,24 @@ void b3PopProfileScope() } Settings* g_settings = nullptr; +TestSettings* g_testSettings = nullptr; -Test::Test() +Test::Test() : m_bodyDragger(&m_bodyRay, &m_world) { b3_allocCalls = 0; b3_gjkCalls = 0; b3_gjkIters = 0; b3_gjkMaxIters = 0; - b3_convexCache = g_settings->convexCache; + b3_convexCache = g_testSettings->convexCache; b3_convexCalls = 0; b3_convexCacheHits = 0; - b3Draw_draw = g_debugDraw; + b3Draw_draw = g_draw; m_world.SetContactListener(this); - m_rayHit.shape = NULL; - m_mouseJoint = NULL; + m_bodyRay.origin.SetZero(); + m_bodyRay.direction.Set(0.0f, 0.0f, -1.0f); + m_bodyRay.fraction = g_camera->m_zFar; m_groundHull.Set(50.0f, 1.0f, 50.0f); m_groundMesh.BuildTree(); @@ -73,57 +76,44 @@ void Test::Step() b3_gjkCalls = 0; b3_gjkIters = 0; b3_gjkMaxIters = 0; - b3_convexCache = g_settings->convexCache; + b3_convexCache = g_testSettings->convexCache; b3_convexCalls = 0; b3_convexCacheHits = 0; - float32 dt = g_settings->inv_hertz; - // Step - m_world.SetSleeping(g_settings->sleep); - m_world.SetWarmStart(g_settings->warmStart); - m_world.Step(dt, g_settings->velocityIterations, g_settings->positionIterations); + float32 dt = g_testSettings->inv_hertz; - g_debugDraw->Submit(); + m_world.SetSleeping(g_testSettings->sleep); + m_world.SetWarmStart(g_testSettings->warmStart); + m_world.Step(dt, g_testSettings->velocityIterations, g_testSettings->positionIterations); - // Draw World + // Draw u32 drawFlags = 0; - drawFlags += g_settings->drawBounds * b3Draw::e_aabbsFlag; - drawFlags += g_settings->drawVerticesEdges * b3Draw::e_shapesFlag; - drawFlags += g_settings->drawCenterOfMasses * b3Draw::e_centerOfMassesFlag; - drawFlags += g_settings->drawJoints * b3Draw::e_jointsFlag; - drawFlags += g_settings->drawContactPoints * b3Draw::e_contactPointsFlag; - drawFlags += g_settings->drawContactNormals * b3Draw::e_contactNormalsFlag; - drawFlags += g_settings->drawContactTangents * b3Draw::e_contactTangentsFlag; - drawFlags += g_settings->drawContactPolygons * b3Draw::e_contactPolygonsFlag; + drawFlags += g_testSettings->drawBounds * b3Draw::e_aabbsFlag; + drawFlags += g_testSettings->drawShapes * b3Draw::e_shapesFlag; + drawFlags += g_testSettings->drawCenterOfMasses * b3Draw::e_centerOfMassesFlag; + drawFlags += g_testSettings->drawJoints * b3Draw::e_jointsFlag; + drawFlags += g_testSettings->drawContactPoints * b3Draw::e_contactPointsFlag; + drawFlags += g_testSettings->drawContactNormals * b3Draw::e_contactNormalsFlag; + drawFlags += g_testSettings->drawContactTangents * b3Draw::e_contactTangentsFlag; + drawFlags += g_testSettings->drawContactPolygons * b3Draw::e_contactPolygonsFlag; - g_debugDraw->SetFlags(drawFlags); + g_draw->SetFlags(drawFlags); m_world.Draw(); - - if (m_mouseJoint) - { - b3Shape* shape = m_rayHit.shape; - b3Body* body = shape->GetBody(); - b3Vec3 n = body->GetWorldVector(m_rayHit.normal); - b3Vec3 p = body->GetWorldPoint(m_rayHit.point); - - g_debugDraw->DrawSolidCircle(n, p + 0.05f * n, 1.0f, b3Color_white); - } + g_draw->Flush(); - g_debugDraw->Submit(); - - if (g_settings->drawFaces) + if (g_settings->drawTriangles) { - g_debugDraw->Draw(m_world); + g_draw->DrawSolidShapes(m_world); } if (g_settings->drawStats) { - g_debugDraw->DrawString(b3Color_white, "Bodies %d", m_world.GetBodyList().m_count); - g_debugDraw->DrawString(b3Color_white, "Joints %d", m_world.GetJointList().m_count); - g_debugDraw->DrawString(b3Color_white, "Contacts %d", m_world.GetContactList().m_count); + g_draw->DrawString(b3Color_white, "Bodies %d", m_world.GetBodyList().m_count); + g_draw->DrawString(b3Color_white, "Joints %d", m_world.GetJointList().m_count); + g_draw->DrawString(b3Color_white, "Contacts %d", m_world.GetContactList().m_count); float32 avgGjkIters = 0.0f; if (b3_gjkCalls > 0) @@ -131,8 +121,8 @@ void Test::Step() avgGjkIters = float32(b3_gjkIters) / float32(b3_gjkCalls); } - g_debugDraw->DrawString(b3Color_white, "GJK Calls %d", b3_gjkCalls); - g_debugDraw->DrawString(b3Color_white, "GJK Iterations %d (%d) (%f)", b3_gjkIters, b3_gjkMaxIters, avgGjkIters); + g_draw->DrawString(b3Color_white, "GJK Calls %d", b3_gjkCalls); + g_draw->DrawString(b3Color_white, "GJK Iterations %d (%d) (%f)", b3_gjkIters, b3_gjkMaxIters, avgGjkIters); float32 convexCacheHitRatio = 0.0f; if (b3_convexCalls > 0) @@ -140,84 +130,39 @@ void Test::Step() convexCacheHitRatio = float32(b3_convexCacheHits) / float32(b3_convexCalls); } - g_debugDraw->DrawString(b3Color_white, "Convex Calls %d", b3_convexCalls); - g_debugDraw->DrawString(b3Color_white, "Convex Cache Hits %d (%f)", b3_convexCacheHits, convexCacheHitRatio); - g_debugDraw->DrawString(b3Color_white, "Frame Allocations %d (%d)", b3_allocCalls, b3_maxAllocCalls); + g_draw->DrawString(b3Color_white, "Convex Calls %d", b3_convexCalls); + g_draw->DrawString(b3Color_white, "Convex Cache Hits %d (%f)", b3_convexCacheHits, convexCacheHitRatio); + g_draw->DrawString(b3Color_white, "Frame Allocations %d (%d)", b3_allocCalls, b3_maxAllocCalls); } } void Test::MouseMove(const Ray3& pw) { - if (m_mouseJoint) - { - float32 t = m_rayHit.fraction; - float32 w1 = 1.0f - t; - float32 w2 = t; + m_bodyRay = pw; - b3Vec3 target = w1 * pw.A() + w2 * pw.B(); - m_mouseJoint->SetTarget(target); + if (m_bodyDragger.IsSelected() == true) + { + m_bodyDragger.Drag(); } } void Test::MouseLeftDown(const Ray3& pw) { - // Clear the current hit - m_rayHit.shape = NULL; - if (m_mouseJoint) + if (m_bodyDragger.IsSelected() == false) { - b3Body* groundBody = m_mouseJoint->GetBodyA(); - - m_world.DestroyJoint(m_mouseJoint); - m_mouseJoint = NULL; - - m_world.DestroyBody(groundBody); - } - - // Perform the ray cast - b3Vec3 p1 = pw.A(); - b3Vec3 p2 = pw.B(); - - b3RayCastSingleOutput out; - if (m_world.RayCastSingle(&out, p1, p2)) - { - b3Shape* shape = out.shape; - b3Body* body = shape->GetBody(); - - m_rayHit.shape = out.shape; - m_rayHit.point = body->GetLocalPoint(out.point); - m_rayHit.normal = body->GetLocalVector(out.normal); - m_rayHit.fraction = out.fraction; - - RayHit(); + if (m_bodyDragger.StartDragging() == true) + { + BeginDragging(); + } } } void Test::MouseLeftUp(const Ray3& pw) { - m_rayHit.shape = NULL; - if (m_mouseJoint) + if (m_bodyDragger.IsSelected() == true) { - b3Body* groundBody = m_mouseJoint->GetBodyA(); - - m_world.DestroyJoint(m_mouseJoint); - m_mouseJoint = NULL; - - m_world.DestroyBody(groundBody); + m_bodyDragger.StopDragging(); + + EndDragging(); } -} - -void Test::RayHit() -{ - b3BodyDef bdef; - b3Body* bodyA = m_world.CreateBody(bdef); - b3Body* bodyB = m_rayHit.shape->GetBody(); - - b3MouseJointDef def; - def.bodyA = bodyA; - def.bodyB = bodyB; - def.target = bodyB->GetWorldPoint(m_rayHit.point); - def.maxForce = 2000.0f * bodyB->GetMass(); - - m_mouseJoint = (b3MouseJoint*)m_world.CreateJoint(def); - bodyB->SetAwake(true); -} +} \ No newline at end of file diff --git a/examples/testbed/framework/test.h b/examples/testbed/framework/test.h index 17f7cb0..d945f01 100644 --- a/examples/testbed/framework/test.h +++ b/examples/testbed/framework/test.h @@ -24,7 +24,7 @@ #include -#include +#include #include #include @@ -36,10 +36,9 @@ inline float32 RandomFloat(float32 a, float32 b) return a + r; } -// Test settings -struct Settings +struct TestSettings { - Settings() + TestSettings() { hertz = 60.0f; inv_hertz = 1.0f / hertz; @@ -48,52 +47,34 @@ struct Settings sleep = false; warmStart = true; convexCache = true; - drawCenterOfMasses = false; - drawVerticesEdges = true; - drawFaces = true; + drawCenterOfMasses = true; + drawShapes = true; drawBounds = false; drawJoints = true; drawContactPoints = true; drawContactNormals = false; drawContactTangents = false; drawContactPolygons = false; - drawStats = false; - drawProfile = false; - drawGrid = true; - pause = false; - singleStep = false; - lastTestID = -1; - testID = 0; } - int lastTestID; - int testID; - bool pause; - bool singleStep; - - float32 hertz, inv_hertz; + float hertz, inv_hertz; int velocityIterations; int positionIterations; bool sleep; bool warmStart; bool convexCache; - + bool drawCenterOfMasses; bool drawBounds; - bool drawVerticesEdges; - bool drawFaces; - bool drawSolidShapes; + bool drawShapes; bool drawJoints; bool drawContactPoints; bool drawContactNormals; bool drawContactTangents; bool drawContactPolygons; - bool drawStats; - bool drawProfile; - bool drawGrid; }; -extern Settings* g_settings; +extern TestSettings* g_testSettings; class RayCastListener : public b3RayCastListener { @@ -110,6 +91,110 @@ public: b3RayCastSingleOutput hit; }; +class BodyDragger +{ +public: + BodyDragger(Ray3* ray, b3World* world) + { + m_ray = ray; + m_world = world; + m_shape = nullptr; + m_mouseJoint = nullptr; + } + + ~BodyDragger() + { + + } + + bool StartDragging() + { + B3_ASSERT(m_mouseJoint == nullptr); + + b3RayCastSingleOutput out; + if (m_world->RayCastSingle(&out, m_ray->A(), m_ray->B()) == false) + { + return false; + } + + m_x = out.fraction; + m_shape = out.shape; + + b3BodyDef bd; + b3Body* groundBody = m_world->CreateBody(bd); + + b3Body* body = m_shape->GetBody(); + body->SetAwake(true); + + b3MouseJointDef jd; + jd.bodyA = groundBody; + jd.bodyB = body; + jd.target = out.point; + jd.maxForce = 2000.0f * body->GetMass(); + + m_mouseJoint = (b3MouseJoint*)m_world->CreateJoint(jd); + + m_p = body->GetLocalPoint(out.point); + + return true; + } + + void Drag() + { + B3_ASSERT(m_mouseJoint); + m_mouseJoint->SetTarget(GetPointB()); + } + + void StopDragging() + { + B3_ASSERT(m_mouseJoint); + + b3Body* groundBody = m_mouseJoint->GetBodyA(); + m_world->DestroyJoint(m_mouseJoint); + m_mouseJoint = nullptr; + m_world->DestroyBody(groundBody); + m_shape = nullptr; + } + + bool IsSelected() const + { + return m_mouseJoint != nullptr; + } + + + Ray3* GetRay() const + { + return m_ray; + } + + b3Body* GetBody() const + { + B3_ASSERT(m_shape); + return m_shape->GetBody(); + } + + b3Vec3 GetPointA() const + { + B3_ASSERT(m_shape); + return m_shape->GetBody()->GetWorldPoint(m_p); + } + + b3Vec3 GetPointB() const + { + B3_ASSERT(m_mouseJoint); + return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B(); + } + +private: + Ray3* m_ray; + float32 m_x; + + b3World* m_world; + b3Shape* m_shape; + b3Vec3 m_p; + b3MouseJoint* m_mouseJoint; +}; + class Test : public b3ContactListener { public: @@ -120,21 +205,23 @@ public: virtual void Step(); - virtual void RayHit(); - virtual void MouseMove(const Ray3& pw); virtual void MouseLeftDown(const Ray3& pw); virtual void MouseLeftUp(const Ray3& pw); virtual void KeyDown(int button) { } virtual void KeyUp(int button) { } - virtual void BeginContact(b3Contact* contact) { } - virtual void EndContact(b3Contact* contact) { } - virtual void PreSolve(b3Contact* contact) { } + virtual void BeginDragging() { } + virtual void EndDragging() { } + + void BeginContact(b3Contact* c) override { } + void EndContact(b3Contact* c) override { } + void PreSolve(b3Contact* c) override { } b3World m_world; - b3RayCastSingleOutput m_rayHit; - b3MouseJoint* m_mouseJoint; + + Ray3 m_bodyRay; + BodyDragger m_bodyDragger; b3BoxHull m_groundHull; b3GridMesh<50, 50> m_groundMesh; diff --git a/examples/testbed/framework/test_entries.cpp b/examples/testbed/framework/test_entries.cpp index 81722c1..b87e870 100644 --- a/examples/testbed/framework/test_entries.cpp +++ b/examples/testbed/framework/test_entries.cpp @@ -28,11 +28,11 @@ #include #include #include +#include #include #include #include -#include -#include +#include #include #include #include @@ -44,14 +44,14 @@ #include #include #include +#include #include #include -#include #include #include #include #include -#include +#include #include #include #include @@ -78,12 +78,12 @@ TestEntry g_tests[] = { "Hull Collision (1)", &HullAndHull::Create }, { "Hull Collision (2)", &HullAndHull2::Create }, { "Capsule and Hull Contact (1)", &CapsuleAndHullContact1::Create }, + { "Mesh Contact Test", &MeshContactTest::Create }, { "Linear Motion", &LinearMotion::Create }, { "Angular Motion", &AngularMotion::Create }, - { "Multiple Shapes", &MultipleShapes::Create }, + { "Gyroscopic Motion", &GyroMotion::Create }, + { "Compound Body", &CompoundBody::Create }, { "Quadric Shapes", &QuadricShapes::Create }, - { "Thin Boxes", &Thin::Create }, - { "Gyroscopic Test", &GyroTest::Create }, { "Springs", &Spring::Create }, { "Weld Test", &WeldTest::Create }, { "Cone Test", &ConeTest::Create }, @@ -91,17 +91,17 @@ TestEntry g_tests[] = { "Hinge Chain", &HingeChain::Create }, { "Ragdoll", &Ragdoll::Create }, { "Newton's Cradle", &NewtonCradle::Create }, - { "Mesh Contact Test", &MeshContactTest::Create }, { "Sphere Stack", &SphereStack::Create }, { "Capsule Stack", &CapsuleStack::Create }, { "Box Stack", &BoxStack::Create }, + { "Sheet Stack", &SheetStack::Create }, { "Shape Stack", &ShapeStack::Create }, { "Jenga", &Jenga::Create }, { "Box Pyramid", &Pyramid::Create }, { "Box Pyramid Rows", &Pyramids::Create }, { "Ray Cast", &RayCast::Create }, { "Sensor Test", &SensorTest::Create }, - { "Character Test", &Character::Create }, + { "Point & Click", &PointClick::Create }, { "Body Types", &BodyTypes::Create }, { "Varying Friction", &VaryingFriction::Create }, { "Varying Restitution", &VaryingRestitution::Create }, diff --git a/examples/testbed/framework/view.cpp b/examples/testbed/framework/view.cpp index 5caa370..896e380 100644 --- a/examples/testbed/framework/view.cpp +++ b/examples/testbed/framework/view.cpp @@ -24,7 +24,6 @@ #elif defined (U_OPENGL_4) #include #else - #endif static bool GetTestName(void* userData, int idx, const char** name) @@ -147,6 +146,7 @@ void View::Command_Draw() { Camera& camera = m_model->m_camera; Settings& settings = m_model->m_settings; + TestSettings& testSettings = m_model->m_testSettings; bool openAbout = false; if (ImGui::BeginMainMenuBar()) @@ -170,24 +170,29 @@ void View::Command_Draw() if (ImGui::BeginMenu("View")) { - ImGui::MenuItem("Reference Grid", "", &settings.drawGrid); - ImGui::MenuItem("Vertices and Edges", "", &settings.drawVerticesEdges); - ImGui::MenuItem("Faces", "", &settings.drawFaces); - - ImGui::Separator(); - - ImGui::MenuItem("Center of Masses", "", &settings.drawCenterOfMasses); - ImGui::MenuItem("Bounding Boxes", "", &settings.drawBounds); - ImGui::MenuItem("Joints", "", &settings.drawJoints); - ImGui::MenuItem("Contact Points", "", &settings.drawContactPoints); - ImGui::MenuItem("Contact Normals", "", &settings.drawContactNormals); - ImGui::MenuItem("Contact Tangents", "", &settings.drawContactTangents); - ImGui::MenuItem("Contact Polygons", "", &settings.drawContactPolygons); - - ImGui::Separator(); - - ImGui::MenuItem("Statistics", "", &settings.drawStats); ImGui::MenuItem("Profile", "", &settings.drawProfile); + ImGui::MenuItem("Statistics", "", &settings.drawStats); + + ImGui::Separator(); + + ImGui::MenuItem("Points", "", &settings.drawPoints); + ImGui::MenuItem("Lines", "", &settings.drawLines); + ImGui::MenuItem("Triangles", "", &settings.drawTriangles); + + ImGui::Separator(); + + ImGui::MenuItem("Reference Grid", "", &settings.drawGrid); + + ImGui::Separator(); + + ImGui::MenuItem("Center of Masses", "", &testSettings.drawCenterOfMasses); + ImGui::MenuItem("Bounding Boxes", "", &testSettings.drawBounds); + ImGui::MenuItem("Shapes", "", &testSettings.drawShapes); + ImGui::MenuItem("Joints", "", &testSettings.drawJoints); + ImGui::MenuItem("Contact Points", "", &testSettings.drawContactPoints); + ImGui::MenuItem("Contact Normals", "", &testSettings.drawContactNormals); + ImGui::MenuItem("Contact Tangents", "", &testSettings.drawContactTangents); + ImGui::MenuItem("Contact Polygons", "", &testSettings.drawContactPolygons); ImGui::EndMenu(); } @@ -307,17 +312,17 @@ void View::Command_Draw() ImGui::PushItemWidth(-1.0f); ImGui::Text("Hertz"); - ImGui::SliderFloat("##Hertz", &settings.hertz, 0.0f, 240.0f, "%.1f"); + ImGui::SliderFloat("##Hertz", &testSettings.hertz, 0.0f, 240.0f, "%.1f"); ImGui::Text("Velocity Iterations"); - ImGui::SliderInt("##Velocity Iterations", &settings.velocityIterations, 0, 50); + ImGui::SliderInt("##Velocity Iterations", &testSettings.velocityIterations, 0, 50); ImGui::Text("Position Iterations"); - ImGui::SliderInt("##Position Iterations", &settings.positionIterations, 0, 50); + ImGui::SliderInt("##Position Iterations", &testSettings.positionIterations, 0, 50); - ImGui::Checkbox("Sleep", &settings.sleep); - ImGui::Checkbox("Convex Cache", &settings.convexCache); - ImGui::Checkbox("Warm Start", &settings.warmStart); + ImGui::Checkbox("Sleep", &testSettings.sleep); + ImGui::Checkbox("Convex Cache", &testSettings.convexCache); + ImGui::Checkbox("Warm Start", &testSettings.warmStart); ImGui::PopItemWidth(); diff --git a/examples/testbed/tests/body_types.h b/examples/testbed/tests/body_types.h index c41efed..ab3449a 100644 --- a/examples/testbed/tests/body_types.h +++ b/examples/testbed/tests/body_types.h @@ -64,11 +64,11 @@ public: { Test::Step(); - g_debugDraw->DrawString(b3Color_white, "S - Static"); - g_debugDraw->DrawString(b3Color_white, "D - Dynamic"); - g_debugDraw->DrawString(b3Color_white, "K - Kinematic"); - g_debugDraw->DrawString(b3Color_white, "Space - Throw Bomb"); - g_debugDraw->DrawString(b3Color_white, "Arrows - Apply Force/Velocity/Position"); + g_draw->DrawString(b3Color_white, "S - Static"); + g_draw->DrawString(b3Color_white, "D - Dynamic"); + g_draw->DrawString(b3Color_white, "K - Kinematic"); + g_draw->DrawString(b3Color_white, "Space - Throw Bomb"); + g_draw->DrawString(b3Color_white, "Arrows - Apply Force/Velocity/Position"); } void KeyDown(int button) diff --git a/examples/testbed/tests/cloth_test.h b/examples/testbed/tests/cloth_test.h index 32d29a5..f96afc3 100644 --- a/examples/testbed/tests/cloth_test.h +++ b/examples/testbed/tests/cloth_test.h @@ -51,7 +51,7 @@ public: void Step() { - m_cloth.Step(g_settings->inv_hertz, g_settings->positionIterations); + m_cloth.Step(g_testSettings->inv_hertz, g_testSettings->positionIterations); m_cloth.Draw(); } diff --git a/examples/testbed/tests/cluster_test.h b/examples/testbed/tests/cluster_test.h index 2dc305e..5829e2e 100644 --- a/examples/testbed/tests/cluster_test.h +++ b/examples/testbed/tests/cluster_test.h @@ -61,15 +61,15 @@ public: for (u32 i = 0; i < clusters.Count(); ++i) { - g_debugDraw->DrawSegment(b3Vec3(0, 0, 0), clusters[i].centroid, b3Color(1, 1, 1)); - g_debugDraw->DrawPoint(clusters[i].centroid, 4.0f, m_colors[i]); + g_draw->DrawSegment(b3Vec3(0, 0, 0), clusters[i].centroid, b3Color(1, 1, 1)); + g_draw->DrawPoint(clusters[i].centroid, 4.0f, m_colors[i]); for (u32 j = 0; j < observations.Count(); ++j) { b3Observation obs = observations[j]; if (obs.cluster == i) { - g_debugDraw->DrawPoint(obs.point, 4.0f, m_colors[i]); + g_draw->DrawPoint(obs.point, 4.0f, m_colors[i]); } } } diff --git a/examples/testbed/tests/collide_test.h b/examples/testbed/tests/collide_test.h index 78e5cd8..4509430 100644 --- a/examples/testbed/tests/collide_test.h +++ b/examples/testbed/tests/collide_test.h @@ -46,21 +46,15 @@ public: b3Vec3 pw = wm.points[i].point; b3Vec2 ps = g_camera->ConvertWorldToScreen(pw); - g_debugDraw->DrawPoint(pw, 4.0f, b3Color(0.0f, 1.0f, 0.0f)); - g_debugDraw->DrawSegment(pw, pw + wm.points[i].normal, b3Color(1.0f, 1.0f, 1.0f)); + g_draw->DrawPoint(pw, 4.0f, b3Color(0.0f, 1.0f, 0.0f)); + g_draw->DrawSegment(pw, pw + wm.points[i].normal, b3Color(1.0f, 1.0f, 1.0f)); } - if (g_settings->drawFaces) - { - g_debugDraw->DrawShape(m_shapeA, b3Color(1.0f, 1.0f, 1.0f, 0.5f), m_xfA); - g_debugDraw->DrawShape(m_shapeB, b3Color(1.0f, 1.0f, 1.0f, 0.5f), m_xfB); - } - - if (g_settings->drawVerticesEdges) - { - m_world.DrawShape(m_xfA, m_shapeA); - m_world.DrawShape(m_xfB, m_shapeB); - } + g_draw->DrawSolidShape(m_shapeA, b3Color(1.0f, 1.0f, 1.0f, 0.5f), m_xfA); + g_draw->DrawSolidShape(m_shapeB, b3Color(1.0f, 1.0f, 1.0f, 0.5f), m_xfB); + + m_world.DrawShape(m_xfA, m_shapeA); + m_world.DrawShape(m_xfB, m_shapeB); } virtual void KeyDown(int key) diff --git a/examples/testbed/tests/multiple_shapes.h b/examples/testbed/tests/compound_body.h similarity index 92% rename from examples/testbed/tests/multiple_shapes.h rename to examples/testbed/tests/compound_body.h index f0fa841..0445d03 100644 --- a/examples/testbed/tests/multiple_shapes.h +++ b/examples/testbed/tests/compound_body.h @@ -16,13 +16,13 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef MULTIPLE_SHAPES_H -#define MULTIPLE_SHAPES_H +#ifndef COMPOUND_BODY_H +#define COMPOUND_BODY_H -class MultipleShapes : public Test +class CompoundBody : public Test { public: - MultipleShapes() + CompoundBody() { { b3BodyDef bd; @@ -76,7 +76,7 @@ public: b3BodyDef bd; bd.type = e_dynamicBody; bd.position.Set(0.0f, 0.0f, 0.0f); - bd.angularVelocity.Set(0.0f, 200.0f * B3_PI, 0.0f); + bd.angularVelocity.Set(0.0f, 2.0f * B3_PI, 0.0f); b3Body* body = m_world.CreateBody(bd); @@ -105,7 +105,7 @@ public: static Test* Create() { - return new MultipleShapes(); + return new CompoundBody(); } b3BoxHull m_box1; diff --git a/examples/testbed/tests/distance_test.h b/examples/testbed/tests/distance_test.h index d5c4464..a8ed592 100644 --- a/examples/testbed/tests/distance_test.h +++ b/examples/testbed/tests/distance_test.h @@ -51,22 +51,22 @@ public: for (u32 i = 0; i < featurePair.count1; ++i) { u32 index = featurePair.index1[i]; - g_debugDraw->DrawPoint(m_xfA * m_proxyA.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f)); + g_draw->DrawPoint(m_xfA * m_proxyA.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f)); } for (u32 i = 0; i < featurePair.count2; ++i) { u32 index = featurePair.index2[i]; - g_debugDraw->DrawPoint(m_xfB * m_proxyB.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f)); + g_draw->DrawPoint(m_xfB * m_proxyB.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f)); } } - g_debugDraw->DrawPoint(out.point1, 4.0f, b3Color(0.0f, 1.0f, 0.0f)); - g_debugDraw->DrawPoint(out.point2, 4.0f, b3Color(0.0f, 1.0f, 0.0f)); - g_debugDraw->DrawSegment(out.point1, out.point2, b3Color(1.0f, 1.0f, 1.0f)); + g_draw->DrawPoint(out.point1, 4.0f, b3Color(0.0f, 1.0f, 0.0f)); + g_draw->DrawPoint(out.point2, 4.0f, b3Color(0.0f, 1.0f, 0.0f)); + g_draw->DrawSegment(out.point1, out.point2, b3Color(1.0f, 1.0f, 1.0f)); - g_debugDraw->DrawTransform(m_xfA); - g_debugDraw->DrawTransform(m_xfB); + g_draw->DrawTransform(m_xfA); + g_draw->DrawTransform(m_xfB); m_world.DrawShape(m_xfA, &m_shapeA); m_world.DrawShape(m_xfB, &m_shapeB); diff --git a/examples/testbed/tests/gyro_test.h b/examples/testbed/tests/gyro_motion.h similarity index 90% rename from examples/testbed/tests/gyro_test.h rename to examples/testbed/tests/gyro_motion.h index 2dee7a1..aebc21b 100644 --- a/examples/testbed/tests/gyro_test.h +++ b/examples/testbed/tests/gyro_motion.h @@ -16,15 +16,15 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef GYRO_TEST_H -#define GYRO_TEST_H +#ifndef GYRO_MOTION_H +#define GYRO_MOTION_H #include -class GyroTest : public Test +class GyroMotion : public Test { public: - GyroTest() + GyroMotion() { { b3StackArray points; @@ -63,10 +63,7 @@ public: b3Body* body = m_world.CreateBody(bdef); { - b3Transform xf; - xf.position.SetZero(); - xf.rotation = b3Diagonal(1.0f, 0.5f, 7.0f); - m_rotorBox.SetTransform(xf); + m_rotorBox.Set(1.0f, 0.5f, 7.0f); b3HullShape hull; hull.m_hull = &m_rotorBox; @@ -93,7 +90,7 @@ public: m_world.SetGravity(b3Vec3(0.0f, 0.0f, 0.0f)); } - ~GyroTest() + ~GyroMotion() { { b3Free(m_cylinderHull.vertices); @@ -105,7 +102,7 @@ public: static Test* Create() { - return new GyroTest(); + return new GyroMotion(); } b3BoxHull m_rotorBox; diff --git a/examples/testbed/tests/mass_spring.h b/examples/testbed/tests/mass_spring.h index 8c23b92..4c10924 100644 --- a/examples/testbed/tests/mass_spring.h +++ b/examples/testbed/tests/mass_spring.h @@ -126,18 +126,18 @@ public: void Step() { - float32 h = g_settings->inv_hertz; + float32 h = g_testSettings->inv_hertz; Solve(h); - g_debugDraw->DrawSolidSphere(m_x, 0.25f, b3Color_white); + g_draw->DrawSolidSphere(m_x, 0.25f, b3Color_white); - g_debugDraw->DrawSegment(b3Vec3_zero, m_x, b3Color_white); + g_draw->DrawSegment(b3Vec3_zero, m_x, b3Color_white); - g_debugDraw->DrawString(b3Color_white, "Iterations = %u", m_iterations); + g_draw->DrawString(b3Color_white, "Iterations = %u", m_iterations); float32 E = 0.5f * b3Dot(m_v, m_v); - g_debugDraw->DrawString(b3Color_white, "E = %f", E); + g_draw->DrawString(b3Color_white, "E = %f", E); } static Test* Create() diff --git a/examples/testbed/tests/mesh_contact_test.h b/examples/testbed/tests/mesh_contact_test.h index 173d739..d81f05f 100644 --- a/examples/testbed/tests/mesh_contact_test.h +++ b/examples/testbed/tests/mesh_contact_test.h @@ -163,11 +163,11 @@ public: { Test::Step(); - g_debugDraw->DrawString(b3Color_white, "S - Sphere"); - g_debugDraw->DrawString(b3Color_white, "C - Capsule"); - g_debugDraw->DrawString(b3Color_white, "H - Hull"); - g_debugDraw->DrawString(b3Color_white, "G - Grid"); - g_debugDraw->DrawString(b3Color_white, "T - Terrain"); + g_draw->DrawString(b3Color_white, "S - Sphere"); + g_draw->DrawString(b3Color_white, "C - Capsule"); + g_draw->DrawString(b3Color_white, "H - Hull"); + g_draw->DrawString(b3Color_white, "G - Grid"); + g_draw->DrawString(b3Color_white, "T - Terrain"); } static Test* Create() diff --git a/examples/testbed/tests/character_test.h b/examples/testbed/tests/point_click.h similarity index 75% rename from examples/testbed/tests/character_test.h rename to examples/testbed/tests/point_click.h index 4132825..3c24366 100644 --- a/examples/testbed/tests/character_test.h +++ b/examples/testbed/tests/point_click.h @@ -16,13 +16,13 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef CHARACTER_H -#define CHARACTER_H +#ifndef POINT_CLICK_H +#define POINT_CLICK_H -class Character : public Test +class PointClick : public Test { public: - Character() + PointClick() { { b3BodyDef bdef; @@ -59,31 +59,28 @@ public: } } - void RayHit() + void BeginDragging() { - if (m_rayHit.shape) + if (m_bodyDragger.GetBody() == m_character) { - if (m_rayHit.shape->GetBody() != m_character) - { - Test::RayHit(); - } + m_bodyDragger.StopDragging(); } } void Step() { - if (m_rayHit.shape) + if (m_bodyDragger.IsSelected()) { - if (m_rayHit.shape->GetBody() != m_character) + if (m_bodyDragger.GetBody() != m_character) { - b3Vec3 point = m_rayHit.point; - b3Vec3 normal = m_rayHit.normal; - - const b3Transform& xf = m_character->GetTransform(); - b3Vec3 n = point - xf.position; - n.Normalize(); + b3Vec3 p1 = m_character->GetPosition(); + b3Vec3 p2 = m_bodyDragger.GetPointA(); - m_character->ApplyForceToCenter(1000.0f * n, true); + b3Vec3 n = b3Normalize(p2 - p1); + const float32 k = 1000.0f; + b3Vec3 f = k * n; + + m_character->ApplyForceToCenter(f, true); } } @@ -92,10 +89,10 @@ public: static Test* Create() { - return new Character(); + return new PointClick(); } b3Body* m_character; }; -#endif +#endif \ No newline at end of file diff --git a/examples/testbed/tests/quickhull_test.h b/examples/testbed/tests/quickhull_test.h index 844484f..4292591 100644 --- a/examples/testbed/tests/quickhull_test.h +++ b/examples/testbed/tests/quickhull_test.h @@ -317,7 +317,7 @@ public: void Step() { - m_qhull.Draw(g_debugDraw); + m_qhull.Draw(g_draw); } static Test* Create() diff --git a/examples/testbed/tests/ray_cast.h b/examples/testbed/tests/ray_cast.h index 0e38f97..610627f 100644 --- a/examples/testbed/tests/ray_cast.h +++ b/examples/testbed/tests/ray_cast.h @@ -181,22 +181,20 @@ public: b3RayCastSingleOutput out; if (m_world.RayCastSingle(&out, p1, p2)) { - g_debugDraw->DrawSegment(p1, out.point, b3Color_green); + g_draw->DrawSegment(p1, out.point, b3Color_green); - g_debugDraw->DrawPoint(out.point, 4.0f, b3Color_red); - g_debugDraw->DrawSegment(out.point, out.point + out.normal, b3Color_white); - - g_debugDraw->DrawSolidCircle(out.normal, out.point + 0.025f * out.normal, 1.0f, b3Color_white); + g_draw->DrawPoint(out.point, 4.0f, b3Color_red); + g_draw->DrawSegment(out.point, out.point + out.normal, b3Color_white); } else { - g_debugDraw->DrawSegment(p1, p2, b3Color_green); + g_draw->DrawSegment(p1, p2, b3Color_green); } } void Step() { - float32 dt = g_settings->inv_hertz; + float32 dt = g_testSettings->inv_hertz; b3Quat dq = b3QuatRotationY(0.05f * B3_PI * dt); m_p1 = b3Mul(dq, m_p1); diff --git a/examples/testbed/tests/rope_test.h b/examples/testbed/tests/rope_test.h index 5e41bfe..de9252d 100644 --- a/examples/testbed/tests/rope_test.h +++ b/examples/testbed/tests/rope_test.h @@ -85,7 +85,7 @@ public: void Step() { - m_rope.Step(g_settings->inv_hertz); + m_rope.Step(g_testSettings->inv_hertz); m_rope.Draw(); } diff --git a/examples/testbed/tests/thin.h b/examples/testbed/tests/sheet_stack.h similarity index 78% rename from examples/testbed/tests/thin.h rename to examples/testbed/tests/sheet_stack.h index 88ddf5c..afdbba9 100644 --- a/examples/testbed/tests/thin.h +++ b/examples/testbed/tests/sheet_stack.h @@ -16,10 +16,10 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#ifndef THIN_H -#define THIN_H +#ifndef SHEET_STACK_H +#define SHEET_STACK_H -class Thin : public Test +class SheetStack : public Test { public: enum @@ -29,7 +29,7 @@ public: e_depthCount = 1 }; - Thin() + SheetStack() { { b3BodyDef bdef; @@ -47,22 +47,12 @@ public: b3Shape* shape = body->CreateShape(sdef); } - static b3BoxHull thinHull; - - { - b3Transform xf; - xf.position.SetZero(); - xf.rotation = b3Diagonal(4.05f, 2.0f * B3_LINEAR_SLOP, 4.05f); - - thinHull.SetTransform(xf); - } + static b3Vec3 sheetExtents(4.05f, 2.0f * B3_LINEAR_SLOP, 4.05f); + static b3BoxHull sheetHull(sheetExtents.x, sheetExtents.y, sheetExtents.z); b3Vec3 stackOrigin; stackOrigin.Set(0.0f, 4.05f, 0.0f); - b3Vec3 boxScale; - boxScale.Set(4.05f, 2.05f, 4.05f); - for (u32 i = 0; i < e_rowCount; ++i) { for (u32 j = 0; j < e_columnCount; ++j) @@ -72,15 +62,15 @@ public: b3BodyDef bdef; bdef.type = b3BodyType::e_dynamicBody; - bdef.position.x = float32(i) * boxScale.x; - bdef.position.y = 1.5f * float32(j) * boxScale.y; - bdef.position.z = float32(k) * boxScale.z; + bdef.position.x = float32(i) * sheetExtents.x; + bdef.position.y = float32(j) * 50.0f * sheetExtents.y; + bdef.position.z = float32(k) * sheetExtents.z; bdef.position += stackOrigin; b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &thinHull; + hs.m_hull = &sheetHull; b3ShapeDef sdef; sdef.shape = &hs; @@ -95,8 +85,8 @@ public: static Test* Create() { - return new Thin(); + return new SheetStack(); } }; -#endif +#endif \ No newline at end of file diff --git a/examples/testbed/tests/single_pendulum.h b/examples/testbed/tests/single_pendulum.h index f8b3b63..4746d3e 100644 --- a/examples/testbed/tests/single_pendulum.h +++ b/examples/testbed/tests/single_pendulum.h @@ -37,7 +37,7 @@ public: void Step() { - float32 h = g_settings->inv_hertz; + float32 h = g_testSettings->inv_hertz; // Solution (acceleration) float32 omega_dot = -m_g / m_r * sin(m_theta); @@ -53,11 +53,11 @@ public: c.x = m_r * sin(m_theta); c.y = m_r * cos(m_theta); c.z = 0.0f; - g_debugDraw->DrawSolidSphere(c, 1.0f, b3Color_white); + g_draw->DrawSolidSphere(c, 1.0f, b3Color_white); b3Vec3 pole; pole.SetZero(); - g_debugDraw->DrawSegment(pole, c, b3Color_white); + g_draw->DrawSegment(pole, c, b3Color_white); // Kinetic energy float32 T = 0.5f * m_I * m_omega * m_omega; @@ -69,7 +69,7 @@ public: float32 L = T - V; // - g_debugDraw->DrawString(b3Color_white, "T = %f \nV = %f \nL = %f", T, V, L); + g_draw->DrawString(b3Color_white, "T = %f \nV = %f \nL = %f", T, V, L); } static Test* Create() diff --git a/examples/testbed/tests/spring_cloth_test.h b/examples/testbed/tests/spring_cloth_test.h index e101908..3c20cdf 100644 --- a/examples/testbed/tests/spring_cloth_test.h +++ b/examples/testbed/tests/spring_cloth_test.h @@ -204,8 +204,6 @@ class SpringClothTest : public Test public: SpringClothTest() : m_clothDragger(&m_clothRay, &m_cloth) { - g_camera->m_zoom = 25.0f; - m_clothRay.origin.SetZero(); m_clothRay.direction.Set(0.0f, 0.0f, -1.0f); m_clothRay.fraction = g_camera->m_zFar; @@ -213,7 +211,7 @@ public: void Step() { - float32 dt = g_settings->inv_hertz; + float32 dt = g_testSettings->inv_hertz; m_cloth.Step(dt); m_cloth.Apply(); @@ -226,18 +224,18 @@ public: b3Transform xf; xf.SetIdentity(); - g_debugDraw->DrawShape(s, b3Color_white, xf); + g_draw->DrawSolidShape(s, b3Color_white, xf); } m_cloth.Draw(); b3SpringClothStep step = m_cloth.GetStep(); - g_debugDraw->DrawString(b3Color_white, "Iterations = %u", step.iterations); + g_draw->DrawString(b3Color_white, "Iterations = %u", step.iterations); if (m_clothDragger.IsSelected() == true) { - g_debugDraw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); + g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); } } diff --git a/examples/testbed/tests/tension_mapping.h b/examples/testbed/tests/tension_mapping.h index 19afa90..480f183 100644 --- a/examples/testbed/tests/tension_mapping.h +++ b/examples/testbed/tests/tension_mapping.h @@ -84,7 +84,7 @@ public: void Step() { - float32 dt = g_settings->inv_hertz; + float32 dt = g_testSettings->inv_hertz; m_cloth.Step(dt); m_cloth.Apply(); @@ -119,17 +119,17 @@ public: b3Vec3 n2 = -n1; - g_debugDraw->DrawSolidTriangle(n1, v1, c1, v2, c2, v3, c3); - g_debugDraw->DrawSolidTriangle(n2, v1, c1, v3, c3, v2, c2); + g_draw->DrawSolidTriangle(n1, v1, c1, v2, c2, v3, c3); + g_draw->DrawSolidTriangle(n2, v1, c1, v3, c3, v2, c2); } b3SpringClothStep step = m_cloth.GetStep(); - g_debugDraw->DrawString(b3Color_white, "Iterations = %u", step.iterations); + g_draw->DrawString(b3Color_white, "Iterations = %u", step.iterations); if (m_clothDragger.IsSelected() == true) { - g_debugDraw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); + g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white); } } diff --git a/premake5.lua b/premake5.lua index 1a626d2..ee9954a 100644 --- a/premake5.lua +++ b/premake5.lua @@ -261,7 +261,7 @@ solution (solution_name) files { - examples_inc_dir .. "/testbed/framework/debug_draw.h", + examples_inc_dir .. "/testbed/framework/draw.h", examples_inc_dir .. "/testbed/framework/profiler.h", examples_inc_dir .. "/testbed/framework/recorder_profiler.h", examples_inc_dir .. "/testbed/framework/json_profiler.h", @@ -275,6 +275,7 @@ solution (solution_name) examples_inc_dir .. "/testbed/tests/**.h", + examples_src_dir .. "/testbed/framework/draw.cpp", examples_src_dir .. "/testbed/framework/profiler.cpp", examples_src_dir .. "/testbed/framework/recorder_profiler.cpp", examples_src_dir .. "/testbed/framework/json_profiler.cpp", @@ -292,14 +293,14 @@ solution (solution_name) if is_gfxapi("opengl_2") then files { - examples_src_dir .. "/testbed/framework/debug_draw_2.cpp" + examples_src_dir .. "/testbed/framework/draw_gl2.h" } end if is_gfxapi("opengl_4") then files { - examples_src_dir .. "/testbed/framework/debug_draw_4.cpp" + examples_src_dir .. "/testbed/framework/draw_gl4.h" } end