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.
This commit is contained in:
parent
59a993af18
commit
bd09b243c2
@ -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.
|
||||
|
162
examples/testbed/framework/controller.cpp
Normal file
162
examples/testbed/framework/controller.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
#include <testbed/framework/controller.h>
|
||||
#include <testbed/framework/model.h>
|
||||
#include <testbed/framework/view.h>
|
||||
|
||||
// !
|
||||
#include <glfw/glfw3.h>
|
||||
|
||||
// !
|
||||
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);
|
||||
}
|
||||
}
|
59
examples/testbed/framework/controller.h
Normal file
59
examples/testbed/framework/controller.h
Normal file
@ -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 <bounce/common/math/vec2.h>
|
||||
|
||||
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
|
@ -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
|
@ -24,99 +24,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
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)
|
||||
|
@ -24,99 +24,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
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)
|
||||
|
@ -16,166 +16,53 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#if defined(__APPLE_CC__)
|
||||
#include <OpenGL/gl3.h>
|
||||
#if defined (U_OPENGL_2)
|
||||
#include <glad_2/glad.h>
|
||||
#elif defined (U_OPENGL_4)
|
||||
#include <glad_4/glad.h>
|
||||
#else
|
||||
|
||||
#if defined(U_OPENGL_2)
|
||||
#include <glad_2/glad.h>
|
||||
#elif defined(U_OPENGL_4)
|
||||
#include <glad_4/glad.h>
|
||||
#else
|
||||
|
||||
// error
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#if defined(U_OPENGL_2)
|
||||
#include <imgui/imgui_impl_glfw_gl2.h>
|
||||
#elif defined(U_OPENGL_4)
|
||||
#include <imgui/imgui_impl_glfw_gl3.h>
|
||||
#else
|
||||
// error
|
||||
#endif
|
||||
|
||||
#include <testbed/framework/testbed_listener.h>
|
||||
#include <testbed/tests/test.h>
|
||||
#include <glfw/glfw3.h>
|
||||
#include <testbed/framework/model.h>
|
||||
#include <testbed/framework/view.h>
|
||||
#include <testbed/framework/controller.h>
|
||||
|
||||
//
|
||||
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;
|
||||
}
|
130
examples/testbed/framework/model.cpp
Normal file
130
examples/testbed/framework/model.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include <testbed/framework/model.h>
|
||||
|
||||
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<ProfilerRecord>& 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();
|
||||
}
|
225
examples/testbed/framework/model.h
Normal file
225
examples/testbed/framework/model.h
Normal file
@ -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 <testbed/framework/debug_draw.h>
|
||||
#include <testbed/framework/testbed_listener.h>
|
||||
#include <testbed/tests/test.h>
|
||||
|
||||
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
|
@ -18,6 +18,9 @@
|
||||
|
||||
#include <testbed/framework/profiler.h>
|
||||
|
||||
Profiler* g_profiler = nullptr;
|
||||
ProfilerListener* g_profilerListener = nullptr;
|
||||
|
||||
Profiler::Profiler()
|
||||
{
|
||||
m_top = nullptr;
|
||||
|
@ -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
|
@ -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<ProfilerRecord>& 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)
|
||||
|
@ -117,4 +117,18 @@ TestEntry g_tests[] =
|
||||
{ "Mass-Spring System", &MassSpring::Create },
|
||||
{ "Shift Center", &ShiftCenter::Create },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
static u32 TestCount()
|
||||
{
|
||||
u32 count = 0;
|
||||
while (g_tests[count].create != NULL)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Count the tests
|
||||
u32 g_testCount = TestCount();
|
@ -30,14 +30,13 @@
|
||||
#include <testbed\framework\json_profiler.h>
|
||||
#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
|
||||
|
261
examples/testbed/framework/view.cpp
Normal file
261
examples/testbed/framework/view.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
#include <testbed/framework/view.h>
|
||||
#include <testbed/framework/model.h>
|
||||
|
||||
#if defined (U_OPENGL_2)
|
||||
#include <imgui/imgui_impl_glfw_gl2.h>
|
||||
#elif defined (U_OPENGL_4)
|
||||
#include <imgui/imgui_impl_glfw_gl3.h>
|
||||
#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());
|
||||
}
|
43
examples/testbed/framework/view.h
Normal file
43
examples/testbed/framework/view.h
Normal file
@ -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
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -21,16 +21,11 @@
|
||||
|
||||
#include <bounce/dynamics/contacts/contact_cluster.h>
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -21,10 +21,6 @@
|
||||
|
||||
#include <testbed/tests/quickhull_test.h>
|
||||
|
||||
extern DebugDraw* g_debugDraw;
|
||||
extern Camera g_camera;
|
||||
extern Settings g_settings;
|
||||
|
||||
class GyroTest : public Test
|
||||
{
|
||||
public:
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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];
|
||||
|
@ -24,8 +24,6 @@ class MultipleShapes : public Test
|
||||
public:
|
||||
MultipleShapes()
|
||||
{
|
||||
g_settings.drawCenterOfMasses = true;
|
||||
|
||||
{
|
||||
b3BodyDef bd;
|
||||
b3Body* body = m_world.CreateBody(bd);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -21,19 +21,11 @@
|
||||
|
||||
#include <testbed/tests/quickhull_test.h>
|
||||
|
||||
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);
|
||||
|
@ -21,74 +21,6 @@
|
||||
|
||||
#include <bounce/quickhull/qh_hull.h>
|
||||
|
||||
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();
|
||||
|
||||
|
@ -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
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -21,19 +21,11 @@
|
||||
|
||||
#include <testbed/tests/quickhull_test.h>
|
||||
|
||||
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);
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
@ -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;
|
||||
|
@ -21,10 +21,6 @@
|
||||
|
||||
#include <testbed/tests/quickhull_test.h>
|
||||
|
||||
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);
|
||||
|
@ -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
|
@ -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
|
@ -21,20 +21,20 @@
|
||||
|
||||
#include <bounce/collision/sat/sat.h>
|
||||
|
||||
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
|
@ -21,11 +21,13 @@
|
||||
|
||||
#include <bounce/collision/sat/sat.h>
|
||||
|
||||
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
|
||||
|
@ -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
|
@ -21,20 +21,38 @@
|
||||
|
||||
#include <bounce/common/math/vec3.h>
|
||||
|
||||
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]))
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -19,7 +19,6 @@
|
||||
#ifndef B3_DYNAMIC_TREE_H
|
||||
#define B3_DYNAMIC_TREE_H
|
||||
|
||||
#include <bounce/common/draw.h>
|
||||
#include <bounce/common/template/stack.h>
|
||||
#include <bounce/collision/shapes/aabb3.h>
|
||||
#include <bounce/collision/collision.h>
|
||||
@ -67,7 +66,7 @@ public :
|
||||
void Validate(i32 node) const;
|
||||
|
||||
// Draw this tree.
|
||||
void Draw(b3Draw* draw) const;
|
||||
void Draw() const;
|
||||
private :
|
||||
struct b3Node
|
||||
{
|
||||
|
@ -19,7 +19,6 @@
|
||||
#ifndef B3_STATIC_TREE_H
|
||||
#define B3_STATIC_TREE_H
|
||||
|
||||
#include <bounce/common/draw.h>
|
||||
#include <bounce/common/template/stack.h>
|
||||
#include <bounce/collision/shapes/aabb3.h>
|
||||
#include <bounce/collision/collision.h>
|
||||
@ -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 :
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -23,7 +23,6 @@
|
||||
#include <bounce/collision/collision.h>
|
||||
|
||||
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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include <bounce/common/template/list.h>
|
||||
#include <bounce/dynamics/time_step.h>
|
||||
|
||||
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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -21,8 +21,6 @@
|
||||
|
||||
#include <bounce/common/math/transform.h>
|
||||
|
||||
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;
|
||||
|
@ -117,13 +117,11 @@ public:
|
||||
const b3List2<b3Contact>& GetContactList() const;
|
||||
b3List2<b3Contact>& 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;
|
||||
|
18
premake5.lua
18
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"
|
||||
}
|
||||
|
||||
|
27
src/bounce/collision/collision.cpp
Normal file
27
src/bounce/collision/collision.cpp
Normal file
@ -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 <bounce/collision/shapes/sphere.h>
|
||||
#include <bounce/collision/shapes/capsule.h>
|
||||
#include <bounce/collision/shapes/box_hull.h>
|
||||
|
||||
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);
|
@ -20,13 +20,13 @@
|
||||
#include <bounce/collision/shapes/capsule.h>
|
||||
#include <bounce/collision/shapes/hull.h>
|
||||
|
||||
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;
|
||||
|
@ -20,17 +20,17 @@
|
||||
#include <bounce/collision/shapes/sphere.h>
|
||||
#include <bounce/collision/shapes/hull.h>
|
||||
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include <bounce/collision/trees/dynamic_tree.h>
|
||||
#include <bounce/common/draw.h>
|
||||
|
||||
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);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <bounce/collision/trees/static_tree.h>
|
||||
#include <bounce/common/template/stack.h>
|
||||
#include <bounce/common/draw.h>
|
||||
|
||||
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);
|
||||
|
@ -16,28 +16,45 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <bounce/common/math/vec2.h>
|
||||
#include <bounce/common/math/vec3.h>
|
||||
|
||||
#include <bounce/common/math/mat22.h>
|
||||
#include <bounce/common/math/mat33.h>
|
||||
#include <bounce/common/math/mat44.h>
|
||||
#include <bounce/common/math/transform.h>
|
||||
|
||||
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
|
@ -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);
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
#include <bounce/dynamics/shapes/shape.h>
|
||||
#include <bounce/collision/shapes/mesh.h>
|
||||
#include <bounce/common/memory/stack_allocator.h>
|
||||
#include <bounce/common/draw.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
#include <bounce/collision/shapes/hull.h>
|
||||
|
||||
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.
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <bounce/collision/shapes/capsule.h>
|
||||
|
||||
// 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];
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user