From bd09b243c2a5e4bafa68dec8e7f6f9964955a516 Mon Sep 17 00:00:00 2001 From: Irlan <-> Date: Tue, 10 Apr 2018 00:57:14 -0300 Subject: [PATCH] use mvc for the testbed, update almost all tests, bugfixes, improvements, cleanup Since I started altering the testbed for better maintainability, I prefered to drop this (tested) large change with a single commit. Some changes below: Put some globals in their correct place, Now Testbed uses the MVC pattern (Model-View Controller). This way it becomes better to maintain than using no pattern in my opinion. Fixed some bugs in the debug draw interface. Of course, updated almost all tests because of the differences. Update script. --- building.txt | 4 +- examples/testbed/framework/controller.cpp | 162 +++++ examples/testbed/framework/controller.h | 59 ++ examples/testbed/framework/debug_draw.h | 119 +++- examples/testbed/framework/debug_draw_2.cpp | 148 +---- examples/testbed/framework/debug_draw_4.cpp | 148 +---- examples/testbed/framework/main.cpp | 560 ++---------------- examples/testbed/framework/model.cpp | 130 ++++ examples/testbed/framework/model.h | 225 +++++++ examples/testbed/framework/profiler.cpp | 3 + examples/testbed/framework/profiler.h | 4 + examples/testbed/framework/test.cpp | 141 ++--- examples/testbed/framework/test_entries.cpp | 16 +- examples/testbed/framework/testbed_listener.h | 9 +- examples/testbed/framework/view.cpp | 261 ++++++++ examples/testbed/framework/view.h | 43 ++ examples/testbed/tests/body_types.h | 13 +- examples/testbed/tests/box_stack.h | 13 +- examples/testbed/tests/cloth_test.h | 24 +- examples/testbed/tests/cluster_test.h | 5 - examples/testbed/tests/collide_test.h | 12 +- examples/testbed/tests/cone_test.h | 5 - examples/testbed/tests/distance_test.h | 8 +- examples/testbed/tests/gyro_test.h | 4 - examples/testbed/tests/hinge_chain.h | 5 - examples/testbed/tests/initial_overlap.h | 3 - examples/testbed/tests/jenga.h | 3 - examples/testbed/tests/mass_spring.h | 30 +- examples/testbed/tests/mesh_contact_test.h | 14 +- examples/testbed/tests/multiple_pendulum.h | 2 - examples/testbed/tests/multiple_shapes.h | 2 - examples/testbed/tests/pyramid.h | 4 +- examples/testbed/tests/pyramids.h | 4 +- examples/testbed/tests/quadric_shapes.h | 8 - examples/testbed/tests/quickhull_test.h | 72 +-- examples/testbed/tests/ray_cast.h | 17 +- examples/testbed/tests/rope_test.h | 22 +- examples/testbed/tests/shape_stack.h | 2 +- examples/testbed/tests/shift_center.h | 8 - examples/testbed/tests/single_pendulum.h | 22 +- examples/testbed/tests/spring_cloth.h | 4 - .../tests/spring_cloth_collision_test.h | 4 - examples/testbed/tests/spring_cloth_test.h | 28 +- examples/testbed/tests/tension_mapping.h | 22 +- examples/testbed/tests/test.h | 40 +- examples/testbed/tests/thin.h | 3 - examples/testbed/tests/tumbler.h | 8 - examples/testbed/tests/varying_friction.h | 80 ++- include/bounce/collision/broad_phase.h | 6 +- .../bounce/collision/sat/sat_edge_and_hull.h | 8 +- .../collision/sat/sat_vertex_and_hull.h | 6 +- include/bounce/collision/shapes/box_hull.h | 8 + include/bounce/collision/shapes/capsule.h | 26 +- include/bounce/collision/shapes/hull.h | 3 + include/bounce/collision/shapes/sphere.h | 16 + include/bounce/collision/trees/dynamic_tree.h | 3 +- include/bounce/collision/trees/static_tree.h | 3 +- include/bounce/common/draw.h | 5 + include/bounce/common/math/mat22.h | 6 + include/bounce/common/math/mat33.h | 4 +- include/bounce/common/math/quat.h | 3 + include/bounce/common/math/transform.h | 10 + include/bounce/common/math/vec2.h | 9 + include/bounce/common/math/vec3.h | 12 + include/bounce/dynamics/cloth/cloth.h | 3 +- include/bounce/dynamics/cloth/spring_cloth.h | 3 +- .../bounce/dynamics/contacts/collide/clip.h | 6 +- include/bounce/dynamics/joints/cone_joint.h | 2 +- include/bounce/dynamics/joints/joint.h | 7 +- include/bounce/dynamics/joints/mouse_joint.h | 2 +- .../bounce/dynamics/joints/revolute_joint.h | 2 +- include/bounce/dynamics/joints/sphere_joint.h | 2 +- include/bounce/dynamics/joints/spring_joint.h | 2 +- include/bounce/dynamics/joints/weld_joint.h | 2 +- include/bounce/dynamics/rope/rope.h | 4 +- include/bounce/dynamics/world.h | 11 +- premake5.lua | 18 +- src/bounce/collision/collision.cpp | 27 + .../collision/sat/sat_edge_and_hull.cpp | 6 +- .../collision/sat/sat_vertex_and_hull.cpp | 8 +- src/bounce/collision/shapes/hull.cpp | 66 +++ src/bounce/collision/trees/dynamic_tree.cpp | 7 +- src/bounce/collision/trees/static_tree.cpp | 7 +- src/bounce/common/math/{mat.cpp => math.cpp} | 25 +- src/bounce/dynamics/cloth/cloth.cpp | 8 +- src/bounce/dynamics/cloth/spring_cloth.cpp | 13 +- src/bounce/dynamics/contacts/collide/clip.cpp | 6 +- .../contacts/collide/collide_capsule_hull.cpp | 11 +- .../contacts/collide/collide_capsules.cpp | 10 +- .../contacts/collide/collide_sphere_hull.cpp | 6 +- src/bounce/dynamics/draw_world.cpp | 95 +-- src/bounce/dynamics/joints/cone_joint.cpp | 6 +- src/bounce/dynamics/joints/mouse_joint.cpp | 8 +- src/bounce/dynamics/joints/revolute_joint.cpp | 7 +- src/bounce/dynamics/joints/sphere_joint.cpp | 11 +- src/bounce/dynamics/joints/spring_joint.cpp | 13 +- src/bounce/dynamics/joints/weld_joint.cpp | 13 +- src/bounce/dynamics/rope/rope.cpp | 27 +- src/bounce/dynamics/world.cpp | 1 - 99 files changed, 1654 insertions(+), 1442 deletions(-) create mode 100644 examples/testbed/framework/controller.cpp create mode 100644 examples/testbed/framework/controller.h create mode 100644 examples/testbed/framework/model.cpp create mode 100644 examples/testbed/framework/model.h create mode 100644 examples/testbed/framework/view.cpp create mode 100644 examples/testbed/framework/view.h create mode 100644 src/bounce/collision/collision.cpp rename src/bounce/common/math/{mat.cpp => math.cpp} (83%) diff --git a/building.txt b/building.txt index 29e6db5..ac668be 100644 --- a/building.txt +++ b/building.txt @@ -5,8 +5,8 @@ Put premake into bounce/. Visual Studio 2017 -Ensure you have installed the Visual Studio 2015 libraries -Say { premake5 vs2017 } on a command line. +Ensure you have installed the Visual Studio 2015 libraries. +Say { premake5 vs2017 } on a command line. Open build/vs2017/bounce.sln. Set testbed as the startup project. In the testbed debugging properties, set the Working Directory to ..\..\examples\testbed. diff --git a/examples/testbed/framework/controller.cpp b/examples/testbed/framework/controller.cpp new file mode 100644 index 0000000..9fee1c2 --- /dev/null +++ b/examples/testbed/framework/controller.cpp @@ -0,0 +1,162 @@ +#include +#include +#include + +// ! +#include + +// ! +static inline b3Vec2 GetCursorPosition() +{ + extern GLFWwindow* g_window; + + double x, y; + glfwGetCursorPos(g_window, &x, &y); + + return b3Vec2(float32(x), float32(y)); +} + +Controller::Controller(Model* model, View* view) +{ + m_model = model; + m_view = view; + + m_leftDown = false; + m_rightDown = false; + m_shiftDown = false; + m_ps0.SetZero(); +} + +Controller::~Controller() +{ + +} + +void Controller::Event_SetWindowSize(u32 w, u32 h) +{ + m_model->Command_ResizeCamera(float32(w), float32(h)); +} + +void Controller::Event_Press_Key(int button) +{ + if (button == GLFW_KEY_LEFT_SHIFT) + { + m_shiftDown = true; + } + + if (m_shiftDown) + { + if (button == GLFW_KEY_DOWN) + { + m_model->Command_ZoomCamera(1.0f); + } + + if (button == GLFW_KEY_UP) + { + m_model->Command_ZoomCamera(-1.0f); + } + } + else + { + m_model->Command_Press_Key(button); + } +} + +void Controller::Event_Release_Key(int button) +{ + if (button == GLFW_KEY_LEFT_SHIFT) + { + m_shiftDown = false; + } + + if (m_shiftDown) + { + + } + else + { + m_model->Command_Release_Key(button); + } +} + +void Controller::Event_Press_Mouse(int button) +{ + if (button == GLFW_MOUSE_BUTTON_LEFT) + { + m_leftDown = true; + + if (!m_shiftDown) + { + m_model->Command_Press_Mouse_Left(GetCursorPosition()); + } + } + + if (button == GLFW_MOUSE_BUTTON_RIGHT) + { + m_rightDown = true; + } +} + +void Controller::Event_Release_Mouse(int button) +{ + if (button == GLFW_MOUSE_BUTTON_LEFT) + { + m_leftDown = false; + + if (!m_shiftDown) + { + m_model->Command_Release_Mouse_Left(GetCursorPosition()); + } + } + + if (button == GLFW_MOUSE_BUTTON_RIGHT) + { + m_rightDown = false; + } +} + +void Controller::Event_Move_Cursor(float32 x, float32 y) +{ + b3Vec2 ps; + ps.Set(float32(x), float32(y)); + + b3Vec2 dp = ps - m_ps0; + m_ps0 = ps; + + float32 ndx = b3Clamp(dp.x, -1.0f, 1.0f); + float32 ndy = b3Clamp(dp.y, -1.0f, 1.0f); + + if (m_shiftDown) + { + if (m_leftDown) + { + float32 ax = -0.005f * B3_PI * ndx; + float32 ay = -0.005f * B3_PI * ndy; + + m_model->Command_RotateCameraY(ax); + m_model->Command_RotateCameraX(ay); + } + + if (m_rightDown) + { + float32 tx = 0.2f * ndx; + float32 ty = -0.2f * ndy; + + m_model->Command_TranslateCameraX(tx); + m_model->Command_TranslateCameraY(ty); + } + } + else + { + m_model->Command_Move_Cursor(GetCursorPosition()); + } +} + +void Controller::Event_Scroll(float32 dx, float32 dy) +{ + if (m_shiftDown) + { + float32 ny = b3Clamp(dy, -1.0f, 1.0f); + m_model->Command_ZoomCamera(1.0f * ny); + } +} \ No newline at end of file diff --git a/examples/testbed/framework/controller.h b/examples/testbed/framework/controller.h new file mode 100644 index 0000000..1f53e4e --- /dev/null +++ b/examples/testbed/framework/controller.h @@ -0,0 +1,59 @@ +/* +* 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. +*/ + +#ifndef CONTROLLER_H +#define CONTROLLER_H + +#include + +class Model; +class View; + +class Controller +{ +public: + Controller(Model* model, View* view); + + ~Controller(); + + void Event_SetWindowSize(u32 w, u32 h); + + void Event_Press_Key(int button); + void Event_Release_Key(int button); + + void Event_Press_Mouse(int button); + void Event_Release_Mouse(int button); + + void Event_Move_Cursor(float32 x, float32 y); + void Event_Scroll(float32 dx, float32 dy); +private: + friend class Model; + friend class View; + + Model* m_model; + View* m_view; + + bool m_leftDown; + bool m_rightDown; + bool m_shiftDown; + b3Vec2 m_ps0; + + // Ray3 m_ray0; +}; + +#endif \ No newline at end of file diff --git a/examples/testbed/framework/debug_draw.h b/examples/testbed/framework/debug_draw.h index ee560f2..9730b73 100644 --- a/examples/testbed/framework/debug_draw.h +++ b/examples/testbed/framework/debug_draw.h @@ -27,29 +27,34 @@ struct DrawTriangles; struct DrawWire; struct DrawSolid; +// struct Ray3 { - b3Vec3 A() const - { - return origin; - } - - b3Vec3 B() const - { - return origin + fraction * direction; - } + b3Vec3 A() const; + b3Vec3 B() const; b3Vec3 direction; b3Vec3 origin; float32 fraction; }; +inline b3Vec3 Ray3::A() const +{ + return origin; +} + +inline b3Vec3 Ray3::B() const +{ + return origin + fraction * direction; +} + +// class Camera { public: Camera() { - m_center.Set(0.0f, 5.0f, 0.0f); + m_center.SetZero(); m_q.SetIdentity(); m_width = 1024.0f; m_height = 768.0f; @@ -77,6 +82,92 @@ public: float32 m_zFar; }; +inline b3Mat44 MakeMat44(const b3Transform& T) +{ + return b3Mat44( + b3Vec4(T.rotation.x.x, T.rotation.x.y, T.rotation.x.z, 0.0f), + b3Vec4(T.rotation.y.x, T.rotation.y.y, T.rotation.y.z, 0.0f), + b3Vec4(T.rotation.z.x, T.rotation.z.y, T.rotation.z.z, 0.0f), + b3Vec4(T.position.x, T.position.y, T.position.z, 1.0f)); +} + +inline b3Mat44 Camera::BuildProjectionMatrix() const +{ + float32 t = tan(0.5f * m_fovy); + float32 sy = 1.0f / t; + + float32 aspect = m_width / m_height; + float32 sx = 1.0f / (aspect * t); + + float32 invRange = 1.0f / (m_zNear - m_zFar); + float32 sz = invRange * (m_zNear + m_zFar); + float32 tz = invRange * m_zNear * m_zFar; + + b3Mat44 m; + m.x = b3Vec4(sx, 0.0f, 0.0f, 0.0f); + m.y = b3Vec4(0.0f, sy, 0.0f, 0.0f); + m.z = b3Vec4(0.0f, 0.0f, sz, -1.0f); + m.w = b3Vec4(0.0f, 0.0f, tz, 0.0f); + return m; +} + +inline b3Transform Camera::BuildWorldTransform() const +{ + b3Transform xf; + xf.rotation = b3QuatMat33(m_q); + xf.position = (m_zoom * xf.rotation.z) - m_center; + return xf; +} + +inline b3Mat44 Camera::BuildWorldMatrix() const +{ + b3Transform xf = BuildWorldTransform(); + return MakeMat44(xf); +} + +inline b3Transform Camera::BuildViewTransform() const +{ + b3Transform xf; + xf.rotation = b3QuatMat33(m_q); + xf.position = (m_zoom * xf.rotation.z) - m_center; + return b3Inverse(xf); +} + +inline b3Mat44 Camera::BuildViewMatrix() const +{ + b3Transform xf = BuildViewTransform(); + return MakeMat44(xf); +} + +inline b3Vec2 Camera::ConvertWorldToScreen(const b3Vec3& pw) const +{ + b3Vec2 ps; + ps.SetZero(); + return ps; +} + +inline Ray3 Camera::ConvertScreenToWorld(const b3Vec2& ps) const +{ + // Essential Math, page 250. + float32 t = tan(0.5f * m_fovy); + float32 aspect = m_width / m_height; + + b3Vec3 pv; + pv.x = 2.0f * aspect * ps.x / m_width - aspect; + pv.y = -2.0f * ps.y / m_height + 1.0f; + pv.z = -1.0f / t; + + b3Transform xf = BuildWorldTransform(); + b3Vec3 pw = xf * pv; + + Ray3 rw; + rw.direction = b3Normalize(pw - xf.position); + rw.origin = xf.position; + rw.fraction = m_zFar; + return rw; +} + +// class DebugDraw : public b3Draw { public: @@ -114,8 +205,8 @@ public: void DrawTransform(const b3Transform& xf); // - void DrawString(const char* string, const b3Color& color, ...); - + void DrawString(const b3Color& color, const char* string, ...); + void DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf); void DrawCapsule(const b3CapsuleShape* s, const b3Color& c, const b3Transform& xf); @@ -139,4 +230,8 @@ private: DrawSolid* m_solid; }; +extern DebugDraw* g_debugDraw; +extern Camera* g_camera; +extern const char* g_overlayName; + #endif \ No newline at end of file diff --git a/examples/testbed/framework/debug_draw_2.cpp b/examples/testbed/framework/debug_draw_2.cpp index 6d090cd..dba41c9 100644 --- a/examples/testbed/framework/debug_draw_2.cpp +++ b/examples/testbed/framework/debug_draw_2.cpp @@ -24,99 +24,10 @@ #include #include -extern Camera g_camera; -extern DebugDraw* g_debugDraw; -extern const char* g_logName; - -static B3_FORCE_INLINE b3Mat34 Convert34(const b3Transform& T) -{ - return b3Mat34(T.rotation.x, T.rotation.y, T.rotation.z, T.position); -} - -static B3_FORCE_INLINE b3Mat44 Convert44(const b3Transform& T) -{ - return b3Mat44( - b3Vec4(T.rotation.x.x, T.rotation.x.y, T.rotation.x.z, 0.0f), - b3Vec4(T.rotation.y.x, T.rotation.y.y, T.rotation.y.z, 0.0f), - b3Vec4(T.rotation.z.x, T.rotation.z.y, T.rotation.z.z, 0.0f), - b3Vec4(T.position.x, T.position.y, T.position.z, 1.0f)); -} - -b3Mat44 Camera::BuildProjectionMatrix() const -{ - float32 t = tan(0.5f * m_fovy); - float32 sy = 1.0f / t; - - float32 aspect = m_width / m_height; - float32 sx = 1.0f / (aspect * t); - - float32 invRange = 1.0f / (m_zNear - m_zFar); - float32 sz = invRange * (m_zNear + m_zFar); - float32 tz = invRange * m_zNear * m_zFar; - - b3Mat44 m; - m.x = b3Vec4(sx, 0.0f, 0.0f, 0.0f); - m.y = b3Vec4(0.0f, sy, 0.0f, 0.0f); - m.z = b3Vec4(0.0f, 0.0f, sz, -1.0f); - m.w = b3Vec4(0.0f, 0.0f, tz, 0.0f); - return m; -} - -b3Transform Camera::BuildWorldTransform() const -{ - b3Transform xf; - xf.rotation = b3QuatMat33(m_q); - xf.position = (m_zoom * xf.rotation.z) - m_center; - return xf; -} - -b3Mat44 Camera::BuildWorldMatrix() const -{ - b3Transform xf = BuildWorldTransform(); - return Convert44(xf); -} - -b3Transform Camera::BuildViewTransform() const -{ - b3Transform xf; - xf.rotation = b3QuatMat33(m_q); - xf.position = (m_zoom * xf.rotation.z) - m_center; - return b3Inverse(xf); -} - -b3Mat44 Camera::BuildViewMatrix() const -{ - b3Transform xf = BuildViewTransform(); - return Convert44(xf); -} - -b3Vec2 Camera::ConvertWorldToScreen(const b3Vec3& pw) const -{ - b3Vec2 ps; - ps.SetZero(); - return ps; -} - -Ray3 Camera::ConvertScreenToWorld(const b3Vec2& ps) const -{ - // Essential Math, page 250. - float32 t = tan(0.5f * m_fovy); - float32 aspect = m_width / m_height; - - b3Vec3 pv; - pv.x = 2.0f * aspect * ps.x / m_width - aspect; - pv.y = -2.0f * ps.y / m_height + 1.0f; - pv.z = -1.0f / t; - - b3Transform xf = BuildWorldTransform(); - b3Vec3 pw = xf * pv; - - Ray3 rw; - rw.direction = b3Normalize(pw - xf.position); - rw.origin = xf.position; - rw.fraction = m_zFar; - return rw; -} +// +DebugDraw* g_debugDraw = nullptr; +Camera* g_camera = nullptr; +const char* g_overlayName = nullptr; #define BUFFER_OFFSET(i) ((char*)NULL + (i)) @@ -283,8 +194,8 @@ struct DrawPoints glUseProgram(m_programId); - b3Mat44 m1 = g_camera.BuildViewMatrix(); - b3Mat44 m2 = g_camera.BuildProjectionMatrix(); + b3Mat44 m1 = g_camera->BuildViewMatrix(); + b3Mat44 m2 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -412,8 +323,8 @@ struct DrawLines glUseProgram(m_programId); - b3Mat44 m1 = g_camera.BuildViewMatrix(); - b3Mat44 m2 = g_camera.BuildProjectionMatrix(); + b3Mat44 m1 = g_camera->BuildViewMatrix(); + b3Mat44 m2 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -542,8 +453,8 @@ struct DrawTriangles glUseProgram(m_programId); - b3Mat44 m1 = g_camera.BuildViewMatrix(); - b3Mat44 m2 = g_camera.BuildProjectionMatrix(); + b3Mat44 m1 = g_camera->BuildViewMatrix(); + b3Mat44 m2 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -722,12 +633,12 @@ struct DrawWire { glUseProgram(m_programId); - b3Mat44 m1 = Convert44(xf); + b3Mat44 m1 = MakeMat44(xf); m1.x = radius * m1.x; m1.y = radius * m1.y; m1.z = radius * m1.z; - b3Mat44 m2 = g_camera.BuildViewMatrix(); - b3Mat44 m3 = g_camera.BuildProjectionMatrix(); + b3Mat44 m2 = g_camera->BuildViewMatrix(); + b3Mat44 m3 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m3 * m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -1011,13 +922,13 @@ struct DrawSolid { glUseProgram(m_programId); - b3Mat44 m1 = Convert44(xf); + b3Mat44 m1 = MakeMat44(xf); m1.x = radius * m1.x; m1.y = height * m1.y; m1.z = radius * m1.z; - b3Mat44 m2 = g_camera.BuildViewMatrix(); - b3Mat44 m3 = g_camera.BuildProjectionMatrix(); + b3Mat44 m2 = g_camera->BuildViewMatrix(); + b3Mat44 m3 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m3 * m2 * m1; glUniform4fv(m_colorUniform, 1, &c.r); @@ -1049,13 +960,13 @@ struct DrawSolid { glUseProgram(m_programId); - b3Mat44 m1 = Convert44(xf); + b3Mat44 m1 = MakeMat44(xf); m1.x = radius * m1.x; m1.y = radius * m1.y; m1.z = radius * m1.z; - b3Mat44 m2 = g_camera.BuildViewMatrix(); - b3Mat44 m3 = g_camera.BuildProjectionMatrix(); + b3Mat44 m2 = g_camera->BuildViewMatrix(); + b3Mat44 m3 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m3 * m2 * m1; glUniform4fv(m_colorUniform, 1, &c.r); @@ -1137,7 +1048,7 @@ void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const m_triangles->Vertex(p3, color, normal); b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p2, p3, p3, edgeColor); + 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) @@ -1147,7 +1058,7 @@ void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const m_triangles->Vertex(p3, color3, normal); b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p2, p3, p3, edgeColor); + DrawTriangle(p1, p2, p3, edgeColor); } void DebugDraw::DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) @@ -1397,14 +1308,19 @@ void DebugDraw::DrawAABB(const b3AABB3& aabb, const b3Color& color) DrawSegment(vs[1], vs[7], color); } -void DebugDraw::DrawString(const char* text, const b3Color& color, ...) +void DebugDraw::DrawString(const b3Color& color, const char* text, ...) { - va_list arg; - va_start(arg, text); - ImGui::Begin(g_logName, NULL, ImVec2(0, 0), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - ImGui::TextColoredV(ImVec4(color.r, color.g, color.b, color.a), text, arg); + va_list args; + va_start(args, text); + + ImGui::SetNextWindowPos(ImVec2(0.0f, 0.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(arg); + + va_end(args); } void DebugDraw::DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf) diff --git a/examples/testbed/framework/debug_draw_4.cpp b/examples/testbed/framework/debug_draw_4.cpp index 4934b3c..68e7dc1 100644 --- a/examples/testbed/framework/debug_draw_4.cpp +++ b/examples/testbed/framework/debug_draw_4.cpp @@ -24,99 +24,10 @@ #include #include -extern Camera g_camera; -extern DebugDraw* g_debugDraw; -extern const char* g_logName; - -static B3_FORCE_INLINE b3Mat34 Convert34(const b3Transform& T) -{ - return b3Mat34(T.rotation.x, T.rotation.y, T.rotation.z, T.position); -} - -static B3_FORCE_INLINE b3Mat44 Convert44(const b3Transform& T) -{ - return b3Mat44( - b3Vec4(T.rotation.x.x, T.rotation.x.y, T.rotation.x.z, 0.0f), - b3Vec4(T.rotation.y.x, T.rotation.y.y, T.rotation.y.z, 0.0f), - b3Vec4(T.rotation.z.x, T.rotation.z.y, T.rotation.z.z, 0.0f), - b3Vec4(T.position.x, T.position.y, T.position.z, 1.0f)); -} - -b3Mat44 Camera::BuildProjectionMatrix() const -{ - float32 t = tan(0.5f * m_fovy); - float32 sy = 1.0f / t; - - float32 aspect = m_width / m_height; - float32 sx = 1.0f / (aspect * t); - - float32 invRange = 1.0f / (m_zNear - m_zFar); - float32 sz = invRange * (m_zNear + m_zFar); - float32 tz = invRange * m_zNear * m_zFar; - - b3Mat44 m; - m.x = b3Vec4(sx, 0.0f, 0.0f, 0.0f); - m.y = b3Vec4(0.0f, sy, 0.0f, 0.0f); - m.z = b3Vec4(0.0f, 0.0f, sz, -1.0f); - m.w = b3Vec4(0.0f, 0.0f, tz, 0.0f); - return m; -} - -b3Transform Camera::BuildWorldTransform() const -{ - b3Transform xf; - xf.rotation = b3QuatMat33(m_q); - xf.position = (m_zoom * xf.rotation.z) - m_center; - return xf; -} - -b3Mat44 Camera::BuildWorldMatrix() const -{ - b3Transform xf = BuildWorldTransform(); - return Convert44(xf); -} - -b3Transform Camera::BuildViewTransform() const -{ - b3Transform xf; - xf.rotation = b3QuatMat33(m_q); - xf.position = (m_zoom * xf.rotation.z) - m_center; - return b3Inverse(xf); -} - -b3Mat44 Camera::BuildViewMatrix() const -{ - b3Transform xf = BuildViewTransform(); - return Convert44(xf); -} - -b3Vec2 Camera::ConvertWorldToScreen(const b3Vec3& pw) const -{ - b3Vec2 ps; - ps.SetZero(); - return ps; -} - -Ray3 Camera::ConvertScreenToWorld(const b3Vec2& ps) const -{ - // Essential Math, page 250. - float32 t = tan(0.5f * m_fovy); - float32 aspect = m_width / m_height; - - b3Vec3 pv; - pv.x = 2.0f * aspect * ps.x / m_width - aspect; - pv.y = -2.0f * ps.y / m_height + 1.0f; - pv.z = -1.0f / t; - - b3Transform xf = BuildWorldTransform(); - b3Vec3 pw = xf * pv; - - Ray3 rw; - rw.direction = b3Normalize(pw - xf.position); - rw.origin = xf.position; - rw.fraction = m_zFar; - return rw; -} +// +DebugDraw* g_debugDraw = nullptr; +Camera* g_camera = nullptr; +const char* g_overlayName = nullptr; #define BUFFER_OFFSET(i) ((char*)NULL + (i)) @@ -297,8 +208,8 @@ struct DrawPoints glUseProgram(m_programId); - b3Mat44 m1 = g_camera.BuildViewMatrix(); - b3Mat44 m2 = g_camera.BuildProjectionMatrix(); + b3Mat44 m1 = g_camera->BuildViewMatrix(); + b3Mat44 m2 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -428,8 +339,8 @@ struct DrawLines glUseProgram(m_programId); - b3Mat44 m1 = g_camera.BuildViewMatrix(); - b3Mat44 m2 = g_camera.BuildProjectionMatrix(); + b3Mat44 m1 = g_camera->BuildViewMatrix(); + b3Mat44 m2 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -566,8 +477,8 @@ struct DrawTriangles glUseProgram(m_programId); - b3Mat44 m1 = g_camera.BuildViewMatrix(); - b3Mat44 m2 = g_camera.BuildProjectionMatrix(); + b3Mat44 m1 = g_camera->BuildViewMatrix(); + b3Mat44 m2 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -739,12 +650,12 @@ struct DrawWire { glUseProgram(m_programId); - b3Mat44 m1 = Convert44(xf); + b3Mat44 m1 = MakeMat44(xf); m1.x = radius * m1.x; m1.y = radius * m1.y; m1.z = radius * m1.z; - b3Mat44 m2 = g_camera.BuildViewMatrix(); - b3Mat44 m3 = g_camera.BuildProjectionMatrix(); + b3Mat44 m2 = g_camera->BuildViewMatrix(); + b3Mat44 m3 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m3 * m2 * m1; glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x); @@ -1027,13 +938,13 @@ struct DrawSolid { glUseProgram(m_programId); - b3Mat44 m1 = Convert44(xf); + b3Mat44 m1 = MakeMat44(xf); m1.x = radius * m1.x; m1.y = height * m1.y; m1.z = radius * m1.z; - b3Mat44 m2 = g_camera.BuildViewMatrix(); - b3Mat44 m3 = g_camera.BuildProjectionMatrix(); + b3Mat44 m2 = g_camera->BuildViewMatrix(); + b3Mat44 m3 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m3 * m2 * m1; glUniform4fv(m_colorUniform, 1, &c.r); @@ -1061,13 +972,13 @@ struct DrawSolid { glUseProgram(m_programId); - b3Mat44 m1 = Convert44(xf); + b3Mat44 m1 = MakeMat44(xf); m1.x = radius * m1.x; m1.y = radius * m1.y; m1.z = radius * m1.z; - b3Mat44 m2 = g_camera.BuildViewMatrix(); - b3Mat44 m3 = g_camera.BuildProjectionMatrix(); + b3Mat44 m2 = g_camera->BuildViewMatrix(); + b3Mat44 m3 = g_camera->BuildProjectionMatrix(); b3Mat44 m = m3 * m2 * m1; glUniform4fv(m_colorUniform, 1, &c.r); @@ -1145,7 +1056,7 @@ void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const m_triangles->Vertex(p3, color, normal); b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p2, p3, p3, edgeColor); + 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) @@ -1155,7 +1066,7 @@ void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const m_triangles->Vertex(p3, color3, normal); b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f); - DrawTriangle(p2, p3, p3, edgeColor); + DrawTriangle(p1, p2, p3, edgeColor); } void DebugDraw::DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) @@ -1405,14 +1316,19 @@ void DebugDraw::DrawAABB(const b3AABB3& aabb, const b3Color& color) DrawSegment(vs[1], vs[7], color); } -void DebugDraw::DrawString(const char* text, const b3Color& color, ...) +void DebugDraw::DrawString(const b3Color& color, const char* text, ...) { - va_list arg; - va_start(arg, text); - ImGui::Begin(g_logName, NULL, ImVec2(0, 0), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - ImGui::TextColoredV(ImVec4(color.r, color.g, color.b, color.a), text, arg); + va_list args; + va_start(args, text); + + ImGui::SetNextWindowPos(ImVec2(0.0f, 0.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(arg); + + va_end(args); } void DebugDraw::DrawSphere(const b3SphereShape* s, const b3Color& c, const b3Transform& xf) diff --git a/examples/testbed/framework/main.cpp b/examples/testbed/framework/main.cpp index 17224b4..d6a3fe8 100644 --- a/examples/testbed/framework/main.cpp +++ b/examples/testbed/framework/main.cpp @@ -16,166 +16,53 @@ * 3. This notice may not be removed or altered from any source distribution. */ -#if defined(__APPLE_CC__) -#include +#if defined (U_OPENGL_2) + #include +#elif defined (U_OPENGL_4) + #include #else - -#if defined(U_OPENGL_2) -#include -#elif defined(U_OPENGL_4) -#include -#else - + // error #endif -#endif - -#include - -#if defined(U_OPENGL_2) -#include -#elif defined(U_OPENGL_4) -#include -#else -// error -#endif - -#include -#include -#include +#include +#include +#include // GLFWwindow* g_window; -Settings g_settings; -Test* g_test; -u32 g_testCount; -Camera g_camera; -DebugDraw* g_debugDraw; -Profiler* g_profiler; -TestbedListener g_testbedListener; -ProfilerListener* g_profilerListener = &g_testbedListener; -RecorderProfiler g_recorderProfiler; -bool g_leftDown; -bool g_rightDown; -bool g_shiftDown; -b3Vec2 g_ps0; -const char* g_logName = { "log" }; -// These two functions below implement Bounce's profiling interfaces. -// If you're not concerned with profiling then just define two slut functions. -bool b3PushProfileScope(const char* name) +// +Model* g_model; +View* g_view; +Controller* g_controller; + +static void WindowSize(GLFWwindow* ww, int w, int h) { - return g_profiler->PushEvent(name); + g_controller->Event_SetWindowSize(u32(w), u32(h)); } -void b3PopProfileScope() +static void CursorMove(GLFWwindow* w, double x, double y) { - g_profiler->PopEvent(); + g_controller->Event_Move_Cursor(float32(x), float32(y)); } -static void WindowSize(int w, int h) +static void WheelScroll(GLFWwindow* w, double dx, double dy) { - g_camera.m_width = float32(w); - g_camera.m_height = float32(h); -} - -static void MouseMove(GLFWwindow* w, double x, double y) -{ - b3Vec2 ps; - ps.Set(float32(x), float32(y)); - - b3Vec2 dp = ps - g_ps0; - g_ps0 = ps; - - Ray3 pw = g_camera.ConvertScreenToWorld(ps); - - float32 nx = b3Clamp(dp.x, -1.0f, 1.0f); - float32 ny = b3Clamp(dp.y, -1.0f, 1.0f); - - if (g_shiftDown) - { - if (g_leftDown) - { - // Negate angles to do positive rotations (CCW) of the world. - float32 angleY = 0.005f * B3_PI * -ny; - float32 angleX = 0.005f * B3_PI * -nx; - - b3Quat qx = b3QuatRotationX(angleY); - b3Quat qy = b3QuatRotationY(angleX); - - g_camera.m_q = g_camera.m_q * qx; - g_camera.m_q = qy * g_camera.m_q; - g_camera.m_q.Normalize(); - } - - if (g_rightDown) - { - b3Transform xf = g_camera.BuildWorldTransform(); - g_camera.m_center += 0.2f * nx * xf.rotation.x; - g_camera.m_center += 0.2f * -ny * xf.rotation.y; - } - } - else - { - g_test->MouseMove(pw); - } -} - -static void MouseWheel(GLFWwindow* w, double dx, double dy) -{ - float32 n = b3Clamp(float32(dy), -1.0f, 1.0f); - if (g_shiftDown) - { - g_camera.m_zoom += 0.5f * -n; - } + g_controller->Event_Scroll(float32(dx), float32(dy)); } static void MouseButton(GLFWwindow* w, int button, int action, int mods) { - double x, y; - glfwGetCursorPos(w, &x, &y); - b3Vec2 p; - p.Set(float32(x), float32(y)); - - Ray3 pw = g_camera.ConvertScreenToWorld(p); - switch (action) { case GLFW_PRESS: { - if (button == GLFW_MOUSE_BUTTON_LEFT) - { - g_leftDown = true; - - if (g_shiftDown == false) - { - g_test->MouseLeftDown(pw); - } - } - - if (button == GLFW_MOUSE_BUTTON_RIGHT) - { - g_rightDown = true; - } - + g_controller->Event_Press_Mouse(button); break; } case GLFW_RELEASE: { - if (button == GLFW_MOUSE_BUTTON_LEFT) - { - g_leftDown = false; - - if (g_shiftDown == false) - { - g_test->MouseLeftUp(pw); - } - } - - if (button == GLFW_MOUSE_BUTTON_RIGHT) - { - g_rightDown = false; - } + g_controller->Event_Release_Mouse(button); break; } default: @@ -191,43 +78,13 @@ static void KeyButton(GLFWwindow* w, int button, int scancode, int action, int m { case GLFW_PRESS: { - if (button == GLFW_KEY_LEFT_SHIFT) - { - g_shiftDown = true; - g_test->KeyDown(button); - } - - if (g_shiftDown) - { - if (button == GLFW_KEY_DOWN) - { - g_camera.m_zoom += 0.2f; - } - - if (button == GLFW_KEY_UP) - { - g_camera.m_zoom -= 0.2f; - } - } - else - { - g_test->KeyDown(button); - } - + g_controller->Event_Press_Key(button); + break; } case GLFW_RELEASE: { - if (button == GLFW_KEY_LEFT_SHIFT) - { - g_shiftDown = false; - } - - if (g_shiftDown == false) - { - g_test->KeyUp(button); - } - + g_controller->Event_Release_Key(button); break; } default: @@ -237,303 +94,34 @@ static void KeyButton(GLFWwindow* w, int button, int scancode, int action, int m } } -static inline bool ImGui_GLFW_GL_Init(GLFWwindow* w, bool install_callbacks) -{ - -#if defined(U_OPENGL_2) - - return ImGui_ImplGlfwGL2_Init(g_window, false); - -#elif defined(U_OPENGL_4) - - return ImGui_ImplGlfwGL3_Init(g_window, false); - -#else - - // error - -#endif - -} - -static inline void ImGui_GLFW_GL_Shutdown() -{ - -#if defined(U_OPENGL_2) - - ImGui_ImplGlfwGL2_Shutdown(); - -#elif defined(U_OPENGL_4) - - ImGui_ImplGlfwGL3_Shutdown(); - -#else - - // error - -#endif - -} - -static inline void ImGui_GLFW_GL_NewFrame() -{ - -#if defined(U_OPENGL_2) - - ImGui_ImplGlfwGL2_NewFrame(); - -#elif defined(U_OPENGL_4) - - ImGui_ImplGlfwGL3_NewFrame(); - -#else - - // error - -#endif - -} - -static inline void ImGui_GLFW_GL_RenderDrawData(ImDrawData* data) -{ - -#if defined(U_OPENGL_2) - - ImGui_ImplGlfwGL2_RenderDrawData(data); - -#elif defined(U_OPENGL_4) - - ImGui_ImplGlfwGL3_RenderDrawData(data); - -#else - - // error - -#endif - -} - -static void Char(GLFWwindow* w, unsigned int codepoint) -{ - ImGui_ImplGlfw_CharCallback(w, codepoint); -} - -static void CreateInterface() -{ - ImGui::CreateContext(); - - ImGuiIO& io = ImGui::GetIO(); - io.Fonts[0].AddFontDefault(); - - ImGui_GLFW_GL_Init(g_window, false); - - ImGui::StyleColorsDark(); -} - -static void DestroyInterface() -{ - ImGui_GLFW_GL_Shutdown(); - - ImGui::DestroyContext(); -} - -static bool GetTestName(void*, int idx, const char** name) -{ - *name = g_tests[idx].name; - return true; -} - -static void Interface() -{ - ImGui::SetNextWindowPos(ImVec2(g_camera.m_width - 250.0f, 0.0f)); - ImGui::SetNextWindowSize(ImVec2(250.0f, g_camera.m_height)); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - - ImGui::Begin("Controls", NULL, ImVec2(0.0f, 0.0f), 0.25f, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize); - - ImGui::PushItemWidth(-1.0f); - - ImGui::Text("Test"); - if (ImGui::Combo("##Test", &g_settings.testID, GetTestName, NULL, g_testCount, g_testCount)) - { - g_settings.lastTestID = -1; - } - - ImVec2 buttonSize = ImVec2(-1, 0); - if (ImGui::Button("Restart", buttonSize)) - { - g_settings.lastTestID = -1; - } - if (ImGui::Button("Previous", buttonSize)) - { - g_settings.testID = b3Clamp(g_settings.testID - 1, 0, int(g_testCount) - 1); - g_settings.lastTestID = -1; - } - if (ImGui::Button("Next", buttonSize)) - { - g_settings.testID = b3Clamp(g_settings.testID + 1, 0, int(g_testCount) - 1); - g_settings.lastTestID = -1; - } - if (ImGui::Button("Dump", buttonSize)) - { - if (g_test) - { - g_test->Dump(); - } - } - if (ImGui::Button("Exit", buttonSize)) - { - glfwSetWindowShouldClose(g_window, true); - } - - ImGui::Separator(); - - ImGui::Text("Step"); - - ImGui::Text("Hertz"); - ImGui::SliderFloat("##Hertz", &g_settings.hertz, 0.0f, 240.0f, "%.1f"); - ImGui::Text("Velocity Iterations"); - ImGui::SliderInt("##Velocity Iterations", &g_settings.velocityIterations, 0, 50); - ImGui::Text("Position Iterations"); - ImGui::SliderInt("#Position Iterations", &g_settings.positionIterations, 0, 50); - ImGui::Checkbox("Sleep", &g_settings.sleep); - ImGui::Checkbox("Convex Cache", &g_settings.convexCache); - ImGui::Checkbox("Warm Start", &g_settings.warmStart); - - if (ImGui::Button("Play/Pause", buttonSize)) - { - g_settings.pause = !g_settings.pause; - } - if (ImGui::Button("Single Step", buttonSize)) - { - g_settings.pause = true; - g_settings.singleStep = true; - } - - ImGui::Separator(); - - ImGui::Text("View"); - ImGui::Checkbox("Grid", &g_settings.drawGrid); - ImGui::Checkbox("Vertices and Edges", &g_settings.drawVerticesEdges); - ImGui::Checkbox("Faces", &g_settings.drawFaces); - ImGui::Checkbox("Center of Masses", &g_settings.drawCenterOfMasses); - ImGui::Checkbox("Bounding Boxes", &g_settings.drawBounds); - ImGui::Checkbox("Joints", &g_settings.drawJoints); - ImGui::Checkbox("Contact Points", &g_settings.drawContactPoints); - ImGui::Checkbox("Contact Normals", &g_settings.drawContactNormals); - ImGui::Checkbox("Contact Tangents", &g_settings.drawContactTangents); - ImGui::Checkbox("Contact Polygons", &g_settings.drawContactPolygons); - ImGui::Checkbox("Statistics", &g_settings.drawStats); - ImGui::Checkbox("Profile", &g_settings.drawProfile); - - ImGui::End(); - ImGui::PopStyleVar(); -} - -static void Step() -{ - if (g_settings.pause) - { - g_debugDraw->DrawString("*PAUSED*", b3Color_white); - } - else - { - g_debugDraw->DrawString("*PLAYING*", b3Color_white); - } - - if (g_settings.drawGrid) - { - b3Color color(0.2f, 0.2f, 0.2f, 1.0f); - - b3Vec3 pn(0.0f, 1.0f, 0.0f); - b3Vec3 p(0.0f, 0.0f, 0.0f); - g_debugDraw->DrawCircle(pn, p, 1.0f, color); - - int n = 20; - - b3Vec3 t; - t.x = -0.5f * float32(n); - t.y = 0.0f; - t.z = -0.5f * float32(n); - - for (int i = 0; i < n; i += 1) - { - for (int j = 0; j < n; j += 1) - { - b3Vec3 vs[4]; - vs[0] = b3Vec3((float)i, 0.0f, (float)j); - vs[1] = b3Vec3((float)i, 0.0f, (float)j + 1); - vs[2] = b3Vec3((float)i + 1, 0.0f, (float)j + 1); - vs[3] = b3Vec3((float)i + 1, 0.0f, (float)j); - - for (u32 k = 0; k < 4; ++k) - { - vs[k] += t; - } - - g_debugDraw->DrawPolygon(vs, 4, color); - } - } - } - - if (g_settings.testID != g_settings.lastTestID) - { - delete g_test; - g_settings.lastTestID = g_settings.testID; - g_test = g_tests[g_settings.testID].create(); - g_settings.pause = true; - } - - g_test->Step(); - g_debugDraw->Submit(); -} - static void Run() { - glFrontFace(GL_CCW); - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); - glEnable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + int w, h; + glfwGetWindowSize(g_window, &w, &h); + g_controller->Event_SetWindowSize(u32(w), u32(h)); - glClearColor(0.3f, 0.3f, 0.3f, 1.0f); - glClearDepth(1.0f); - - double t1 = glfwGetTime(); double frameTime = 0.0; while (glfwWindowShouldClose(g_window) == 0) { - int width, height; - glfwGetWindowSize(g_window, &width, &height); - g_camera.m_width = float32(width); - g_camera.m_height = float32(height); + double time1 = glfwGetTime(); + + g_view->Command_PreDraw(); - glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + g_view->Command_Draw(); - ImGui_GLFW_GL_NewFrame(); + g_debugDraw->DrawString(b3Color_yellow, "%.2f (ms)", 1000.0 * frameTime); - ImGui::SetNextWindowPos(ImVec2(0, 0)); - ImGui::SetNextWindowSize(ImVec2((float)g_camera.m_width, (float)g_camera.m_height)); - ImGui::Begin("Overlay", NULL, ImVec2(0, 0), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - ImGui::SetCursorPos(ImVec2(5, (float)g_camera.m_height - 20)); - ImGui::Text("%.1f ms", 1000.0 * frameTime); - ImGui::End(); + g_model->Command_Step(); - Interface(); - Step(); + g_view->Command_PostDraw(); - double t = glfwGetTime(); - frameTime = t - t1; - t1 = t; - - ImGui::Render(); - ImGui_GLFW_GL_RenderDrawData(ImGui::GetDrawData()); + double time2 = glfwGetTime(); + + double fraction = 0.9; + frameTime = fraction * frameTime + (1.0 - fraction) * (time2 - time1); glfwSwapBuffers(g_window); - glfwPollEvents(); } } @@ -542,7 +130,8 @@ int main(int argc, char** args) { #if defined(_WIN32) // Report memory leaks - _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF | _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); + //_CrtSetBreakAlloc(x); #endif if (glfwInit() == 0) @@ -556,29 +145,23 @@ int main(int argc, char** args) char title[256]; sprintf(title, "Bounce Testbed Version %d.%d.%d", b3_version.major, b3_version.minor, b3_version.revision); -#if defined(__APPLE__) - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#endif - g_window = glfwCreateWindow(1024, 768, title, NULL, NULL); if (g_window == NULL) { - fprintf(stderr, "Failed to open GLFW window\n"); + fprintf(stderr, "Failed to create GLFW window\n"); glfwTerminate(); return -1; } - - glfwMakeContextCurrent(g_window); - glfwSetCursorPosCallback(g_window, MouseMove); - glfwSetScrollCallback(g_window, MouseWheel); + + glfwSetWindowSizeCallback(g_window, WindowSize); + glfwSetCursorPosCallback(g_window, CursorMove); + glfwSetScrollCallback(g_window, WheelScroll); glfwSetMouseButtonCallback(g_window, MouseButton); glfwSetKeyCallback(g_window, KeyButton); - glfwSetCharCallback(g_window, Char); glfwSwapInterval(1); + glfwMakeContextCurrent(g_window); + if (gladLoadGL() == 0) { fprintf(stderr, "Failed to load OpenGL extensions\n"); @@ -589,48 +172,27 @@ int main(int argc, char** args) printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); - g_leftDown = false; - g_rightDown = false; - g_shiftDown = false; - g_ps0.SetZero(); - - // Create UI - CreateInterface(); - - // Create profiler - g_profiler = new Profiler(); - - // Create renderer - g_debugDraw = new DebugDraw(); - - // Run the testbed - g_testCount = 0; - while (g_tests[g_testCount].create != NULL) - { - ++g_testCount; - } - g_test = NULL; + // + g_model = new Model(); + g_view = new View(g_window, g_model); + g_controller = new Controller(g_model, g_view); + // Run Run(); - // Destroy the last test - if (g_test) - { - delete g_test; - g_test = NULL; - } + // + delete g_controller; + g_controller = nullptr; - // Destroy renderer - delete g_debugDraw; + delete g_view; + g_view = nullptr; - // Destroy profiler - delete g_profiler; + delete g_model; + g_model = nullptr; - // Destroy UI - DestroyInterface(); - - // Destroy g_window + // glfwTerminate(); + g_window = nullptr; return 0; } \ No newline at end of file diff --git a/examples/testbed/framework/model.cpp b/examples/testbed/framework/model.cpp new file mode 100644 index 0000000..afdb52c --- /dev/null +++ b/examples/testbed/framework/model.cpp @@ -0,0 +1,130 @@ +#include + +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; + + m_test = nullptr; + + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glClearColor(0.3f, 0.3f, 0.3f, 1.0f); + glClearDepth(1.0f); + + m_camera.m_q = b3QuatRotationX(-0.125f * B3_PI); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +Model::~Model() +{ + g_debugDraw = nullptr; + g_camera = nullptr; + g_overlayName = nullptr; + g_profiler = nullptr; + g_profilerListener = nullptr; + g_settings = nullptr; + + delete m_test; +} + +void Model::Command_Step() +{ + 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; + } + + 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*"); + } + else + { + m_debugDraw.DrawString(b3Color_white, "*PLAYING*"); + } + + if (m_settings.drawGrid) + { + b3Color color(0.2f, 0.2f, 0.2f, 1.0f); + + b3Vec3 pn(0.0f, 1.0f, 0.0f); + b3Vec3 p(0.0f, 0.0f, 0.0f); + m_debugDraw.DrawCircle(pn, p, 1.0f, color); + + int n = 20; + + b3Vec3 t; + t.x = -0.5f * float32(n); + t.y = 0.0f; + t.z = -0.5f * float32(n); + + for (int i = 0; i < n; i += 1) + { + for (int j = 0; j < n; j += 1) + { + b3Vec3 vs[4]; + vs[0] = b3Vec3((float32)i, 0.0f, (float32)j); + vs[1] = b3Vec3((float32)i, 0.0f, (float32)j + 1); + vs[2] = b3Vec3((float32)i + 1, 0.0f, (float32)j + 1); + vs[3] = b3Vec3((float32)i + 1, 0.0f, (float32)j); + + vs[0] += t; + vs[1] += t; + vs[2] += t; + vs[3] += t; + + m_debugDraw.DrawPolygon(vs, 4, color); + } + } + } + + // + m_settings.inv_hertz = m_settings.hertz != 0.0f ? 1.0f / m_settings.hertz : 0.0f; + + if (m_settings.pause) + { + if (m_settings.singleStep) + { + m_settings.singleStep = false; + } + else + { + m_settings.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(); +} \ No newline at end of file diff --git a/examples/testbed/framework/model.h b/examples/testbed/framework/model.h new file mode 100644 index 0000000..3a61609 --- /dev/null +++ b/examples/testbed/framework/model.h @@ -0,0 +1,225 @@ +/* +* 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. +*/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class Model +{ +public: + Model(); + + ~Model(); + + void Action_SelectTest(int selection); + void Action_RestartTest(); + void Action_PreviousTest(); + void Action_NextTest(); + void Action_DumpTest(); + void Action_PlayPause(); + void Action_SingleStep(); + void Action_LeftCamera(); + void Action_RightCamera(); + void Action_BottomCamera(); + void Action_TopCamera(); + void Action_BackCamera(); + void Action_FrontCamera(); + + void Command_Step(); + void Command_Press_Key(int button); + void Command_Release_Key(int button); + void Command_Press_Mouse_Left(const b3Vec2& ps); + void Command_Release_Mouse_Left(const b3Vec2& ps); + void Command_Move_Cursor(const b3Vec2& ps); + void Command_ResizeCamera(float32 w, float32 h); + void Command_RotateCameraX(float32 angle); + void Command_RotateCameraY(float32 angle); + void Command_TranslateCameraX(float32 d); + void Command_TranslateCameraY(float32 d); + void Command_ZoomCamera(float32 d); +private: + friend class View; + friend class Controller; + + DebugDraw m_debugDraw; + Camera m_camera; + Profiler m_profiler; + TestbedListener m_profilerListener; + + Settings m_settings; + Test* m_test; +}; + +inline void Model::Action_SelectTest(int selection) +{ + m_settings.testID = selection; + m_settings.lastTestID = -1; +} + +inline void Model::Action_RestartTest() +{ + m_settings.lastTestID = -1; +} + +inline void Model::Action_PreviousTest() +{ + m_settings.testID = b3Clamp(m_settings.testID - 1, 0, int(g_testCount) - 1); + m_settings.lastTestID = -1; +} + +inline void Model::Action_NextTest() +{ + m_settings.testID = b3Clamp(m_settings.testID + 1, 0, int(g_testCount) - 1); + m_settings.lastTestID = -1; +} + +inline void Model::Action_DumpTest() +{ + m_test->Dump(); +} + +inline void Model::Action_PlayPause() +{ + m_settings.pause = !m_settings.pause; +} + +inline void Model::Action_SingleStep() +{ + m_settings.pause = true; + m_settings.singleStep = true; +} + +inline void Model::Action_LeftCamera() +{ + m_camera.m_q.Set(b3Vec3(0.0f, 1.0f, 0.0f), 0.5f * B3_PI); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +inline void Model::Action_RightCamera() +{ + m_camera.m_q.Set(b3Vec3(0.0f, 1.0f, 0.0f), -0.5f * B3_PI); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +inline void Model::Action_BottomCamera() +{ + m_camera.m_q.Set(b3Vec3(1.0f, 0.0f, 0.0f), 0.5f * B3_PI); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +inline void Model::Action_TopCamera() +{ + m_camera.m_q.Set(b3Vec3(1.0f, 0.0f, 0.0f), -0.5f * B3_PI); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +inline void Model::Action_BackCamera() +{ + m_camera.m_q.Set(b3Vec3(0.0f, 1.0f, 0.0f), -B3_PI); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +inline void Model::Action_FrontCamera() +{ + m_camera.m_q.SetIdentity(); + m_camera.m_center.SetZero(); + m_camera.m_zoom = 20.0f; +} + +inline void Model::Command_Press_Key(int button) +{ + m_test->KeyDown(button); +} + +inline void Model::Command_Release_Key(int button) +{ + m_test->KeyUp(button); +} + +inline void Model::Command_Press_Mouse_Left(const b3Vec2& ps) +{ + Ray3 pw = m_camera.ConvertScreenToWorld(ps); + + m_test->MouseLeftDown(pw); +} + +inline void Model::Command_Release_Mouse_Left(const b3Vec2& ps) +{ + Ray3 pw = m_camera.ConvertScreenToWorld(ps); + + m_test->MouseLeftUp(pw); +} + +inline void Model::Command_Move_Cursor(const b3Vec2& ps) +{ + Ray3 pw = m_camera.ConvertScreenToWorld(ps); + + m_test->MouseMove(pw); +} + +inline void Model::Command_ResizeCamera(float32 w, float32 h) +{ + m_camera.m_width = w; + m_camera.m_height = h; +} + +inline void Model::Command_RotateCameraX(float32 angle) +{ + b3Quat d = b3QuatRotationX(angle); + + m_camera.m_q = m_camera.m_q * d; + m_camera.m_q.Normalize(); +} + +inline void Model::Command_RotateCameraY(float32 angle) +{ + b3Quat d = b3QuatRotationY(angle); + + m_camera.m_q = d * m_camera.m_q; + m_camera.m_q.Normalize(); +} + +inline void Model::Command_TranslateCameraX(float32 d) +{ + b3Transform transform = m_camera.BuildWorldTransform(); + + m_camera.m_center += d * transform.rotation.x; +} + +inline void Model::Command_TranslateCameraY(float32 d) +{ + b3Transform transform = m_camera.BuildWorldTransform(); + + m_camera.m_center += d * transform.rotation.y; +} + +inline void Model::Command_ZoomCamera(float32 d) +{ + m_camera.m_zoom += d; +} + +#endif \ No newline at end of file diff --git a/examples/testbed/framework/profiler.cpp b/examples/testbed/framework/profiler.cpp index 1c4aec9..bc72572 100644 --- a/examples/testbed/framework/profiler.cpp +++ b/examples/testbed/framework/profiler.cpp @@ -18,6 +18,9 @@ #include +Profiler* g_profiler = nullptr; +ProfilerListener* g_profilerListener = nullptr; + Profiler::Profiler() { m_top = nullptr; diff --git a/examples/testbed/framework/profiler.h b/examples/testbed/framework/profiler.h index 441863c..79dd23a 100644 --- a/examples/testbed/framework/profiler.h +++ b/examples/testbed/framework/profiler.h @@ -71,6 +71,8 @@ private: ProfilerEvent* m_top; }; +extern Profiler* g_profiler; + // Any implementation of this interface passed to Profiler::End will listen to profile events. class ProfilerListener { @@ -110,4 +112,6 @@ public: } }; +extern ProfilerListener* g_profilerListener; + #endif \ No newline at end of file diff --git a/examples/testbed/framework/test.cpp b/examples/testbed/framework/test.cpp index 4bac0c5..75b8353 100644 --- a/examples/testbed/framework/test.cpp +++ b/examples/testbed/framework/test.cpp @@ -22,14 +22,18 @@ extern u32 b3_allocCalls, b3_maxAllocCalls; extern u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters; extern bool b3_convexCache; extern u32 b3_convexCalls, b3_convexCacheHits; -extern b3Draw* b3_debugDraw; -extern Settings g_settings; -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Profiler* g_profiler; -extern ProfilerListener* g_profilerListener; -extern RecorderProfiler g_recorderProfiler; +bool b3PushProfileScope(const char* name) +{ + return g_profiler->PushEvent(name); +} + +void b3PopProfileScope() +{ + g_profiler->PopEvent(); +} + +Settings* g_settings = nullptr; Test::Test() { @@ -37,34 +41,17 @@ Test::Test() b3_gjkCalls = 0; b3_gjkIters = 0; b3_gjkMaxIters = 0; - b3_convexCache = g_settings.convexCache; + b3_convexCache = g_settings->convexCache; b3_convexCalls = 0; b3_convexCacheHits = 0; - b3_debugDraw = g_debugDraw; - - b3Quat q_y = b3QuatRotationY(0.15f * B3_PI); - b3Quat q_x = b3QuatRotationX(-0.15f * B3_PI); - - g_camera.m_q = q_y * q_x; - g_camera.m_zoom = 50.0f; - g_camera.m_center.SetZero(); + b3Draw_draw = g_debugDraw; m_world.SetContactListener(this); m_rayHit.shape = NULL; m_mouseJoint = NULL; - { - b3Transform m; - m.position.SetZero(); - m.rotation = b3Diagonal(50.0f, 1.0f, 50.0f); - m_groundHull.SetTransform(m); - } - - { - m_boxHull.SetIdentity(); - } - + m_groundHull.Set(50.0f, 1.0f, 50.0f); m_groundMesh.BuildTree(); } @@ -77,71 +64,42 @@ Test::~Test() b3_convexCache = false; b3_convexCalls = 0; b3_convexCacheHits = 0; - b3_debugDraw = nullptr; -} - -void Test::BeginContact(b3Contact* contact) -{ -} - -void Test::EndContact(b3Contact* contact) -{ - -} - -void Test::PreSolve(b3Contact* contact) -{ - + b3Draw_draw = nullptr; } void Test::Step() { - float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - dt = 0.0f; - } - } - b3_allocCalls = 0; b3_gjkCalls = 0; b3_gjkIters = 0; b3_gjkMaxIters = 0; - b3_convexCache = g_settings.convexCache; + b3_convexCache = g_settings->convexCache; b3_convexCalls = 0; b3_convexCacheHits = 0; + float32 dt = g_settings->inv_hertz; + // Step - g_profiler->Begin(); + m_world.SetSleeping(g_settings->sleep); + m_world.SetWarmStart(g_settings->warmStart); + m_world.Step(dt, g_settings->velocityIterations, g_settings->positionIterations); - m_world.SetSleeping(g_settings.sleep); - m_world.SetWarmStart(g_settings.warmStart); - m_world.Step(dt, g_settings.velocityIterations, g_settings.positionIterations); - - g_profiler->End(g_profilerListener); - g_debugDraw->Submit(); // Draw World 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_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; g_debugDraw->SetFlags(drawFlags); - m_world.DebugDraw(); + + m_world.Draw(); if (m_mouseJoint) { @@ -156,20 +114,16 @@ void Test::Step() g_debugDraw->Submit(); - if (g_settings.drawFaces) + if (g_settings->drawFaces) { g_debugDraw->Draw(m_world); } - // Draw Statistics - extern const char* g_logName; - ImGui::Begin(g_logName, NULL, ImVec2(0, 0), 0.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoScrollbar); - - if (g_settings.drawStats) + if (g_settings->drawStats) { - ImGui::Text("Bodies %d", m_world.GetBodyList().m_count); - ImGui::Text("Joints %d", m_world.GetJointList().m_count); - ImGui::Text("Contacts %d", m_world.GetContactList().m_count); + 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); float32 avgGjkIters = 0.0f; if (b3_gjkCalls > 0) @@ -177,8 +131,8 @@ void Test::Step() avgGjkIters = float32(b3_gjkIters) / float32(b3_gjkCalls); } - ImGui::Text("GJK Calls %d", b3_gjkCalls); - ImGui::Text("GJK Iterations %d (%d) (%f)", b3_gjkIters, b3_gjkMaxIters, avgGjkIters); + 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); float32 convexCacheHitRatio = 0.0f; if (b3_convexCalls > 0) @@ -186,23 +140,10 @@ void Test::Step() convexCacheHitRatio = float32(b3_convexCacheHits) / float32(b3_convexCalls); } - ImGui::Text("Convex Calls %d", b3_convexCalls); - ImGui::Text("Convex Cache Hits %d (%f)", b3_convexCacheHits, convexCacheHitRatio); - ImGui::Text("Frame Allocations %d (%d)", b3_allocCalls, b3_maxAllocCalls); + 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); } - - if (g_settings.drawProfile) - { - const b3Array& records = g_recorderProfiler.GetRecords(); - for (u32 i = 0; i < records.Count(); ++i) - { - const ProfilerRecord& r = records[i]; - - ImGui::Text("%s %.4f (%.4f) [ms]", r.name, r.elapsed, r.maxElapsed); - } - } - - ImGui::End(); } void Test::MouseMove(const Ray3& pw) diff --git a/examples/testbed/framework/test_entries.cpp b/examples/testbed/framework/test_entries.cpp index 47679f1..804d5e5 100644 --- a/examples/testbed/framework/test_entries.cpp +++ b/examples/testbed/framework/test_entries.cpp @@ -117,4 +117,18 @@ TestEntry g_tests[] = { "Mass-Spring System", &MassSpring::Create }, { "Shift Center", &ShiftCenter::Create }, { NULL, NULL } -}; \ No newline at end of file +}; + +// +static u32 TestCount() +{ + u32 count = 0; + while (g_tests[count].create != NULL) + { + ++count; + } + return count; +} + +// Count the tests +u32 g_testCount = TestCount(); \ No newline at end of file diff --git a/examples/testbed/framework/testbed_listener.h b/examples/testbed/framework/testbed_listener.h index dd7f60f..7588f66 100644 --- a/examples/testbed/framework/testbed_listener.h +++ b/examples/testbed/framework/testbed_listener.h @@ -30,14 +30,13 @@ #include #endif -extern RecorderProfiler g_recorderProfiler; class TestbedListener : public ProfilerListener { public: void BeginEvents() override { - g_recorderProfiler.BeginEvents(); + m_recorderProfiler.BeginEvents(); #if (PROFILE_JSON == 1) m_jsonListener.BeginEvents(); @@ -47,7 +46,7 @@ public: void EndEvents() override { - g_recorderProfiler.EndEvents(); + m_recorderProfiler.EndEvents(); #if (PROFILE_JSON == 1) m_jsonListener.EndEvents(); @@ -73,9 +72,11 @@ public: void Duration(const char* name, float64 time) override { - g_recorderProfiler.Add(name, time); + m_recorderProfiler.Add(name, time); } + RecorderProfiler m_recorderProfiler; + #if (PROFILE_JSON == 1) JsonProfiler m_jsonListener; #endif diff --git a/examples/testbed/framework/view.cpp b/examples/testbed/framework/view.cpp new file mode 100644 index 0000000..cf32c5c --- /dev/null +++ b/examples/testbed/framework/view.cpp @@ -0,0 +1,261 @@ +#include +#include + +#if defined (U_OPENGL_2) + #include +#elif defined (U_OPENGL_4) + #include +#else + +#endif + +static bool GetTestName(void* userData, int idx, const char** name) +{ + assert(u32(idx) < g_testCount); + *name = g_tests[idx].name; + return true; +} + +static inline bool ImGui_GLFW_GL_Init(GLFWwindow* w, bool install_callbacks) +{ + +#if defined(U_OPENGL_2) + + return ImGui_ImplGlfwGL2_Init(w, install_callbacks); + +#elif defined(U_OPENGL_4) + + return ImGui_ImplGlfwGL3_Init(w, install_callbacks); + +#else + + // error + +#endif + +} + +static inline void ImGui_GLFW_GL_Shutdown() +{ + +#if defined(U_OPENGL_2) + + ImGui_ImplGlfwGL2_Shutdown(); + +#elif defined(U_OPENGL_4) + + ImGui_ImplGlfwGL3_Shutdown(); + +#else + + // error + +#endif + +} + +static inline void ImGui_GLFW_GL_NewFrame() +{ + +#if defined(U_OPENGL_2) + + ImGui_ImplGlfwGL2_NewFrame(); + +#elif defined(U_OPENGL_4) + + ImGui_ImplGlfwGL3_NewFrame(); + +#else + + // error + +#endif + +} + +static inline void ImGui_GLFW_GL_RenderDrawData(ImDrawData* draw_data) +{ + +#if defined(U_OPENGL_2) + + ImGui_ImplGlfwGL2_RenderDrawData(draw_data); + +#elif defined(U_OPENGL_4) + + ImGui_ImplGlfwGL3_RenderDrawData(draw_data); + +#else + + // error + +#endif + +} + +View::View(GLFWwindow* window, Model* model) +{ + m_window = window; + m_model = model; + + // Create UI + ImGui::CreateContext(); + + ImGuiIO& io = ImGui::GetIO(); + io.Fonts[0].AddFontDefault(); + + ImGui_GLFW_GL_Init(m_window, false); + + ImGui::StyleColorsLight(); +} + +View::~View() +{ + // Destroy UI + ImGui_GLFW_GL_Shutdown(); + + ImGui::DestroyContext(); +} + +void View::Command_PreDraw() +{ + ImGui_GLFW_GL_NewFrame(); +} + +void View::Command_Draw() +{ + Camera& camera = m_model->m_camera; + Settings& settings = m_model->m_settings; + + ImVec2 buttonSize(-1.0f, 0.0f); + + ImGui::SetNextWindowPos(ImVec2(camera.m_width - 250.0f, 0.0f)); + ImGui::SetNextWindowSize(ImVec2(250.0f, camera.m_height)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + + ImGui::Begin("Controller", NULL, ImVec2(0.0f, 0.0f), 0.25f, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize); + + ImGui::PushItemWidth(-1.0f); + + ImGui::Separator(); + + ImGui::Text("Test"); + + ImGui::Separator(); + + if (ImGui::Combo("##Test", &settings.testID, GetTestName, NULL, g_testCount, g_testCount)) + { + m_model->Action_SelectTest(settings.testID); + } + + if (ImGui::Button("Restart", buttonSize)) + { + m_model->Action_RestartTest(); + } + + if (ImGui::Button("Previous", buttonSize)) + { + m_model->Action_PreviousTest(); + } + + if (ImGui::Button("Next", buttonSize)) + { + m_model->Action_NextTest(); + } + + if (ImGui::Button("Dump", buttonSize)) + { + m_model->Action_DumpTest(); + } + + if (ImGui::Button("Exit", buttonSize)) + { + glfwSetWindowShouldClose(m_window, true); + } + + ImGui::Separator(); + + ImGui::Text("Step"); + + ImGui::Separator(); + + ImGui::Text("Hertz"); + ImGui::SliderFloat("##Hertz", &settings.hertz, 0.0f, 240.0f, "%.1f"); + ImGui::Text("Velocity Iterations"); + ImGui::SliderInt("##Velocity Iterations", &settings.velocityIterations, 0, 50); + ImGui::Text("Position Iterations"); + ImGui::SliderInt("#Position Iterations", &settings.positionIterations, 0, 50); + ImGui::Checkbox("Sleep", &settings.sleep); + ImGui::Checkbox("Convex Cache", &settings.convexCache); + ImGui::Checkbox("Warm Start", &settings.warmStart); + + if (ImGui::Button("Play/Pause", buttonSize)) + { + m_model->Action_PlayPause(); + } + + if (ImGui::Button("Single Step", buttonSize)) + { + m_model->Action_SingleStep(); + } + + ImGui::Separator(); + + ImGui::Text("View"); + + ImGui::Separator(); + + ImGui::Checkbox("Reference Grid", &settings.drawGrid); + ImGui::Checkbox("Vertices and Edges", &settings.drawVerticesEdges); + ImGui::Checkbox("Faces", &settings.drawFaces); + ImGui::Checkbox("Center of Masses", &settings.drawCenterOfMasses); + ImGui::Checkbox("Bounding Boxes", &settings.drawBounds); + ImGui::Checkbox("Joints", &settings.drawJoints); + ImGui::Checkbox("Contact Points", &settings.drawContactPoints); + ImGui::Checkbox("Contact Normals", &settings.drawContactNormals); + ImGui::Checkbox("Contact Tangents", &settings.drawContactTangents); + ImGui::Checkbox("Contact Polygons", &settings.drawContactPolygons); + ImGui::Checkbox("Statistics", &settings.drawStats); + ImGui::Checkbox("Profile", &settings.drawProfile); + + ImGui::Separator(); + + if (ImGui::Button("Left", buttonSize)) + { + m_model->Action_LeftCamera(); + } + + if (ImGui::Button("Right", buttonSize)) + { + m_model->Action_RightCamera(); + } + + if (ImGui::Button("Bottom", buttonSize)) + { + m_model->Action_BottomCamera(); + } + + if (ImGui::Button("Top", buttonSize)) + { + m_model->Action_TopCamera(); + } + + if (ImGui::Button("Back", buttonSize)) + { + m_model->Action_BackCamera(); + } + + if (ImGui::Button("Front", buttonSize)) + { + m_model->Action_FrontCamera(); + } + + ImGui::End(); + ImGui::PopStyleVar(); +} + +void View::Command_PostDraw() +{ + ImGui::Render(); + + ImGui_GLFW_GL_RenderDrawData(ImGui::GetDrawData()); +} \ No newline at end of file diff --git a/examples/testbed/framework/view.h b/examples/testbed/framework/view.h new file mode 100644 index 0000000..a5042c7 --- /dev/null +++ b/examples/testbed/framework/view.h @@ -0,0 +1,43 @@ +/* +* 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. +*/ + +#ifndef VIEW_H +#define VIEW_H + +struct GLFWwindow; +class Model; + +class View +{ +public: + View(GLFWwindow* window, Model* model); + + ~View(); + + void Command_PreDraw(); + + void Command_Draw(); + + void Command_PostDraw(); +private: + GLFWwindow * m_window; + + Model* m_model; +}; + +#endif \ No newline at end of file diff --git a/examples/testbed/tests/body_types.h b/examples/testbed/tests/body_types.h index 92458d9..c41efed 100644 --- a/examples/testbed/tests/body_types.h +++ b/examples/testbed/tests/body_types.h @@ -24,8 +24,6 @@ class BodyTypes : public Test public: BodyTypes() { - g_camera.m_zoom = 50.0f; - { b3BodyDef bd; b3Body* ground = m_world.CreateBody(bd); @@ -66,12 +64,11 @@ public: { Test::Step(); - b3Color color(1.0f, 1.0f, 1.0f); - g_debugDraw->DrawString("S - Static", color); - g_debugDraw->DrawString("D - Dynamic", color); - g_debugDraw->DrawString("K - Kinematic", color); - g_debugDraw->DrawString("Space - Throw Bomb", color); - g_debugDraw->DrawString("Arrows - Apply Force/Velocity/Position", color); + 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"); } void KeyDown(int button) diff --git a/examples/testbed/tests/box_stack.h b/examples/testbed/tests/box_stack.h index af150b4..6cf636a 100644 --- a/examples/testbed/tests/box_stack.h +++ b/examples/testbed/tests/box_stack.h @@ -31,9 +31,6 @@ public: BoxStack() { - g_camera.m_center.Set(2.5f, -2.0f, 5.5f); - g_camera.m_zoom = 40.0f; - { b3BodyDef bdef; bdef.type = b3BodyType::e_staticBody; @@ -52,14 +49,6 @@ public: b3Vec3 boxScale(1.0f, 1.0f, 1.0f); - static b3BoxHull boxHull; - - b3Transform m; - m.rotation = b3Diagonal(boxScale.x, boxScale.y, boxScale.z); - m.position.SetZero(); - - boxHull.SetTransform(m); - b3Vec3 stackOrigin(0.0f, 4.05f, 0.0f); for (u32 i = 0; i < e_rowCount; ++i) @@ -81,7 +70,7 @@ public: b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sdef; sdef.density = 0.1f; diff --git a/examples/testbed/tests/cloth_test.h b/examples/testbed/tests/cloth_test.h index 9cd3540..32d29a5 100644 --- a/examples/testbed/tests/cloth_test.h +++ b/examples/testbed/tests/cloth_test.h @@ -19,17 +19,11 @@ #ifndef CLOTH_H #define CLOTH_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class Cloth : public Test { public: Cloth() { - g_camera.m_zoom = 25.0f; - b3ClothDef def; def.mesh = &m_clothMesh; def.density = 0.2f; @@ -57,22 +51,8 @@ public: void Step() { - float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - dt = 0.0f; - } - } - - m_cloth.Step(dt, g_settings.positionIterations); - m_cloth.Draw(g_debugDraw); + m_cloth.Step(g_settings->inv_hertz, g_settings->positionIterations); + m_cloth.Draw(); } static Test* Create() diff --git a/examples/testbed/tests/cluster_test.h b/examples/testbed/tests/cluster_test.h index 3c05c59..2dc305e 100644 --- a/examples/testbed/tests/cluster_test.h +++ b/examples/testbed/tests/cluster_test.h @@ -21,16 +21,11 @@ #include -extern DebugDraw* g_debugDraw; -extern Camera g_camera; - class Cluster : public Test { public: Cluster() { - g_camera.m_zoom = 10.0f; - // Initialize observations for (u32 i = 0; i < 90; ++i) { diff --git a/examples/testbed/tests/collide_test.h b/examples/testbed/tests/collide_test.h index ea025b2..78e5cd8 100644 --- a/examples/testbed/tests/collide_test.h +++ b/examples/testbed/tests/collide_test.h @@ -19,16 +19,12 @@ #ifndef COLLIDE_H #define COLLIDE_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class Collide : public Test { public: Collide() { - g_camera.m_zoom = 25.0f; + } void Step() @@ -48,19 +44,19 @@ public: wm.Initialize(&manifold, m_shapeA->m_radius, m_xfA, m_shapeB->m_radius, m_xfB); b3Vec3 pw = wm.points[i].point; - b3Vec2 ps = g_camera.ConvertWorldToScreen(pw); + 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)); } - if (g_settings.drawFaces) + 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) + if (g_settings->drawVerticesEdges) { m_world.DrawShape(m_xfA, m_shapeA); m_world.DrawShape(m_xfB, m_shapeB); diff --git a/examples/testbed/tests/cone_test.h b/examples/testbed/tests/cone_test.h index f262fc2..dfa6691 100644 --- a/examples/testbed/tests/cone_test.h +++ b/examples/testbed/tests/cone_test.h @@ -24,11 +24,6 @@ class ConeTest : public Test public: ConeTest() { - g_camera.m_zoom = 15.0f; - g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.15f * B3_PI); - g_camera.m_q = g_camera.m_q * b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.2f * B3_PI); - g_camera.m_center.Set(0.0f, 0.0f, 0.0f); - b3Body* ref; b3Body* head; diff --git a/examples/testbed/tests/distance_test.h b/examples/testbed/tests/distance_test.h index 9a3a906..d5c4464 100644 --- a/examples/testbed/tests/distance_test.h +++ b/examples/testbed/tests/distance_test.h @@ -19,17 +19,11 @@ #ifndef DISTANCE_H #define DISTANCE_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class Distance : public Test { public: Distance() { - g_camera.m_zoom = 25.0f; - m_xfA.SetIdentity(); m_xfA.position.Set(-5.0f, 0.0f, 0.0f); m_xfA.rotation.SetIdentity(); @@ -40,7 +34,7 @@ public: m_xfB.SetIdentity(); m_xfB.position.Set(5.0f, 0.0f, 0.0f); m_xfB.rotation.SetIdentity(); - m_shapeB.m_hull = &m_boxHull; + m_shapeB.m_hull = &b3BoxHull_identity; m_proxyA.Set(&m_shapeA, 0); m_proxyB.Set(&m_shapeB, 0); diff --git a/examples/testbed/tests/gyro_test.h b/examples/testbed/tests/gyro_test.h index 38c7f9c..2dee7a1 100644 --- a/examples/testbed/tests/gyro_test.h +++ b/examples/testbed/tests/gyro_test.h @@ -21,10 +21,6 @@ #include -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class GyroTest : public Test { public: diff --git a/examples/testbed/tests/hinge_chain.h b/examples/testbed/tests/hinge_chain.h index 376b7e3..3cc2e6b 100644 --- a/examples/testbed/tests/hinge_chain.h +++ b/examples/testbed/tests/hinge_chain.h @@ -24,11 +24,6 @@ class HingeChain : public Test public: HingeChain() { - g_camera.m_zoom = 100.0f; - g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.15f * B3_PI); - g_camera.m_q = g_camera.m_q * b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.15f * B3_PI); - g_camera.m_center.SetZero(); - static b3BoxHull doorHull; { b3Transform xf; diff --git a/examples/testbed/tests/initial_overlap.h b/examples/testbed/tests/initial_overlap.h index c54576b..b3e7156 100644 --- a/examples/testbed/tests/initial_overlap.h +++ b/examples/testbed/tests/initial_overlap.h @@ -24,9 +24,6 @@ class InitialOverlap : public Test public: InitialOverlap() { - g_camera.m_center.Set(2.0f, -2.0f, 0.0f); - g_camera.m_zoom = 10.0f; - { b3BodyDef bd; b3Body* body = m_world.CreateBody(bd); diff --git a/examples/testbed/tests/jenga.h b/examples/testbed/tests/jenga.h index 377cad3..8695def 100644 --- a/examples/testbed/tests/jenga.h +++ b/examples/testbed/tests/jenga.h @@ -30,9 +30,6 @@ public: Jenga() { - g_camera.m_center.Set(2.0f, -2.0f, 0.0f); - g_camera.m_zoom = 60.0f; - { b3BodyDef bd; b3Body* body = m_world.CreateBody(bd); diff --git a/examples/testbed/tests/mass_spring.h b/examples/testbed/tests/mass_spring.h index 3d1204e..8c23b92 100644 --- a/examples/testbed/tests/mass_spring.h +++ b/examples/testbed/tests/mass_spring.h @@ -19,17 +19,11 @@ #ifndef MASS_SPRING_H #define MASS_SPRING_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class MassSpring : public Test { public: MassSpring() { - g_camera.m_zoom = 20.0f; - m_x.Set(0.0f, 5.0f, 0.0f); m_v.SetZero(); @@ -132,36 +126,18 @@ public: void Step() { - float32 h = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - h = 0.0f; - } - } + float32 h = g_settings->inv_hertz; Solve(h); g_debugDraw->DrawSolidSphere(m_x, 0.25f, b3Color_white); - b3Vec3 b3Vec3_zero; - b3Vec3_zero.SetZero(); g_debugDraw->DrawSegment(b3Vec3_zero, m_x, b3Color_white); - char text1[64]; - sprintf(text1, "Iterations = %u", m_iterations); - g_debugDraw->DrawString(text1, b3Color_white); + g_debugDraw->DrawString(b3Color_white, "Iterations = %u", m_iterations); - char text2[64]; float32 E = 0.5f * b3Dot(m_v, m_v); - sprintf(text2, "E = %f", E); - g_debugDraw->DrawString(text2, b3Color_white); + g_debugDraw->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 f788c6f..173d739 100644 --- a/examples/testbed/tests/mesh_contact_test.h +++ b/examples/testbed/tests/mesh_contact_test.h @@ -114,7 +114,7 @@ public: if (key == GLFW_KEY_H) { b3HullShape hull; - hull.m_hull = &m_boxHull; + hull.m_hull = &b3BoxHull_identity; b3ShapeDef sd; sd.shape = &hull; @@ -163,13 +163,11 @@ public: { Test::Step(); - b3Color color(1.0f, 1.0f, 1.0f); - - g_debugDraw->DrawString("S - Sphere", color); - g_debugDraw->DrawString("C - Capsule", color); - g_debugDraw->DrawString("H - Hull", color); - g_debugDraw->DrawString("G - Grid", color); - g_debugDraw->DrawString("T - Terrain", color); + 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"); } static Test* Create() diff --git a/examples/testbed/tests/multiple_pendulum.h b/examples/testbed/tests/multiple_pendulum.h index 4713aea..487b73f 100644 --- a/examples/testbed/tests/multiple_pendulum.h +++ b/examples/testbed/tests/multiple_pendulum.h @@ -24,8 +24,6 @@ class MultiplePendulum : public Test public: MultiplePendulum() { - g_camera.m_zoom = 10.0f; - b3Vec3 axis(0.0f, 0.0f, 1.0f); b3Body* bs[6]; diff --git a/examples/testbed/tests/multiple_shapes.h b/examples/testbed/tests/multiple_shapes.h index 4d4808f..f0fa841 100644 --- a/examples/testbed/tests/multiple_shapes.h +++ b/examples/testbed/tests/multiple_shapes.h @@ -24,8 +24,6 @@ class MultipleShapes : public Test public: MultipleShapes() { - g_settings.drawCenterOfMasses = true; - { b3BodyDef bd; b3Body* body = m_world.CreateBody(bd); diff --git a/examples/testbed/tests/pyramid.h b/examples/testbed/tests/pyramid.h index 06a8336..ecb3235 100644 --- a/examples/testbed/tests/pyramid.h +++ b/examples/testbed/tests/pyramid.h @@ -29,8 +29,6 @@ public: Pyramid() { - g_camera.m_zoom = 100.0f; - { b3BodyDef bd; b3Body* ground = m_world.CreateBody(bd); @@ -71,7 +69,7 @@ public: b3Body* body = m_world.CreateBody(bd); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sd; sd.shape = &hs; diff --git a/examples/testbed/tests/pyramids.h b/examples/testbed/tests/pyramids.h index 9ae0d16..60f4cff 100644 --- a/examples/testbed/tests/pyramids.h +++ b/examples/testbed/tests/pyramids.h @@ -30,8 +30,6 @@ public: Pyramids() { - g_camera.m_zoom = 100.0f; - { b3BodyDef bd; b3Body* ground = m_world.CreateBody(bd); @@ -74,7 +72,7 @@ public: b3Body* body = m_world.CreateBody(bd); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sd; sd.shape = &hs; diff --git a/examples/testbed/tests/quadric_shapes.h b/examples/testbed/tests/quadric_shapes.h index 30cb344..43de380 100644 --- a/examples/testbed/tests/quadric_shapes.h +++ b/examples/testbed/tests/quadric_shapes.h @@ -21,19 +21,11 @@ #include -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class QuadricShapes : public Test { public: QuadricShapes() { - g_camera.m_center.Set(2.0f, -2.0f, 0.0f); - g_camera.m_zoom = 20.0f; - g_settings.drawCenterOfMasses = true; - { b3BodyDef bd; b3Body* ground = m_world.CreateBody(bd); diff --git a/examples/testbed/tests/quickhull_test.h b/examples/testbed/tests/quickhull_test.h index 3b0a3ce..844484f 100644 --- a/examples/testbed/tests/quickhull_test.h +++ b/examples/testbed/tests/quickhull_test.h @@ -21,74 +21,6 @@ #include -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - -inline b3Vec3 ComputeCentroid(const b3Hull& h) -{ - b3Vec3 c(0.0f, 0.0f, 0.0f); - float32 volume = 0.0f; - - // Pick reference point not too away from the origin - // to minimize floating point rounding errors. - b3Vec3 p1(0.0f, 0.0f, 0.0f); - // Put it inside the hull. - for (u32 i = 0; i < h.vertexCount; ++i) - { - p1 += h.vertices[i]; - } - p1 *= 1.0f / float32(h.vertexCount); - - const float32 inv4 = 0.25f; - const float32 inv6 = 1.0f / 6.0f; - const float32 inv60 = 1.0f / 60.0f; - const float32 inv120 = 1.0f / 120.0f; - - b3Vec3 diag(0.0f, 0.0f, 0.0f); - b3Vec3 offDiag(0.0f, 0.0f, 0.0f); - - // Triangulate convex polygons - for (u32 i = 0; i < h.faceCount; ++i) - { - const b3Face* face = h.GetFace(i); - const b3HalfEdge* begin = h.GetEdge(face->edge); - - const b3HalfEdge* edge = h.GetEdge(begin->next); - do - { - u32 i1 = begin->origin; - u32 i2 = edge->origin; - const b3HalfEdge* next = h.GetEdge(edge->next); - u32 i3 = next->origin; - - b3Vec3 p2 = h.vertices[i1]; - b3Vec3 p3 = h.vertices[i2]; - b3Vec3 p4 = h.vertices[i3]; - - b3Vec3 e1 = p2 - p1; - b3Vec3 e2 = p3 - p1; - b3Vec3 e3 = p4 - p1; - - float32 D = b3Det(e1, e2, e3); - - float32 tetraVolume = inv6 * D; - volume += tetraVolume; - - // Volume weighted centroid - c += tetraVolume * inv4 * (e1 + e2 + e3); - - edge = next; - } while (h.GetEdge(edge->next) != begin); - } - - // Centroid - B3_ASSERT(volume > B3_EPSILON); - c *= 1.0f / volume; - c += p1; - return c; -} - struct Pair { void* key; @@ -259,7 +191,7 @@ inline b3Hull ConvertHull(const qhHull& hull) out.faceCount = faceCount; out.faces = faces; out.planes = planes; - out.centroid = ComputeCentroid(out); + out.centroid = out.GetCentroid(); out.Validate(); return out; } @@ -347,8 +279,6 @@ class QuickhullTest : public Test public: QuickhullTest() { - g_camera.m_zoom = 15.0f; - b3BoxHull box; box.SetIdentity(); diff --git a/examples/testbed/tests/ray_cast.h b/examples/testbed/tests/ray_cast.h index 524aa96..2255741 100644 --- a/examples/testbed/tests/ray_cast.h +++ b/examples/testbed/tests/ray_cast.h @@ -19,8 +19,6 @@ #ifndef RAY_CAST_H #define RAY_CAST_H -extern Settings g_settings; - class RayCast : public Test { public: @@ -49,7 +47,7 @@ public: b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sdef; sdef.shape = &hs; @@ -91,7 +89,7 @@ public: b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sdef; sdef.density = 0.0f; @@ -111,7 +109,7 @@ public: b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sdef; sdef.density = 0.0f; @@ -131,7 +129,7 @@ public: b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sdef; sdef.density = 0.0f; @@ -151,7 +149,7 @@ public: b3Body* body = m_world.CreateBody(bdef); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; b3ShapeDef sdef; sdef.density = 0.0f; @@ -228,7 +226,8 @@ public: void Step() { - float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; + float32 dt = g_settings->inv_hertz; + b3Quat q(b3Vec3(0.0f, 1.0f, 0.0f), dt * 0.05f * B3_PI); m_p1 = b3Mul(q, m_p1); @@ -252,4 +251,4 @@ public: b3Vec3 m_p12, m_p22; }; -#endif +#endif \ No newline at end of file diff --git a/examples/testbed/tests/rope_test.h b/examples/testbed/tests/rope_test.h index 6699a14..5e41bfe 100644 --- a/examples/testbed/tests/rope_test.h +++ b/examples/testbed/tests/rope_test.h @@ -19,8 +19,6 @@ #ifndef ROPE_TEST_H #define ROPE_TEST_H -extern Settings g_settings; - class Rope : public Test { public: @@ -31,8 +29,6 @@ public: Rope() { - g_camera.m_zoom = 30.0f; - b3Vec3 vs[e_count]; float32 ms[e_count]; @@ -89,22 +85,8 @@ public: void Step() { - float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - dt = 0.0f; - } - } - - m_rope.Step(dt); - m_rope.Draw(g_debugDraw); + m_rope.Step(g_settings->inv_hertz); + m_rope.Draw(); } static Test* Create() diff --git a/examples/testbed/tests/shape_stack.h b/examples/testbed/tests/shape_stack.h index f4f1ef1..a22b6ba 100644 --- a/examples/testbed/tests/shape_stack.h +++ b/examples/testbed/tests/shape_stack.h @@ -89,7 +89,7 @@ public: b3Body* body = m_world.CreateBody(bd); b3HullShape hull; - hull.m_hull = &m_boxHull; + hull.m_hull = &b3BoxHull_identity; b3ShapeDef sd; sd.shape = &hull; diff --git a/examples/testbed/tests/shift_center.h b/examples/testbed/tests/shift_center.h index 29e0246..8abb0e3 100644 --- a/examples/testbed/tests/shift_center.h +++ b/examples/testbed/tests/shift_center.h @@ -21,19 +21,11 @@ #include -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class ShiftCenter : public Test { public: ShiftCenter() { - g_camera.m_center.Set(2.0f, -2.0f, 0.0f); - g_camera.m_zoom = 20.0f; - g_settings.drawCenterOfMasses = true; - { b3BodyDef bd; b3Body* ground = m_world.CreateBody(bd); diff --git a/examples/testbed/tests/single_pendulum.h b/examples/testbed/tests/single_pendulum.h index 2432572..f8b3b63 100644 --- a/examples/testbed/tests/single_pendulum.h +++ b/examples/testbed/tests/single_pendulum.h @@ -19,9 +19,6 @@ #ifndef PENDULUM_H #define PENDULUM_H -extern Settings g_settings; -extern DebugDraw* g_debugDraw; - class SinglePendulum : public Test { public: @@ -40,19 +37,7 @@ public: void Step() { - float32 h = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - h = 0.0f; - } - } + float32 h = g_settings->inv_hertz; // Solution (acceleration) float32 omega_dot = -m_g / m_r * sin(m_theta); @@ -83,9 +68,8 @@ public: // Lagrangian float32 L = T - V; - static char s[256]; - sprintf(s, "T = %f \nV = %f \nL = %f", T, V, L); - g_debugDraw->DrawString(s, b3Color_white); + // + g_debugDraw->DrawString(b3Color_white, "T = %f \nV = %f \nL = %f", T, V, L); } static Test* Create() diff --git a/examples/testbed/tests/spring_cloth.h b/examples/testbed/tests/spring_cloth.h index 8444b3c..fc99ed2 100644 --- a/examples/testbed/tests/spring_cloth.h +++ b/examples/testbed/tests/spring_cloth.h @@ -19,10 +19,6 @@ #ifndef SPRING_CLOTH_H #define SPRING_CLOTH_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class SpringCloth : public SpringClothTest { public: diff --git a/examples/testbed/tests/spring_cloth_collision_test.h b/examples/testbed/tests/spring_cloth_collision_test.h index 1328694..35c4bbf 100644 --- a/examples/testbed/tests/spring_cloth_collision_test.h +++ b/examples/testbed/tests/spring_cloth_collision_test.h @@ -19,10 +19,6 @@ #ifndef SPRING_CLOTH_COLLISION_H #define SPRING_CLOTH_COLLISION_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class SpringClothCollision : public SpringClothTest { public: diff --git a/examples/testbed/tests/spring_cloth_test.h b/examples/testbed/tests/spring_cloth_test.h index 8767dae..e101908 100644 --- a/examples/testbed/tests/spring_cloth_test.h +++ b/examples/testbed/tests/spring_cloth_test.h @@ -19,10 +19,6 @@ #ifndef SPRING_CLOTH_TESH_H #define SPRING_CLOTH_TESH_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class ClothDragger { public: @@ -208,28 +204,16 @@ class SpringClothTest : public Test public: SpringClothTest() : m_clothDragger(&m_clothRay, &m_cloth) { - g_camera.m_zoom = 25.0f; + 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; + m_clothRay.fraction = g_camera->m_zFar; } void Step() { - float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - dt = 0.0f; - } - } + float32 dt = g_settings->inv_hertz; m_cloth.Step(dt); m_cloth.Apply(); @@ -245,13 +229,11 @@ public: g_debugDraw->DrawShape(s, b3Color_white, xf); } - m_cloth.Draw(g_debugDraw); + m_cloth.Draw(); b3SpringClothStep step = m_cloth.GetStep(); - char text[256]; - sprintf(text, "Iterations = %u", step.iterations); - g_debugDraw->DrawString(text, b3Color_white); + g_debugDraw->DrawString(b3Color_white, "Iterations = %u", step.iterations); if (m_clothDragger.IsSelected() == true) { diff --git a/examples/testbed/tests/tension_mapping.h b/examples/testbed/tests/tension_mapping.h index e824a66..19afa90 100644 --- a/examples/testbed/tests/tension_mapping.h +++ b/examples/testbed/tests/tension_mapping.h @@ -19,10 +19,6 @@ #ifndef TENSION_MAPPING_H #define TENSION_MAPPING_H -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - // Hot/Cold color map // See http://paulbourke.net/miscellaneous/colourspace/ static inline b3Color Color(float32 x, float32 a, float32 b) @@ -88,19 +84,7 @@ public: void Step() { - float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f; - - if (g_settings.pause) - { - if (g_settings.singleStep) - { - g_settings.singleStep = false; - } - else - { - dt = 0.0f; - } - } + float32 dt = g_settings->inv_hertz; m_cloth.Step(dt); m_cloth.Apply(); @@ -141,9 +125,7 @@ public: b3SpringClothStep step = m_cloth.GetStep(); - char text[256]; - sprintf(text, "Iterations = %u", step.iterations); - g_debugDraw->DrawString(text, b3Color_white); + g_debugDraw->DrawString(b3Color_white, "Iterations = %u", step.iterations); if (m_clothDragger.IsSelected() == true) { diff --git a/examples/testbed/tests/test.h b/examples/testbed/tests/test.h index fcce8af..3b3fed8 100644 --- a/examples/testbed/tests/test.h +++ b/examples/testbed/tests/test.h @@ -36,11 +36,13 @@ inline float32 RandomFloat(float32 a, float32 b) return a + r; } +// Test settings struct Settings { Settings() { hertz = 60.0f; + inv_hertz = 1.0f / hertz; velocityIterations = 8; positionIterations = 2; sleep = false; @@ -69,7 +71,7 @@ struct Settings bool pause; bool singleStep; - float32 hertz; + float32 hertz, inv_hertz; int velocityIterations; int positionIterations; bool sleep; @@ -91,16 +93,7 @@ struct Settings bool drawGrid; }; -class Test; - -struct TestEntry -{ - typedef Test* (*TestCreate)(); - const char* name; - TestCreate create; -}; - -extern TestEntry g_tests[]; +extern Settings* g_settings; class RayCastListener : public b3RayCastListener { @@ -123,11 +116,14 @@ public: Test(); virtual ~Test(); - virtual void BeginContact(b3Contact* contact); - virtual void EndContact(b3Contact* contact); - virtual void PreSolve(b3Contact* contact); + virtual void BeginContact(b3Contact* contact) { } + virtual void EndContact(b3Contact* contact) { } + virtual void PreSolve(b3Contact* contact) { } virtual void Step(); + + virtual void Dump() { } + virtual void RayHit(); virtual void MouseMove(const Ray3& pw); @@ -136,16 +132,22 @@ public: virtual void KeyDown(int button) { } virtual void KeyUp(int button) { } - virtual void Dump() { } - b3World m_world; b3RayCastSingleOutput m_rayHit; b3MouseJoint* m_mouseJoint; - - b3BoxHull m_boxHull; - + b3BoxHull m_groundHull; b3GridMesh<50, 50> m_groundMesh; }; +struct TestEntry +{ + typedef Test* (*TestCreate)(); + const char* name; + TestCreate create; +}; + +extern TestEntry g_tests[]; +extern u32 g_testCount; + #endif \ No newline at end of file diff --git a/examples/testbed/tests/thin.h b/examples/testbed/tests/thin.h index 7073591..88ddf5c 100644 --- a/examples/testbed/tests/thin.h +++ b/examples/testbed/tests/thin.h @@ -31,9 +31,6 @@ public: Thin() { - g_camera.m_center.Set(2.5f, -2.0f, 5.5f); - g_camera.m_zoom = 40.0f; - { b3BodyDef bdef; bdef.type = b3BodyType::e_staticBody; diff --git a/examples/testbed/tests/tumbler.h b/examples/testbed/tests/tumbler.h index c1705d8..d1405a2 100644 --- a/examples/testbed/tests/tumbler.h +++ b/examples/testbed/tests/tumbler.h @@ -21,10 +21,6 @@ #include -extern DebugDraw* g_debugDraw; -extern Camera g_camera; -extern Settings g_settings; - class Tumbler : public Test { public: @@ -35,10 +31,6 @@ public: Tumbler() { - g_camera.m_center.Set(0.0f, 10.0f, 0.0f); - g_camera.m_q.SetIdentity(); - g_camera.m_zoom = 150.0f; - { b3BodyDef bd; b3Body* ground = m_world.CreateBody(bd); diff --git a/examples/testbed/tests/varying_friction.h b/examples/testbed/tests/varying_friction.h index d9951c0..0a1c2ab 100644 --- a/examples/testbed/tests/varying_friction.h +++ b/examples/testbed/tests/varying_friction.h @@ -24,10 +24,6 @@ class VaryingFriction : public Test public: VaryingFriction() { - g_camera.m_zoom = 200.0f; - g_camera.m_q = b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.1f * B3_PI); - g_camera.m_q = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.1f * B3_PI) * g_camera.m_q; - { b3BodyDef bdef; b3Body* ground = m_world.CreateBody(bdef); @@ -35,9 +31,9 @@ public: b3HullShape hs; hs.m_hull = &m_groundHull; - b3ShapeDef sdef; - sdef.shape = &hs; - ground->CreateShape(sdef); + b3ShapeDef sd; + sd.shape = &hs; + ground->CreateShape(sd); } static b3BoxHull rampHull; @@ -59,10 +55,10 @@ public: b3HullShape hs; hs.m_hull = &rampHull; - b3ShapeDef sdef; - sdef.shape = &hs; - sdef.friction = 0.4f; - ramp->CreateShape(sdef); + b3ShapeDef sd; + sd.shape = &hs; + sd.friction = 0.4f; + ramp->CreateShape(sd); } { @@ -75,10 +71,10 @@ public: b3HullShape hs; hs.m_hull = &rampHull; - b3ShapeDef sdef; - sdef.shape = &hs; - sdef.friction = 0.3f; - ramp->CreateShape(sdef); + b3ShapeDef sd; + sd.shape = &hs; + sd.friction = 0.3f; + ramp->CreateShape(sd); } { @@ -91,10 +87,10 @@ public: b3HullShape hs; hs.m_hull = &rampHull; - b3ShapeDef sdef; - sdef.shape = &hs; - sdef.friction = 0.2f; - ramp->CreateShape(sdef); + b3ShapeDef sd; + sd.shape = &hs; + sd.friction = 0.2f; + ramp->CreateShape(sd); } { @@ -107,10 +103,10 @@ public: b3HullShape hs; hs.m_hull = &rampHull; - b3ShapeDef sdef; - sdef.shape = &hs; - sdef.friction = 0.1f; - ramp->CreateShape(sdef); + b3ShapeDef sd; + sd.shape = &hs; + sd.friction = 0.1f; + ramp->CreateShape(sd); } { @@ -120,14 +116,14 @@ public: b3Body* body = m_world.CreateBody(bd); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; - b3ShapeDef sdef; - sdef.density = 1.0f; - sdef.friction = 0.2f; - sdef.shape = &hs; + b3ShapeDef sd; + sd.density = 1.0f; + sd.friction = 0.2f; + sd.shape = &hs; - body->CreateShape(sdef); + body->CreateShape(sd); } { @@ -137,14 +133,14 @@ public: b3Body* body = m_world.CreateBody(bd); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; - b3ShapeDef sdef; - sdef.density = 1.0f; - sdef.friction = 0.5f; - sdef.shape = &hs; + b3ShapeDef sd; + sd.density = 1.0f; + sd.friction = 0.5f; + sd.shape = &hs; - body->CreateShape(sdef); + body->CreateShape(sd); } { @@ -154,14 +150,14 @@ public: b3Body* body = m_world.CreateBody(bd); b3HullShape hs; - hs.m_hull = &m_boxHull; + hs.m_hull = &b3BoxHull_identity; - b3ShapeDef sdef; - sdef.density = 1.0f; - sdef.friction = 0.8f; - sdef.shape = &hs; + b3ShapeDef sd; + sd.density = 1.0f; + sd.friction = 0.8f; + sd.shape = &hs; - body->CreateShape(sdef); + body->CreateShape(sd); } } @@ -171,4 +167,4 @@ public: } }; -#endif +#endif \ No newline at end of file diff --git a/include/bounce/collision/broad_phase.h b/include/bounce/collision/broad_phase.h index 8ac1efe..1b15376 100644 --- a/include/bounce/collision/broad_phase.h +++ b/include/bounce/collision/broad_phase.h @@ -77,7 +77,7 @@ public: void FindNewPairs(T* callback); // Draw the proxy AABBs. - void Draw(b3Draw* draw) const; + void Draw() const; private : friend class b3DynamicTree; @@ -189,9 +189,9 @@ inline void b3BroadPhase::FindNewPairs(T* callback) } } -inline void b3BroadPhase::Draw(b3Draw* draw) const +inline void b3BroadPhase::Draw() const { - m_tree.Draw(draw); + m_tree.Draw(); } #endif \ No newline at end of file diff --git a/include/bounce/collision/sat/sat_edge_and_hull.h b/include/bounce/collision/sat/sat_edge_and_hull.h index 2eabc74..60ecb2f 100644 --- a/include/bounce/collision/sat/sat_edge_and_hull.h +++ b/include/bounce/collision/sat/sat_edge_and_hull.h @@ -21,20 +21,20 @@ #include -struct b3Segment; +struct b3Capsule; /////////////////////////////////////////////////////////////////////////////////////////////////// -float32 b3ProjectEdge(const b3Segment* hull, const b3Plane& plane); +float32 b3ProjectEdge(const b3Capsule* hull, const b3Plane& plane); -b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Segment* hull1, +b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Capsule* hull1, const b3Transform& xf2, const b3Hull* hull2); /////////////////////////////////////////////////////////////////////////////////////////////////// float32 b3ProjectEdge(const b3Vec3& P1, const b3Vec3& E1, const b3Vec3& P2, const b3Vec3& E2, const b3Vec3& C2); -b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xf1, const b3Segment* hull1, +b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xf1, const b3Capsule* hull1, const b3Transform& xf2, const b3Hull* hull2); #endif \ No newline at end of file diff --git a/include/bounce/collision/sat/sat_vertex_and_hull.h b/include/bounce/collision/sat/sat_vertex_and_hull.h index 86ad9d2..52a59d5 100644 --- a/include/bounce/collision/sat/sat_vertex_and_hull.h +++ b/include/bounce/collision/sat/sat_vertex_and_hull.h @@ -21,11 +21,13 @@ #include +struct b3Sphere; + /////////////////////////////////////////////////////////////////////////////////////////////////// -float32 b3ProjectVertex(const b3Vec3& hull, const b3Plane& plane); +float32 b3ProjectVertex(const b3Sphere* hull, const b3Plane& plane); -b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Vec3& hull1, +b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Sphere* hull1, const b3Transform& xf2, const b3Hull* hull2); #endif diff --git a/include/bounce/collision/shapes/box_hull.h b/include/bounce/collision/shapes/box_hull.h index ef20564..5d384fa 100644 --- a/include/bounce/collision/shapes/box_hull.h +++ b/include/bounce/collision/shapes/box_hull.h @@ -31,6 +31,12 @@ struct b3BoxHull : public b3Hull // Does nothing for performance. b3BoxHull() { } + // Construct this box from three extents and centered at the origin. + b3BoxHull(float32 ex, float32 ey, float32 ez) + { + Set(ex, ey, ez); + } + // Set this box to the unit box centered at the origin. void SetIdentity() { @@ -174,4 +180,6 @@ struct b3BoxHull : public b3Hull } }; +extern const b3BoxHull b3BoxHull_identity; + #endif \ No newline at end of file diff --git a/include/bounce/collision/shapes/capsule.h b/include/bounce/collision/shapes/capsule.h index 012fe66..3c5464b 100644 --- a/include/bounce/collision/shapes/capsule.h +++ b/include/bounce/collision/shapes/capsule.h @@ -21,20 +21,38 @@ #include -struct b3Segment +struct b3Capsule { + // + b3Capsule() { } + + // + b3Capsule(const b3Vec3& v1, const b3Vec3& v2, float32 r) + { + vertices[0] = v1; + vertices[1] = v2; + radius = r; + } + + // + ~b3Capsule() { } + b3Vec3 vertices[2]; - + float32 radius; + const b3Vec3& GetVertex(u32 index) const; u32 GetSupportVertex(const b3Vec3& direction) const; }; -inline const b3Vec3& b3Segment::GetVertex(u32 index) const +// Unit capsule centered at the origin +extern const b3Capsule b3Capsule_identity; + +inline const b3Vec3& b3Capsule::GetVertex(u32 index) const { return vertices[index]; } -inline u32 b3Segment::GetSupportVertex(const b3Vec3& d) const +inline u32 b3Capsule::GetSupportVertex(const b3Vec3& d) const { if (b3Dot(d, vertices[0]) > b3Dot(d, vertices[1])) { diff --git a/include/bounce/collision/shapes/hull.h b/include/bounce/collision/shapes/hull.h index cc27c47..afd1285 100644 --- a/include/bounce/collision/shapes/hull.h +++ b/include/bounce/collision/shapes/hull.h @@ -57,6 +57,9 @@ struct b3Hull b3Plane GetEdgeSidePlane(u32 index) const; u32 GetSize() const; + + b3Vec3 GetCentroid() const; + void Validate() const; void Validate(const b3Face* face) const; void Validate(const b3HalfEdge* edge) const; diff --git a/include/bounce/collision/shapes/sphere.h b/include/bounce/collision/shapes/sphere.h index 8d32ff1..7156fb0 100644 --- a/include/bounce/collision/shapes/sphere.h +++ b/include/bounce/collision/shapes/sphere.h @@ -23,6 +23,19 @@ struct b3Sphere { + // + b3Sphere() { } + + // + b3Sphere(const b3Vec3& v, float32 r) + { + vertex = v; + radius = r; + } + + // + ~b3Sphere() { } + b3Vec3 vertex; float32 radius; @@ -30,6 +43,9 @@ struct b3Sphere u32 GetSupportVertex(const b3Vec3& direction) const; }; +// Unit sphere centered at origin +extern const b3Sphere b3Sphere_identity; + inline const b3Vec3& b3Sphere::GetVertex(u32 index) const { B3_NOT_USED(index); diff --git a/include/bounce/collision/trees/dynamic_tree.h b/include/bounce/collision/trees/dynamic_tree.h index c9dd089..29e9bb3 100644 --- a/include/bounce/collision/trees/dynamic_tree.h +++ b/include/bounce/collision/trees/dynamic_tree.h @@ -19,7 +19,6 @@ #ifndef B3_DYNAMIC_TREE_H #define B3_DYNAMIC_TREE_H -#include #include #include #include @@ -67,7 +66,7 @@ public : void Validate(i32 node) const; // Draw this tree. - void Draw(b3Draw* draw) const; + void Draw() const; private : struct b3Node { diff --git a/include/bounce/collision/trees/static_tree.h b/include/bounce/collision/trees/static_tree.h index cac8ba7..2085ca6 100644 --- a/include/bounce/collision/trees/static_tree.h +++ b/include/bounce/collision/trees/static_tree.h @@ -19,7 +19,6 @@ #ifndef B3_STATIC_TREE_H #define B3_STATIC_TREE_H -#include #include #include #include @@ -55,7 +54,7 @@ public: void RayCast(T* callback, const b3RayCastInput& input) const; // Draw this tree. - void Draw(b3Draw* draw) const; + void Draw() const; u32 GetSize() const; private : diff --git a/include/bounce/common/draw.h b/include/bounce/common/draw.h index 98e66bc..cbb2b51 100644 --- a/include/bounce/common/draw.h +++ b/include/bounce/common/draw.h @@ -117,6 +117,11 @@ public : u32 m_flags; }; +// The debug drawer interface used by Bounce. +// You should set this to an implementation +// before calling any function that uses the interface. +extern b3Draw* b3Draw_draw; + inline void b3Draw::SetFlags(u32 flags) { m_flags = flags; diff --git a/include/bounce/common/math/mat22.h b/include/bounce/common/math/mat22.h index cfdda1c..bc66b82 100644 --- a/include/bounce/common/math/mat22.h +++ b/include/bounce/common/math/mat22.h @@ -46,6 +46,12 @@ struct b3Mat22 b3Vec2 x, y; }; +// Zero matrix +extern const b3Mat22 b3Mat22_zero; + +// Identity matrix +extern const b3Mat22 b3Mat22_identity; + // Multiply a matrix times a vector. inline b3Vec2 operator*(const b3Mat22& A, const b3Vec2& v) { diff --git a/include/bounce/common/math/mat33.h b/include/bounce/common/math/mat33.h index 07d3452..3696e22 100644 --- a/include/bounce/common/math/mat33.h +++ b/include/bounce/common/math/mat33.h @@ -90,8 +90,8 @@ struct b3Mat33 }; // Usefull constants. -extern b3Mat33 b3Mat33_zero; -extern b3Mat33 b3Mat33_identity; +extern const b3Mat33 b3Mat33_zero; +extern const b3Mat33 b3Mat33_identity; // Add two matrices. inline b3Mat33 operator+(const b3Mat33& A, const b3Mat33& B) diff --git a/include/bounce/common/math/quat.h b/include/bounce/common/math/quat.h index 4d5ebc1..eb5d8c9 100644 --- a/include/bounce/common/math/quat.h +++ b/include/bounce/common/math/quat.h @@ -141,6 +141,9 @@ struct b3Quat float32 x, y, z, w; }; +// Identity quaternion +extern const b3Quat b3Quat_identity; + // Add two quaternions. inline b3Quat operator+(const b3Quat& a, const b3Quat& b) { diff --git a/include/bounce/common/math/transform.h b/include/bounce/common/math/transform.h index f3a45a8..7169251 100644 --- a/include/bounce/common/math/transform.h +++ b/include/bounce/common/math/transform.h @@ -31,6 +31,13 @@ struct b3Transform // Default ctor does nothing for performance. b3Transform() { } + // Set this transform from a rotation matrix and a translation vector. + b3Transform(const b3Mat33& _rotation, const b3Vec3& _translation) + { + rotation = _rotation; + position = _translation; + } + // Set this transform from a rotation quaternion and a translation vector. b3Transform(const b3Quat& _rotation, const b3Vec3& _translation) { @@ -49,6 +56,9 @@ struct b3Transform b3Vec3 position; // in fact a translation }; +// Identity transformation +extern const b3Transform b3Transform_identity; + // Multiply a transform times a vector. inline b3Vec3 b3Mul(const b3Transform& T, const b3Vec3& v) { diff --git a/include/bounce/common/math/vec2.h b/include/bounce/common/math/vec2.h index 1fe96d3..4fcaac9 100644 --- a/include/bounce/common/math/vec2.h +++ b/include/bounce/common/math/vec2.h @@ -91,6 +91,15 @@ struct b3Vec2 float32 x, y; }; +// Zero vector +extern const b3Vec2 b3Vec2_zero; + +// Left vector +extern const b3Vec2 b3Vec2_x; + +// Right vector +extern const b3Vec2 b3Vec2_y; + // Negate a vector. inline b3Vec2 operator-(const b3Vec2& v) { diff --git a/include/bounce/common/math/vec3.h b/include/bounce/common/math/vec3.h index 66a6cca..0b04bda 100644 --- a/include/bounce/common/math/vec3.h +++ b/include/bounce/common/math/vec3.h @@ -106,6 +106,18 @@ struct b3Vec3 float32 x, y, z; }; +// Zero vector +extern const b3Vec3 b3Vec3_zero; + +// Right vector +extern const b3Vec3 b3Vec3_x; + +// Up vector +extern const b3Vec3 b3Vec3_y; + +// Forward vector +extern const b3Vec3 b3Vec3_z; + // Negate a vector. inline b3Vec3 operator-(const b3Vec3& v) { diff --git a/include/bounce/dynamics/cloth/cloth.h b/include/bounce/dynamics/cloth/cloth.h index 9a27afa..84aca19 100644 --- a/include/bounce/dynamics/cloth/cloth.h +++ b/include/bounce/dynamics/cloth/cloth.h @@ -23,7 +23,6 @@ #include struct b3Mesh; -class b3Draw; struct b3ClothDef { @@ -110,7 +109,7 @@ public: return m_ps; } - void Draw(b3Draw* draw) const; + void Draw() const; private: void SolveC1(); void SolveC2(); diff --git a/include/bounce/dynamics/cloth/spring_cloth.h b/include/bounce/dynamics/cloth/spring_cloth.h index 5e20a08..9d9eb0c 100644 --- a/include/bounce/dynamics/cloth/spring_cloth.h +++ b/include/bounce/dynamics/cloth/spring_cloth.h @@ -25,7 +25,6 @@ #define B3_CLOTH_SHAPE_CAPACITY 32 class b3StackAllocator; -class b3Draw; class b3Shape; @@ -188,7 +187,7 @@ public: void Apply() const; // Debug draw the cloth mesh. - void Draw(b3Draw* draw) const; + void Draw() const; protected: friend class b3SpringSolver; diff --git a/include/bounce/dynamics/contacts/collide/clip.h b/include/bounce/dynamics/contacts/collide/clip.h index 7bae6c5..cb7ff55 100644 --- a/include/bounce/dynamics/contacts/collide/clip.h +++ b/include/bounce/dynamics/contacts/collide/clip.h @@ -75,11 +75,11 @@ struct b3ClipPlane }; struct b3Hull; -struct b3Segment; +struct b3Capsule; // Build a clip edge for an edge. void b3BuildEdge(b3ClipVertex vOut[2], - const b3Segment* hull); + const b3Capsule* hull); // Build a clip polygon given an index to the polygon face. void b3BuildPolygon(b3ClipPolygon& pOut, @@ -99,7 +99,7 @@ void b3ClipPolygonToPlane(b3ClipPolygon& pOut, // Clip a segment by a hull face (side planes). // Return the number of output points. u32 b3ClipEdgeToFace(b3ClipVertex vOut[2], - const b3ClipVertex vIn[2], const b3Segment* hull); + const b3ClipVertex vIn[2], const b3Capsule* hull); // Clip a segment by a hull face (side planes). // Return the number of output points. diff --git a/include/bounce/dynamics/joints/cone_joint.h b/include/bounce/dynamics/joints/cone_joint.h index 1d2b941..7f111cd 100644 --- a/include/bounce/dynamics/joints/cone_joint.h +++ b/include/bounce/dynamics/joints/cone_joint.h @@ -81,7 +81,7 @@ public: void SetConeAngle(float32 angle); // Draw this joint. - void Draw(b3Draw* draw) const; + void Draw() const; private: friend class b3Joint; friend class b3Body; diff --git a/include/bounce/dynamics/joints/joint.h b/include/bounce/dynamics/joints/joint.h index e552ebb..f973d99 100644 --- a/include/bounce/dynamics/joints/joint.h +++ b/include/bounce/dynamics/joints/joint.h @@ -24,7 +24,6 @@ #include #include -class b3Draw; class b3Body; class b3Joint; struct b3SolverData; @@ -116,6 +115,12 @@ public: b3Log("Dump feature not implemented for this joint type.\n"); } + // Draw this joint. + virtual void Draw() const + { + b3Log("Draw feature not implemented for this joint type.\n"); + } + // Get the next joint in the world joint list. const b3Joint* GetNext() const; b3Joint* GetNext(); diff --git a/include/bounce/dynamics/joints/mouse_joint.h b/include/bounce/dynamics/joints/mouse_joint.h index bb9af37..e044495 100644 --- a/include/bounce/dynamics/joints/mouse_joint.h +++ b/include/bounce/dynamics/joints/mouse_joint.h @@ -58,7 +58,7 @@ public: void SetTarget(const b3Vec3& target); // Draw this joint. - void Draw(b3Draw* draw) const; + void Draw() const; private: friend class b3Joint; friend class b3JointManager; diff --git a/include/bounce/dynamics/joints/revolute_joint.h b/include/bounce/dynamics/joints/revolute_joint.h index f17f98d..47214b8 100644 --- a/include/bounce/dynamics/joints/revolute_joint.h +++ b/include/bounce/dynamics/joints/revolute_joint.h @@ -132,7 +132,7 @@ public: void SetMaxMotorTorque(float32 torque); // Draw this joint. - void Draw(b3Draw* draw) const; + void Draw() const; private: friend class b3Joint; friend class b3JointManager; diff --git a/include/bounce/dynamics/joints/sphere_joint.h b/include/bounce/dynamics/joints/sphere_joint.h index aa9fac7..60e1782 100644 --- a/include/bounce/dynamics/joints/sphere_joint.h +++ b/include/bounce/dynamics/joints/sphere_joint.h @@ -52,7 +52,7 @@ public: b3Vec3 GetAnchorB() const; // Draw this joint. - void Draw(b3Draw* draw) const; + void Draw() const; private: friend class b3Joint; friend class b3JointManager; diff --git a/include/bounce/dynamics/joints/spring_joint.h b/include/bounce/dynamics/joints/spring_joint.h index f051610..7af9bcc 100644 --- a/include/bounce/dynamics/joints/spring_joint.h +++ b/include/bounce/dynamics/joints/spring_joint.h @@ -94,7 +94,7 @@ public: void SetDampingRatio(float32 ratio); // Draw this joint. - void Draw(b3Draw* draw) const; + void Draw() const; private: friend class b3Joint; friend class b3JointManager; diff --git a/include/bounce/dynamics/joints/weld_joint.h b/include/bounce/dynamics/joints/weld_joint.h index be60426..e6ced48 100644 --- a/include/bounce/dynamics/joints/weld_joint.h +++ b/include/bounce/dynamics/joints/weld_joint.h @@ -57,7 +57,7 @@ public: b3Vec3 GetAnchorB() const; // Draw this joint. - void Draw(b3Draw* draw) const; + void Draw() const; private: friend class b3Joint; friend class b3JointManager; diff --git a/include/bounce/dynamics/rope/rope.h b/include/bounce/dynamics/rope/rope.h index de3fc7a..4e04763 100644 --- a/include/bounce/dynamics/rope/rope.h +++ b/include/bounce/dynamics/rope/rope.h @@ -21,8 +21,6 @@ #include -class b3Draw; - struct b3RopeBody; // @@ -86,7 +84,7 @@ public: void Step(float32 dt); // - void Draw(b3Draw* draw) const; + void Draw() const; private: // float32 m_kd1, m_kd2; diff --git a/include/bounce/dynamics/world.h b/include/bounce/dynamics/world.h index a74710b..3251875 100644 --- a/include/bounce/dynamics/world.h +++ b/include/bounce/dynamics/world.h @@ -117,13 +117,11 @@ public: const b3List2& GetContactList() const; b3List2& GetContactList(); - // Debug draw the physics entities that belong to this world. - // The user must implement the debug draw interface b3Draw and b3_debugDraw must have been - // set to the user implementation. - void DebugDraw() const; + // Draw the entities in this world. + void Draw() const; + + // Draw a shape. void DrawShape(const b3Transform& xf, const b3Shape* shape) const; - void DrawJoint(const b3Joint* joint) const; - void DrawContact(const b3Contact* contact) const; private : enum b3Flags { @@ -144,7 +142,6 @@ private : bool m_warmStarting; u32 m_flags; b3Vec3 m_gravity; - b3Draw* m_debugDraw; b3StackAllocator m_stackAllocator; b3BlockPool m_bodyBlocks; diff --git a/premake5.lua b/premake5.lua index 38f7fc2..e33ea59 100644 --- a/premake5.lua +++ b/premake5.lua @@ -257,17 +257,33 @@ solution (solution_name) language "C++" location ( solution_dir .. action ) includedirs { external_dir, bounce_inc_dir, examples_inc_dir } - vpaths { ["Headers"] = "**.h", ["Sources"] = "**.cpp" } + vpaths { [""] = "testbed" } files { examples_inc_dir .. "/testbed/framework/debug_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", + examples_inc_dir .. "/testbed/framework/testbed_listener.h", + + examples_inc_dir .. "/testbed/framework/model.h", + examples_inc_dir .. "/testbed/framework/view.h", + examples_inc_dir .. "/testbed/framework/controller.h", + examples_inc_dir .. "/testbed/tests/**.h", examples_src_dir .. "/testbed/framework/profiler.cpp", + examples_src_dir .. "/testbed/framework/recorder_profiler.cpp", + examples_src_dir .. "/testbed/framework/json_profiler.cpp", + + examples_inc_dir .. "/testbed/framework/model.cpp", + examples_inc_dir .. "/testbed/framework/view.cpp", + examples_inc_dir .. "/testbed/framework/controller.cpp", + examples_src_dir .. "/testbed/framework/test.cpp", examples_src_dir .. "/testbed/framework/test_entries.cpp", + examples_src_dir .. "/testbed/framework/main.cpp" } diff --git a/src/bounce/collision/collision.cpp b/src/bounce/collision/collision.cpp new file mode 100644 index 0000000..9826e31 --- /dev/null +++ b/src/bounce/collision/collision.cpp @@ -0,0 +1,27 @@ +/* +* 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 +#include +#include + +const b3Sphere b3Sphere_identity(b3Vec3_zero, 1.0f); + +const b3Capsule b3Capsule_identity(b3Vec3(0.0f, -0.5f, 0.0f), b3Vec3(0.0f, 0.5f, 0.0f), 1.0f); + +const b3BoxHull b3BoxHull_identity(1.0f, 1.0f, 1.0f); \ No newline at end of file diff --git a/src/bounce/collision/sat/sat_edge_and_hull.cpp b/src/bounce/collision/sat/sat_edge_and_hull.cpp index ca6ca9a..fe639df 100644 --- a/src/bounce/collision/sat/sat_edge_and_hull.cpp +++ b/src/bounce/collision/sat/sat_edge_and_hull.cpp @@ -20,13 +20,13 @@ #include #include -float32 b3ProjectEdge(const b3Segment* hull, const b3Plane& plane) +float32 b3ProjectEdge(const b3Capsule* hull, const b3Plane& plane) { b3Vec3 support = hull->GetVertex(hull->GetSupportVertex(-plane.normal)); return b3Distance(support, plane); } -b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Segment* hull1, +b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Capsule* hull1, const b3Transform& xf2, const b3Hull* hull2) { // Perform computations in the local space of the first hull. @@ -95,7 +95,7 @@ float32 b3ProjectEdge(const b3Vec3& P1, const b3Vec3& E1, return b3Dot(N, P2 - P1); } -b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xf1, const b3Segment* hull1, const b3Transform& xf2, const b3Hull* hull2) +b3EdgeQuery b3QueryEdgeSeparation(const b3Transform& xf1, const b3Capsule* hull1, const b3Transform& xf2, const b3Hull* hull2) { // Query minimum edge separation. u32 maxIndex = 0; diff --git a/src/bounce/collision/sat/sat_vertex_and_hull.cpp b/src/bounce/collision/sat/sat_vertex_and_hull.cpp index b3ea83c..96a4b81 100644 --- a/src/bounce/collision/sat/sat_vertex_and_hull.cpp +++ b/src/bounce/collision/sat/sat_vertex_and_hull.cpp @@ -20,17 +20,17 @@ #include #include -float32 b3ProjectVertex(const b3Vec3& hull, const b3Plane& plane) +float32 b3ProjectVertex(const b3Sphere* hull, const b3Plane& plane) { - b3Vec3 support = hull; + b3Vec3 support = hull->GetVertex(hull->GetSupportVertex(-plane.normal)); return b3Distance(support, plane); } -b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Vec3& hull, +b3FaceQuery b3QueryFaceSeparation(const b3Transform& xf1, const b3Sphere* hull, const b3Transform& xf2, const b3Hull* hull2) { // Perform computations in the local space of the second hull. - b3Vec3 support = b3MulT(xf2, b3Mul(xf1, hull)); + b3Vec3 support = b3MulT(xf2, b3Mul(xf1, hull->vertex)); u32 maxIndex = 0; float32 maxSeparation = -B3_MAX_FLOAT; diff --git a/src/bounce/collision/shapes/hull.cpp b/src/bounce/collision/shapes/hull.cpp index 5dbcd19..5347e06 100644 --- a/src/bounce/collision/shapes/hull.cpp +++ b/src/bounce/collision/shapes/hull.cpp @@ -77,4 +77,70 @@ void b3Hull::Validate(const b3HalfEdge* e) const B3_ASSERT(count < edgeCount); ++count; } while (e != begin); +} + +b3Vec3 b3Hull::GetCentroid() const +{ + Validate(); + + b3Vec3 c(0.0f, 0.0f, 0.0f); + float32 volume = 0.0f; + + // Pick reference point not too away from the origin + // to minimize floating point rounding errors. + b3Vec3 p1(0.0f, 0.0f, 0.0f); + // Put it inside the hull. + for (u32 i = 0; i < vertexCount; ++i) + { + p1 += vertices[i]; + } + p1 /= float32(vertexCount); + + const float32 inv4 = 0.25f; + const float32 inv6 = 1.0f / 6.0f; + const float32 inv60 = 1.0f / 60.0f; + const float32 inv120 = 1.0f / 120.0f; + + b3Vec3 diag(0.0f, 0.0f, 0.0f); + b3Vec3 offDiag(0.0f, 0.0f, 0.0f); + + // Triangulate convex polygons + for (u32 i = 0; i < faceCount; ++i) + { + const b3Face* face = GetFace(i); + const b3HalfEdge* begin = GetEdge(face->edge); + + const b3HalfEdge* edge = GetEdge(begin->next); + do + { + u32 i1 = begin->origin; + u32 i2 = edge->origin; + const b3HalfEdge* next = GetEdge(edge->next); + u32 i3 = next->origin; + + b3Vec3 p2 = vertices[i1]; + b3Vec3 p3 = vertices[i2]; + b3Vec3 p4 = vertices[i3]; + + b3Vec3 e1 = p2 - p1; + b3Vec3 e2 = p3 - p1; + b3Vec3 e3 = p4 - p1; + + float32 D = b3Det(e1, e2, e3); + + float32 tetraVolume = inv6 * D; + volume += tetraVolume; + + // Volume weighted centroid + c += tetraVolume * inv4 * (e1 + e2 + e3); + + edge = next; + } while (GetEdge(edge->next) != begin); + } + + // Centroid + B3_ASSERT(volume > B3_EPSILON); + c /= volume; + c += p1; + return c; } \ No newline at end of file diff --git a/src/bounce/collision/trees/dynamic_tree.cpp b/src/bounce/collision/trees/dynamic_tree.cpp index ce54721..9485a71 100644 --- a/src/bounce/collision/trees/dynamic_tree.cpp +++ b/src/bounce/collision/trees/dynamic_tree.cpp @@ -17,6 +17,7 @@ */ #include +#include b3DynamicTree::b3DynamicTree() { @@ -362,7 +363,7 @@ void b3DynamicTree::Validate(i32 nodeID) const } } -void b3DynamicTree::Draw(b3Draw* draw) const +void b3DynamicTree::Draw() const { if (m_nodeCount == 0) { @@ -385,11 +386,11 @@ void b3DynamicTree::Draw(b3Draw* draw) const const b3Node* node = m_nodes + nodeIndex; if (node->IsLeaf()) { - draw->DrawAABB(node->aabb, b3Color_pink); + b3Draw_draw->DrawAABB(node->aabb, b3Color_pink); } else { - draw->DrawAABB(node->aabb, b3Color_red); + b3Draw_draw->DrawAABB(node->aabb, b3Color_red); stack.Push(node->child1); stack.Push(node->child2); diff --git a/src/bounce/collision/trees/static_tree.cpp b/src/bounce/collision/trees/static_tree.cpp index 5f3c104..6535ef1 100644 --- a/src/bounce/collision/trees/static_tree.cpp +++ b/src/bounce/collision/trees/static_tree.cpp @@ -18,6 +18,7 @@ #include #include +#include b3StaticTree::b3StaticTree() { @@ -178,7 +179,7 @@ void b3StaticTree::Build(const b3AABB3* set, u32 count) B3_ASSERT(m_nodeCount == nodeCapacity); } -void b3StaticTree::Draw(b3Draw* draw) const +void b3StaticTree::Draw() const { if (m_nodeCount == 0) { @@ -199,11 +200,11 @@ void b3StaticTree::Draw(b3Draw* draw) const const b3Node* node = m_nodes + nodeIndex; if (node->IsLeaf()) { - draw->DrawAABB(node->aabb, b3Color_pink); + b3Draw_draw->DrawAABB(node->aabb, b3Color_pink); } else { - draw->DrawAABB(node->aabb, b3Color_red); + b3Draw_draw->DrawAABB(node->aabb, b3Color_red); stack.Push(node->child1); stack.Push(node->child2); diff --git a/src/bounce/common/math/mat.cpp b/src/bounce/common/math/math.cpp similarity index 83% rename from src/bounce/common/math/mat.cpp rename to src/bounce/common/math/math.cpp index f1d744c..f50ff18 100644 --- a/src/bounce/common/math/mat.cpp +++ b/src/bounce/common/math/math.cpp @@ -16,28 +16,45 @@ * 3. This notice may not be removed or altered from any source distribution. */ +#include +#include + #include #include #include +#include -b3Mat22 b3Mat22_zero = b3Mat22( +const b3Vec2 b3Vec2_zero(0.0f, 0.0f); +const b3Vec2 b3Vec2_x(1.0f, 0.0f); +const b3Vec2 b3Vec2_y(0.0f, 1.0f); + +const b3Vec3 b3Vec3_zero(0.0f, 0.0f, 0.0f); +const b3Vec3 b3Vec3_x(1.0f, 0.0f, 0.0f); +const b3Vec3 b3Vec3_y(0.0f, 1.0f, 0.0f); +const b3Vec3 b3Vec3_z(0.0f, 0.0f, 1.0f); + +const b3Mat22 b3Mat22_zero( b3Vec2(0.0f, 0.0f), b3Vec2(0.0f, 0.0f)); -b3Mat22 b3Mat22_identity = b3Mat22( +const b3Mat22 b3Mat22_identity( b3Vec2(1.0f, 0.0f), b3Vec2(0.0f, 1.0f)); -b3Mat33 b3Mat33_zero = b3Mat33( +const b3Mat33 b3Mat33_zero( b3Vec3(0.0f, 0.0f, 0.0f), b3Vec3(0.0f, 0.0f, 0.0f), b3Vec3(0.0f, 0.0f, 0.0f)); -b3Mat33 b3Mat33_identity = b3Mat33( +const b3Mat33 b3Mat33_identity( b3Vec3(1.0f, 0.0f, 0.0f), b3Vec3(0.0f, 1.0f, 0.0f), b3Vec3(0.0f, 0.0f, 1.0f)); +const b3Transform b3Transform_identity(b3Mat33_identity, b3Vec3_zero); + +const b3Quat b3Quat_identity(0.0f, 0.0f, 0.0f, 1.0f); + b3Vec2 b3Mat22::Solve(const b3Vec2& b) const { // Cramer's rule diff --git a/src/bounce/dynamics/cloth/cloth.cpp b/src/bounce/dynamics/cloth/cloth.cpp index 830291b..534181c 100644 --- a/src/bounce/dynamics/cloth/cloth.cpp +++ b/src/bounce/dynamics/cloth/cloth.cpp @@ -368,13 +368,13 @@ void b3Cloth::SolveC2() } } -void b3Cloth::Draw(b3Draw* draw) const +void b3Cloth::Draw() const { const b3Mesh* m = m_mesh; for (u32 i = 0; i < m->vertexCount; ++i) { - draw->DrawPoint(m_ps[i].p, 6.0f, b3Color_green); + b3Draw_draw->DrawPoint(m_ps[i].p, 6.0f, b3Color_green); } for (u32 i = 0; i < m->triangleCount; ++i) @@ -394,7 +394,7 @@ void b3Cloth::Draw(b3Draw* draw) const b3Vec3 n2 = -n1; - draw->DrawSolidTriangle(n1, v1, v2, v3, b3Color_blue); - draw->DrawSolidTriangle(n2, v1, v3, v2, b3Color_blue); + b3Draw_draw->DrawSolidTriangle(n1, v1, v2, v3, b3Color_blue); + b3Draw_draw->DrawSolidTriangle(n2, v1, v3, v2, b3Color_blue); } } \ No newline at end of file diff --git a/src/bounce/dynamics/cloth/spring_cloth.cpp b/src/bounce/dynamics/cloth/spring_cloth.cpp index fb2db21..6bf283f 100644 --- a/src/bounce/dynamics/cloth/spring_cloth.cpp +++ b/src/bounce/dynamics/cloth/spring_cloth.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #define B3_FORCE_THRESHOLD (0.1f) @@ -610,7 +611,7 @@ void b3SpringCloth::Apply() const } } -void b3SpringCloth::Draw(b3Draw* draw) const +void b3SpringCloth::Draw() const { const b3Mesh* m = m_mesh; @@ -620,16 +621,16 @@ void b3SpringCloth::Draw(b3Draw* draw) const { if (m_contacts[i].Fn < B3_FORCE_THRESHOLD) { - draw->DrawPoint(m_x[i], 6.0f, b3Color_yellow); + b3Draw_draw->DrawPoint(m_x[i], 6.0f, b3Color_yellow); } else { - draw->DrawPoint(m_x[i], 6.0f, b3Color_red); + b3Draw_draw->DrawPoint(m_x[i], 6.0f, b3Color_red); } } else { - draw->DrawPoint(m_x[i], 6.0f, b3Color_green); + b3Draw_draw->DrawPoint(m_x[i], 6.0f, b3Color_green); } } @@ -646,7 +647,7 @@ void b3SpringCloth::Draw(b3Draw* draw) const b3Vec3 n2 = -n1; - draw->DrawSolidTriangle(n1, v1, v2, v3, b3Color_blue); - draw->DrawSolidTriangle(n2, v1, v3, v2, b3Color_blue); + b3Draw_draw->DrawSolidTriangle(n1, v1, v2, v3, b3Color_blue); + b3Draw_draw->DrawSolidTriangle(n2, v1, v3, v2, b3Color_blue); } } \ No newline at end of file diff --git a/src/bounce/dynamics/contacts/collide/clip.cpp b/src/bounce/dynamics/contacts/collide/clip.cpp index 48e7b38..ded4e26 100644 --- a/src/bounce/dynamics/contacts/collide/clip.cpp +++ b/src/bounce/dynamics/contacts/collide/clip.cpp @@ -21,7 +21,7 @@ #include void b3BuildEdge(b3ClipVertex vOut[2], - const b3Segment* hull) + const b3Capsule* hull) { vOut[0].position = hull->vertices[0]; vOut[0].pair = b3MakePair(0, B3_NULL_EDGE, 0, B3_NULL_EDGE); @@ -150,7 +150,7 @@ void b3ClipPolygonToPlane(b3ClipPolygon& pOut, // Clip a segment to edge side planes. u32 b3ClipEdgeToFace(b3ClipVertex vOut[2], - const b3ClipVertex vIn[2], const b3Segment* hull) + const b3ClipVertex vIn[2], const b3Capsule* hull) { // Start from somewhere. vOut[0] = vIn[0]; @@ -277,4 +277,4 @@ void b3ClipPolygonToFace(b3ClipPolygon& pOut, } while (edge != begin); // Now pOut contains the clipped points. -} +} \ No newline at end of file diff --git a/src/bounce/dynamics/contacts/collide/collide_capsule_hull.cpp b/src/bounce/dynamics/contacts/collide/collide_capsule_hull.cpp index 01d4199..29d3186 100644 --- a/src/bounce/dynamics/contacts/collide/collide_capsule_hull.cpp +++ b/src/bounce/dynamics/contacts/collide/collide_capsule_hull.cpp @@ -94,13 +94,11 @@ static void b3BuildFaceContact(b3Manifold& manifold, const b3Transform& xf2, u32 index2, const b3HullShape* s2) { // Clip edge 1 against the side planes of the face 2. - b3Segment segment1; - segment1.vertices[0] = xf1 * s1->m_centers[0]; - segment1.vertices[1] = xf1 * s1->m_centers[1]; + const b3Capsule hull1(xf1 * s1->m_centers[0], xf1 * s1->m_centers[1], 0.0f); float32 r1 = s1->m_radius; b3ClipVertex edge1[2]; - b3BuildEdge(edge1, &segment1); + b3BuildEdge(edge1, &hull1); const b3Hull* hull2 = s2->m_hull; float32 r2 = s2->m_radius; @@ -162,10 +160,7 @@ void b3CollideCapsuleAndHull(b3Manifold& manifold, return; } - b3Segment hull1; - hull1.vertices[0] = s1->m_centers[0]; - hull1.vertices[1] = s1->m_centers[1]; - + const b3Capsule hull1(s1->m_centers[0], s1->m_centers[1], 0.0f); const b3Hull* hull2 = s2->m_hull; if (gjk.distance > B3_EPSILON) diff --git a/src/bounce/dynamics/contacts/collide/collide_capsules.cpp b/src/bounce/dynamics/contacts/collide/collide_capsules.cpp index 357bd48..7b01ed8 100644 --- a/src/bounce/dynamics/contacts/collide/collide_capsules.cpp +++ b/src/bounce/dynamics/contacts/collide/collide_capsules.cpp @@ -23,7 +23,7 @@ #include // Compute the closest point on a segment to a point. -static b3Vec3 b3ClosestPoint(const b3Vec3& Q, const b3Segment& hull) +static b3Vec3 b3ClosestPoint(const b3Vec3& Q, const b3Capsule& hull) { b3Vec3 A = hull.vertices[0]; b3Vec3 B = hull.vertices[1]; @@ -56,7 +56,7 @@ static b3Vec3 b3ClosestPoint(const b3Vec3& Q, const b3Segment& hull) // Compute the closest points between two line segments. static void b3ClosestPoints(b3Vec3& C1, b3Vec3& C2, - const b3Segment& hull1, const b3Segment& hull2) + const b3Capsule& hull1, const b3Capsule& hull2) { b3Vec3 P1 = hull1.vertices[0]; b3Vec3 Q1 = hull1.vertices[1]; @@ -136,7 +136,7 @@ static void b3ClosestPoints(b3Vec3& C1, b3Vec3& C2, C1 = b3ClosestPoint(C2, hull1); } -static bool b3AreParalell(const b3Segment& hull1, const b3Segment& hull2) +static bool b3AreParalell(const b3Capsule& hull1, const b3Capsule& hull2) { b3Vec3 E1 = hull1.vertices[1] - hull1.vertices[0]; float32 L1 = b3Length(E1); @@ -162,11 +162,11 @@ void b3CollideCapsuleAndCapsule(b3Manifold& manifold, const b3Transform& xf1, const b3CapsuleShape* s1, const b3Transform& xf2, const b3CapsuleShape* s2) { - b3Segment hull1; + b3Capsule hull1; hull1.vertices[0] = xf1 * s1->m_centers[0]; hull1.vertices[1] = xf1 * s1->m_centers[1]; - b3Segment hull2; + b3Capsule hull2; hull2.vertices[0] = xf2 * s2->m_centers[0]; hull2.vertices[1] = xf2 * s2->m_centers[1]; diff --git a/src/bounce/dynamics/contacts/collide/collide_sphere_hull.cpp b/src/bounce/dynamics/contacts/collide/collide_sphere_hull.cpp index 52d225c..1e0e2cc 100644 --- a/src/bounce/dynamics/contacts/collide/collide_sphere_hull.cpp +++ b/src/bounce/dynamics/contacts/collide/collide_sphere_hull.cpp @@ -58,10 +58,10 @@ void b3CollideSphereAndHull(b3Manifold& manifold, return; } - const b3Vec3& hull1 = s1->m_center; + const b3Sphere hull1(s1->m_center, 0.0f); const b3Hull* hull2 = s2->m_hull; - b3FaceQuery faceQuery = b3QueryFaceSeparation(xf1, hull1, xf2, hull2); + b3FaceQuery faceQuery = b3QueryFaceSeparation(xf1, &hull1, xf2, hull2); if (faceQuery.separation > totalRadius) { return; @@ -70,7 +70,7 @@ void b3CollideSphereAndHull(b3Manifold& manifold, b3Plane localPlane2 = hull2->planes[faceQuery.index]; b3Plane plane2 = xf2 * localPlane2; - b3Vec3 c1 = xf1 * hull1; + b3Vec3 c1 = xf1 * hull1.vertex; b3Vec3 c2 = b3ClosestPointOnPlane(c1, plane2); // Ensure normal orientation to shape 2 diff --git a/src/bounce/dynamics/draw_world.cpp b/src/bounce/dynamics/draw_world.cpp index d2d0541..3b674d4 100644 --- a/src/bounce/dynamics/draw_world.cpp +++ b/src/bounce/dynamics/draw_world.cpp @@ -26,13 +26,13 @@ const b3Color b3Color_blue(0.0f, 0.0f, 1.0f); const b3Color b3Color_yellow(1.0f, 1.0f, 0.0f); const b3Color b3Color_pink(1.0f, 0.0f, 1.0f); -b3Draw* b3_debugDraw = NULL; +b3Draw* b3Draw_draw(nullptr); -void b3World::DebugDraw() const +void b3World::Draw() const { - B3_ASSERT(b3_debugDraw); + B3_ASSERT(b3Draw_draw); - u32 flags = b3_debugDraw->m_flags; + u32 flags = b3Draw_draw->m_flags; if (flags & b3Draw::e_centerOfMassesFlag) { @@ -40,7 +40,7 @@ void b3World::DebugDraw() const { b3Transform xf = b->m_xf; xf.position = b->m_sweep.worldCenter; - b3_debugDraw->DrawTransform(xf); + b3Draw_draw->DrawTransform(xf); } } @@ -63,7 +63,7 @@ void b3World::DebugDraw() const for (b3Shape* s = b->m_shapeList.m_head; s; s = s->m_next) { const b3AABB3& aabb = m_contactMan.m_broadPhase.GetAABB(s->m_broadPhaseID); - b3_debugDraw->DrawAABB(aabb, b3Color_pink); + b3Draw_draw->DrawAABB(aabb, b3Color_pink); } } } @@ -72,7 +72,7 @@ void b3World::DebugDraw() const { for (b3Joint* j = m_jointMan.m_jointList.m_head; j; j = j->m_next) { - DrawJoint(j); + j->Draw(); } } @@ -103,12 +103,12 @@ void b3World::DebugDraw() const if (flags & b3Draw::e_contactPointsFlag) { - b3_debugDraw->DrawPoint(p, 4.0f, mp->persisting ? b3Color_green : b3Color_red); + b3Draw_draw->DrawPoint(p, 4.0f, mp->persisting ? b3Color_green : b3Color_red); } if (flags & b3Draw::e_contactNormalsFlag) { - b3_debugDraw->DrawSegment(p, p + n, b3Color_white); + b3Draw_draw->DrawSegment(p, p + n, b3Color_white); } } @@ -121,20 +121,20 @@ void b3World::DebugDraw() const if (flags & b3Draw::e_contactNormalsFlag) { - b3_debugDraw->DrawSegment(p, p + n, b3Color_yellow); + b3Draw_draw->DrawSegment(p, p + n, b3Color_yellow); } if (flags & b3Draw::e_contactTangentsFlag) { - b3_debugDraw->DrawSegment(p, p + t1, b3Color_yellow); - b3_debugDraw->DrawSegment(p, p + t2, b3Color_yellow); + b3Draw_draw->DrawSegment(p, p + t1, b3Color_yellow); + b3Draw_draw->DrawSegment(p, p + t2, b3Color_yellow); } if (m->pointCount > 2) { if (flags & b3Draw::e_contactPolygonsFlag) { - b3_debugDraw->DrawSolidPolygon(wm.normal, points, m->pointCount, b3Color_pink); + b3Draw_draw->DrawSolidPolygon(wm.normal, points, m->pointCount, b3Color_pink); } } } @@ -151,7 +151,7 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const { const b3SphereShape* sphere = (b3SphereShape*)shape; b3Vec3 p = xf * sphere->m_center; - b3_debugDraw->DrawPoint(p, 4.0f, wireColor); + b3Draw_draw->DrawPoint(p, 4.0f, wireColor); break; } case e_capsuleShape: @@ -159,9 +159,9 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const const b3CapsuleShape* capsule = (b3CapsuleShape*)shape; b3Vec3 p1 = xf * capsule->m_centers[0]; b3Vec3 p2 = xf * capsule->m_centers[1]; - b3_debugDraw->DrawPoint(p1, 4.0f, wireColor); - b3_debugDraw->DrawPoint(p2, 4.0f, wireColor); - b3_debugDraw->DrawSegment(p1, p2, wireColor); + b3Draw_draw->DrawPoint(p1, 4.0f, wireColor); + b3Draw_draw->DrawPoint(p2, 4.0f, wireColor); + b3Draw_draw->DrawSegment(p1, p2, wireColor); break; } case e_hullShape: @@ -176,7 +176,7 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const b3Vec3 p1 = xf * hull->vertices[edge->origin]; b3Vec3 p2 = xf * hull->vertices[twin->origin]; - b3_debugDraw->DrawSegment(p1, p2, wireColor); + b3Draw_draw->DrawSegment(p1, p2, wireColor); } break; } @@ -192,7 +192,7 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const b3Vec3 p2 = xf * mesh->vertices[t->v2]; b3Vec3 p3 = xf * mesh->vertices[t->v3]; - b3_debugDraw->DrawTriangle(p1, p2, p3, wireColor); + b3Draw_draw->DrawTriangle(p1, p2, p3, wireColor); } break; } @@ -201,59 +201,4 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const break; } }; -} - -void b3World::DrawJoint(const b3Joint* joint) const -{ - b3JointType type = joint->GetType(); - - switch (type) - { - case e_mouseJoint: - { - b3MouseJoint* o = (b3MouseJoint*)joint; - o->Draw(b3_debugDraw); - break; - } - case e_springJoint: - { - b3SpringJoint* o = (b3SpringJoint*)joint; - o->Draw(b3_debugDraw); - break; - } - case e_weldJoint: - { - b3WeldJoint* o = (b3WeldJoint*)joint; - o->Draw(b3_debugDraw); - break; - } - case e_revoluteJoint: - { - b3RevoluteJoint* o = (b3RevoluteJoint*)joint; - o->Draw(b3_debugDraw); - break; - } - case e_sphereJoint: - { - b3SphereJoint* o = (b3SphereJoint*)joint; - o->Draw(b3_debugDraw); - break; - } - case e_coneJoint: - { - b3ConeJoint* o = (b3ConeJoint*)joint; - o->Draw(b3_debugDraw); - break; - } - default: - { - B3_ASSERT(false); - break; - } - } -} - -void b3World::DrawContact(const b3Contact* c) const -{ - B3_NOT_USED(c); -} +} \ No newline at end of file diff --git a/src/bounce/dynamics/joints/cone_joint.cpp b/src/bounce/dynamics/joints/cone_joint.cpp index a5217a1..94726bd 100644 --- a/src/bounce/dynamics/joints/cone_joint.cpp +++ b/src/bounce/dynamics/joints/cone_joint.cpp @@ -346,10 +346,10 @@ void b3ConeJoint::SetConeAngle(float32 angle) } } -void b3ConeJoint::Draw(b3Draw* draw) const +void b3ConeJoint::Draw() const { b3Transform xfA = GetFrameA(); - draw->DrawTransform(xfA); + b3Draw_draw->DrawTransform(xfA); b3Transform xfB = GetFrameB(); - draw->DrawTransform(xfB); + b3Draw_draw->DrawTransform(xfB); } \ No newline at end of file diff --git a/src/bounce/dynamics/joints/mouse_joint.cpp b/src/bounce/dynamics/joints/mouse_joint.cpp index 1c2d1e6..dc38de1 100644 --- a/src/bounce/dynamics/joints/mouse_joint.cpp +++ b/src/bounce/dynamics/joints/mouse_joint.cpp @@ -109,12 +109,12 @@ void b3MouseJoint::SetTarget(const b3Vec3& target) GetBodyB()->SetAwake(true); } -void b3MouseJoint::Draw(b3Draw* draw) const +void b3MouseJoint::Draw() const { b3Vec3 a = GetAnchorA(); b3Vec3 b = GetAnchorB(); - draw->DrawPoint(a, 4.0f, b3Color_green); - draw->DrawPoint(b, 4.0f, b3Color_red); - draw->DrawSegment(a, b, b3Color_yellow); + b3Draw_draw->DrawPoint(a, 4.0f, b3Color_green); + b3Draw_draw->DrawPoint(b, 4.0f, b3Color_red); + b3Draw_draw->DrawSegment(a, b, b3Color_yellow); } \ No newline at end of file diff --git a/src/bounce/dynamics/joints/revolute_joint.cpp b/src/bounce/dynamics/joints/revolute_joint.cpp index 0bacca8..dc9964b 100644 --- a/src/bounce/dynamics/joints/revolute_joint.cpp +++ b/src/bounce/dynamics/joints/revolute_joint.cpp @@ -749,10 +749,11 @@ void b3RevoluteJoint::SetMaxMotorTorque(float32 torque) m_maxMotorTorque = torque; } -void b3RevoluteJoint::Draw(b3Draw* draw) const +void b3RevoluteJoint::Draw() const { b3Transform xfA = GetFrameA(); + b3Draw_draw->DrawTransform(xfA); + b3Transform xfB = GetFrameB(); - draw->DrawTransform(xfA); - draw->DrawTransform(xfB); + b3Draw_draw->DrawTransform(xfB); } \ No newline at end of file diff --git a/src/bounce/dynamics/joints/sphere_joint.cpp b/src/bounce/dynamics/joints/sphere_joint.cpp index 7bef9aa..f62ef2f 100644 --- a/src/bounce/dynamics/joints/sphere_joint.cpp +++ b/src/bounce/dynamics/joints/sphere_joint.cpp @@ -157,12 +157,13 @@ b3Vec3 b3SphereJoint::GetAnchorB() const return GetBodyB()->GetWorldPoint(m_localAnchorB); } -void b3SphereJoint::Draw(b3Draw* draw) const +void b3SphereJoint::Draw() const { b3Vec3 a = GetAnchorA(); - b3Vec3 b = GetAnchorB(); + b3Draw_draw->DrawPoint(a, 4.0f, b3Color_red); - draw->DrawPoint(a, 4.0f, b3Color_red); - draw->DrawPoint(b, 4.0f, b3Color_green); - draw->DrawSegment(a, b, b3Color_yellow); + b3Vec3 b = GetAnchorB(); + b3Draw_draw->DrawPoint(b, 4.0f, b3Color_green); + + b3Draw_draw->DrawSegment(a, b, b3Color_yellow); } diff --git a/src/bounce/dynamics/joints/spring_joint.cpp b/src/bounce/dynamics/joints/spring_joint.cpp index 1006e49..6aa667e 100644 --- a/src/bounce/dynamics/joints/spring_joint.cpp +++ b/src/bounce/dynamics/joints/spring_joint.cpp @@ -252,12 +252,13 @@ bool b3SpringJoint::SolvePositionConstraints(const b3SolverData* data) return b3Abs(C) < B3_LINEAR_SLOP; } -void b3SpringJoint::Draw(b3Draw* draw) const +void b3SpringJoint::Draw() const { b3Vec3 a = GetBodyA()->GetWorldPoint(m_localAnchorA); - b3Vec3 b = GetBodyB()->GetWorldPoint(m_localAnchorB); + b3Draw_draw->DrawPoint(a, 4.0f, b3Color_red); - draw->DrawPoint(a, 4.0f, b3Color_red); - draw->DrawPoint(b, 4.0f, b3Color_green); - draw->DrawSegment(a, b, b3Color_yellow); -} + b3Vec3 b = GetBodyB()->GetWorldPoint(m_localAnchorB); + b3Draw_draw->DrawPoint(b, 4.0f, b3Color_green); + + b3Draw_draw->DrawSegment(a, b, b3Color_yellow); +} \ No newline at end of file diff --git a/src/bounce/dynamics/joints/weld_joint.cpp b/src/bounce/dynamics/joints/weld_joint.cpp index 13e7d17..22e15b0 100644 --- a/src/bounce/dynamics/joints/weld_joint.cpp +++ b/src/bounce/dynamics/joints/weld_joint.cpp @@ -311,12 +311,13 @@ b3Vec3 b3WeldJoint::GetAnchorB() const return GetBodyB()->GetWorldPoint(m_localAnchorB); } -void b3WeldJoint::Draw(b3Draw* draw) const +void b3WeldJoint::Draw() const { b3Vec3 a = GetAnchorA(); + b3Draw_draw->DrawPoint(a, 4.0f, b3Color_red); + b3Vec3 b = GetAnchorB(); - - draw->DrawPoint(a, 4.0f, b3Color_red); - draw->DrawPoint(b, 4.0f, b3Color_green); - draw->DrawSegment(a, b, b3Color_yellow); -} + b3Draw_draw->DrawPoint(b, 4.0f, b3Color_green); + + b3Draw_draw->DrawSegment(a, b, b3Color_yellow); +} \ No newline at end of file diff --git a/src/bounce/dynamics/rope/rope.cpp b/src/bounce/dynamics/rope/rope.cpp index d03da4a..6ddec52 100644 --- a/src/bounce/dynamics/rope/rope.cpp +++ b/src/bounce/dynamics/rope/rope.cpp @@ -170,12 +170,13 @@ void b3Rope::Initialize(const b3RopeDef& def) b3Vec3 d = -b->m_X_J_j.position; - b3Vec3 w1(1.0f, 0.0f, 0.0f); - b3Vec3 w2(0.0f, 1.0f, 0.0f); - b3Vec3 w3(0.0f, 0.0f, 1.0f); - + b3Vec3 w1(b3Vec3_x); b3Vec3 v1 = b3Cross(w1, d); + + b3Vec3 w2(b3Vec3_y); b3Vec3 v2 = b3Cross(w2, d); + + b3Vec3 w3(b3Vec3_z); b3Vec3 v3 = b3Cross(w3, d); b->m_S[0].w = w1; @@ -468,7 +469,7 @@ void b3Rope::Step(float32 h) } } -void b3Rope::Draw(b3Draw* draw) const +void b3Rope::Draw() const { if (m_count == 0) { @@ -478,8 +479,8 @@ void b3Rope::Draw(b3Draw* draw) const { b3RopeBody* b = m_links; - draw->DrawTransform(b->m_X); - draw->DrawSolidSphere(b->m_X.position, 0.2f, b3Color_green); + b3Draw_draw->DrawTransform(b->m_X); + b3Draw_draw->DrawSolidSphere(b->m_X.position, 0.2f, b3Color_green); } for (u32 i = 1; i < m_count; ++i) @@ -490,13 +491,13 @@ void b3Rope::Draw(b3Draw* draw) const b3Transform X_J = b0->m_X * b3Inverse(b->m_X_i_J); b3Transform X_J0 = b->m_X * b->m_X_J_j; - draw->DrawTransform(X_J); - draw->DrawPoint(X_J.position, 5.0f, b3Color_red); + b3Draw_draw->DrawTransform(X_J); + b3Draw_draw->DrawPoint(X_J.position, 5.0f, b3Color_red); - draw->DrawTransform(X_J0); - draw->DrawPoint(X_J0.position, 5.0f, b3Color_red); + b3Draw_draw->DrawTransform(X_J0); + b3Draw_draw->DrawPoint(X_J0.position, 5.0f, b3Color_red); - draw->DrawTransform(b->m_X); - draw->DrawSolidSphere(b->m_X.position, 0.2f, b3Color_green); + b3Draw_draw->DrawTransform(b->m_X); + b3Draw_draw->DrawSolidSphere(b->m_X.position, 0.2f, b3Color_green); } } \ No newline at end of file diff --git a/src/bounce/dynamics/world.cpp b/src/bounce/dynamics/world.cpp index 50a01f1..27c2972 100644 --- a/src/bounce/dynamics/world.cpp +++ b/src/bounce/dynamics/world.cpp @@ -32,7 +32,6 @@ b3World::b3World() : m_bodyBlocks(sizeof(b3Body)) { b3_allocCalls = 0; b3_maxAllocCalls = 0; - m_debugDraw = NULL; m_flags = e_clearForcesFlag; m_sleeping = false;