fix a lot of issues, add gyroscopic force integrator, add contact polygon winding, add some quaternion constraints, add more tests

This commit is contained in:
Irlan
2017-03-24 18:49:41 -03:00
parent dd6ca355e9
commit 8defab9945
103 changed files with 3840 additions and 3355 deletions

View File

@ -27,7 +27,21 @@
extern Camera g_camera;
extern DebugDraw* g_debugDraw;
Mat44 Camera::BuildProjectionMatrix() const
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;
@ -39,11 +53,11 @@ Mat44 Camera::BuildProjectionMatrix() const
float32 sz = invRange * (m_zNear + m_zFar);
float32 tz = invRange * m_zNear * m_zFar;
Mat44 m;
m.x.Set(sx, 0.0f, 0.0f, 0.0f);
m.y.Set(0.0f, sy, 0.0f, 0.0f);
m.z.Set(0.0f, 0.0f, sz, -1.0f);
m.w.Set(0.0f, 0.0f, tz, 0.0f);
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;
}
@ -55,10 +69,10 @@ b3Transform Camera::BuildWorldTransform() const
return xf;
}
Mat44 Camera::BuildWorldMatrix() const
b3Mat44 Camera::BuildWorldMatrix() const
{
b3Transform xf = BuildWorldTransform();
return GetMat44(xf);
return Convert44(xf);
}
b3Transform Camera::BuildViewTransform() const
@ -69,10 +83,10 @@ b3Transform Camera::BuildViewTransform() const
return b3Inverse(xf);
}
Mat44 Camera::BuildViewMatrix() const
b3Mat44 Camera::BuildViewMatrix() const
{
b3Transform xf = BuildViewTransform();
return GetMat44(xf);
return Convert44(xf);
}
b3Vec2 Camera::ConvertWorldToScreen(const b3Vec3& pw) const
@ -150,11 +164,11 @@ static void PrintLog(GLuint id)
static GLuint CreateShader(const char* source, GLenum type)
{
GLuint shaderId = glCreateShader(type);
const char* sources[] = { source };
glShaderSource(shaderId, 1, sources, NULL);
glCompileShader(shaderId);
GLint status = GL_FALSE;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
@ -164,7 +178,7 @@ static GLuint CreateShader(const char* source, GLenum type)
glDeleteShader(shaderId);
return 0;
}
return shaderId;
}
@ -225,7 +239,7 @@ struct DrawPoints
m_sizeAttribute = 2;
glGenBuffers(3, m_vboIds);
glGenVertexArrays(1, &m_vaoId);
glBindVertexArray(m_vaoId);
@ -282,14 +296,14 @@ struct DrawPoints
glUseProgram(m_programId);
Mat44 m1 = g_camera.BuildViewMatrix();
Mat44 m2 = g_camera.BuildProjectionMatrix();
Mat44 m = m2 * m1;
b3Mat44 m1 = g_camera.BuildViewMatrix();
b3Mat44 m2 = g_camera.BuildProjectionMatrix();
b3Mat44 m = m2 * m1;
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x);
glBindVertexArray(m_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b3Vec3), m_vertices);
@ -321,13 +335,13 @@ struct DrawPoints
b3Color m_colors[e_vertexCapacity];
float32 m_sizes[e_vertexCapacity];
u32 m_count;
GLuint m_programId;
GLuint m_projectionUniform;
GLuint m_vertexAttribute;
GLuint m_colorAttribute;
GLuint m_sizeAttribute;
GLuint m_vboIds[3];
GLuint m_vaoId;
};
@ -361,8 +375,8 @@ struct DrawLines
m_projectionUniform = glGetUniformLocation(m_programId, "projectionMatrix");
m_vertexAttribute = 0;
m_colorAttribute = 1;
glGenVertexArrays(1, &m_vaoId);
glGenVertexArrays(1, &m_vaoId);
glGenBuffers(2, m_vboIds);
glBindVertexArray(m_vaoId);
@ -376,7 +390,7 @@ struct DrawLines
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[1]);
glVertexAttribPointer(m_colorAttribute, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBufferData(GL_ARRAY_BUFFER, e_vertexCapacity * sizeof(b3Color), m_colors, GL_DYNAMIC_DRAW);
AssertGL();
glBindVertexArray(0);
@ -413,9 +427,9 @@ struct DrawLines
glUseProgram(m_programId);
Mat44 m1 = g_camera.BuildViewMatrix();
Mat44 m2 = g_camera.BuildProjectionMatrix();
Mat44 m = m2 * m1;
b3Mat44 m1 = g_camera.BuildViewMatrix();
b3Mat44 m2 = g_camera.BuildProjectionMatrix();
b3Mat44 m = m2 * m1;
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x);
glBindVertexArray(m_vaoId);
@ -427,7 +441,7 @@ struct DrawLines
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b3Color), m_colors);
glDrawArrays(GL_LINES, 0, m_count);
AssertGL();
glBindVertexArray(0);
@ -450,7 +464,7 @@ struct DrawLines
GLuint m_projectionUniform;
GLuint m_vertexAttribute;
GLuint m_colorAttribute;
GLuint m_vboIds[2];
GLuint m_vaoId;
};
@ -470,7 +484,7 @@ struct DrawTriangles
"{\n"
" vec3 La = vec3(0.5f, 0.5f, 0.5f);\n"
" vec3 Ld = vec3(0.5f, 0.5f, 0.5f);\n"
" vec3 L = vec3(0.0f, 0.0f, 1.0f);\n"
" vec3 L = vec3(0.0f, 0.3f, 0.7f);\n"
" vec3 Ma = v_color.xyz;\n"
" vec3 Md = v_color.xyz;\n"
" vec3 a = La * Ma;\n"
@ -498,7 +512,7 @@ struct DrawTriangles
glGenBuffers(3, m_vboIds);
glBindVertexArray(m_vaoId);
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, e_vertexCapacity * sizeof(b3Vec3), m_vertices, GL_DYNAMIC_DRAW);
glVertexAttribPointer(m_vertexAttribute, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
@ -518,7 +532,7 @@ struct DrawTriangles
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_count = 0;
}
@ -551,9 +565,9 @@ struct DrawTriangles
glUseProgram(m_programId);
Mat44 m1 = g_camera.BuildViewMatrix();
Mat44 m2 = g_camera.BuildProjectionMatrix();
Mat44 m = m2 * m1;
b3Mat44 m1 = g_camera.BuildViewMatrix();
b3Mat44 m2 = g_camera.BuildProjectionMatrix();
b3Mat44 m = m2 * m1;
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x);
@ -567,7 +581,7 @@ struct DrawTriangles
glBindBuffer(GL_ARRAY_BUFFER, m_vboIds[2]);
glBufferSubData(GL_ARRAY_BUFFER, 0, m_count * sizeof(b3Vec3), m_normals);
glDrawArrays(GL_TRIANGLES, 0, m_count);
AssertGL();
@ -578,7 +592,7 @@ struct DrawTriangles
m_count = 0;
}
enum
{
e_vertexCapacity = 3 * 512
@ -724,13 +738,13 @@ struct DrawWire
{
glUseProgram(m_programId);
Mat44 m1 = GetMat44(xf);
b3Mat44 m1 = Convert44(xf);
m1.x = radius * m1.x;
m1.y = radius * m1.y;
m1.z = radius * m1.z;
Mat44 m2 = g_camera.BuildViewMatrix();
Mat44 m3 = g_camera.BuildProjectionMatrix();
Mat44 m = m3 * m2 * m1;
b3Mat44 m2 = g_camera.BuildViewMatrix();
b3Mat44 m3 = g_camera.BuildProjectionMatrix();
b3Mat44 m = m3 * m2 * m1;
glUniformMatrix4fv(m_projectionUniform, 1, GL_FALSE, &m.x.x);
@ -759,8 +773,8 @@ struct DrawSolidSphere
{
enum
{
e_rings = 12,
e_sectors = 12,
e_rings = 18,
e_sectors = 18,
e_vertexCount = e_rings * e_sectors,
e_indexCount = (e_rings - 1) * (e_sectors - 1) * 6,
e_faceCount = e_indexCount / 3
@ -773,18 +787,31 @@ struct DrawSolidSphere
b3Vec3 vs[e_vertexCount];
b3Vec3 ns[e_vertexCount];
u32 vc = 0;
for (u32 r = 0; r < e_rings; r++)
{
for (u32 s = 0; s < e_sectors; s++)
{
float32 y = sin(-0.5f * B3_PI + B3_PI * r * R);
float32 x = cos(2.0f * B3_PI * s * S) * sin(B3_PI * r * R);
float32 z = sin(2.0f * B3_PI * s * S) * sin(B3_PI * r * R);
float32 a1 = 2.0f * B3_PI * float32(s) * S;
float32 c1 = cos(a1);
float32 s1 = sin(a1);
vs[vc].Set(x, y, z);
ns[vc].Set(x, y, z);
float32 a2 = -0.5f * B3_PI + B3_PI * float32(r) * R;
float32 s2 = sin(a2);
float32 a3 = B3_PI * float32(r) * R;
float32 s3 = sin(a3);
float32 x = c1 * s3;
float32 y = s2;
float32 z = s1 * s3;
b3Vec3 v(x, y, z);
v.Normalize();
vs[vc] = v;
ns[vc] = v;
++vc;
}
}
@ -843,7 +870,7 @@ struct DrawSolidCylinder
{
enum
{
e_segments = 24,
e_segments = 64,
e_vertexCount = e_segments * 6,
};
@ -851,12 +878,12 @@ struct DrawSolidCylinder
{
b3Vec3 vs[e_vertexCount];
b3Vec3 ns[e_vertexCount];
u32 vc = 0;
for (u32 i = 0; i < e_segments; ++i)
{
float32 t0 = 2.0f * B3_PI * (float32)i / (float32)e_segments;
float32 t1 = 2.0f * B3_PI * (float32)(i + 1) / (float32)e_segments;
float32 t0 = 2.0f * B3_PI * float32(i) / float32(e_segments);
float32 t1 = 2.0f * B3_PI * float32(i + 1) / float32(e_segments);
float32 c0 = cos(t0);
float32 s0 = sin(t0);
@ -868,22 +895,22 @@ struct DrawSolidCylinder
v1.x = s0;
v1.y = -0.5f;
v1.z = c0;
b3Vec3 v2;
v2.x = s1;
v2.y = -0.5f;
v2.z = c1;
b3Vec3 v3;
v3.x = s1;
v3.y = 0.5f;
v3.z = c1;
b3Vec3 v4;
v4.x = s0;
v4.y = 0.5f;
v4.z = c0;
b3Vec3 n = b3Cross(v2 - v1, v3 - v1);
n.Normalize();
@ -966,7 +993,7 @@ struct DrawSolid
" gl_Position = projectionMatrix * vec4(v_position, 1.0f);\n"
" vec3 La = vec3(0.5f, 0.5f, 0.5f);\n"
" vec3 Ld = vec3(0.5f, 0.5f, 0.5f);\n"
" vec3 L = vec3(0.0f, 0.0f, 1.0f);\n"
" vec3 L = vec3(0.0f, 0.3f, 0.7f);\n"
" vec3 Ma = color.xyz;\n"
" vec3 Md = color.xyz;\n"
" vec3 a = La * Ma;\n"
@ -999,14 +1026,14 @@ struct DrawSolid
{
glUseProgram(m_programId);
Mat44 m1 = GetMat44(xf);
b3Mat44 m1 = Convert44(xf);
m1.x = radius * m1.x;
m1.y = height * m1.y;
m1.z = radius * m1.z;
Mat44 m2 = g_camera.BuildViewMatrix();
Mat44 m3 = g_camera.BuildProjectionMatrix();
Mat44 m = m3 * m2 * m1;
b3Mat44 m2 = g_camera.BuildViewMatrix();
b3Mat44 m3 = g_camera.BuildProjectionMatrix();
b3Mat44 m = m3 * m2 * m1;
glUniform4fv(m_colorUniform, 1, &c.r);
glUniformMatrix4fv(m_modelUniform, 1, GL_FALSE, &m1.x.x);
@ -1033,14 +1060,14 @@ struct DrawSolid
{
glUseProgram(m_programId);
Mat44 m1 = GetMat44(xf);
b3Mat44 m1 = Convert44(xf);
m1.x = radius * m1.x;
m1.y = radius * m1.y;
m1.z = radius * m1.z;
Mat44 m2 = g_camera.BuildViewMatrix();
Mat44 m3 = g_camera.BuildProjectionMatrix();
Mat44 m = m3 * m2 * m1;
b3Mat44 m2 = g_camera.BuildViewMatrix();
b3Mat44 m3 = g_camera.BuildProjectionMatrix();
b3Mat44 m = m3 * m2 * m1;
glUniform4fv(m_colorUniform, 1, &c.r);
glUniformMatrix4fv(m_modelUniform, 1, GL_FALSE, &m1.x.x);
@ -1071,7 +1098,7 @@ struct DrawSolid
GLuint m_normalAttribute;
DrawSolidSphere m_sphere;
DrawSolidCylinder m_cylinder;
DrawSolidCylinder m_cylinder;
};
DebugDraw::DebugDraw()
@ -1115,7 +1142,7 @@ void DebugDraw::DrawSolidTriangle(const b3Vec3& normal, const b3Vec3& p1, const
m_triangles->Vertex(p1, color, normal);
m_triangles->Vertex(p2, color, normal);
m_triangles->Vertex(p3, color, normal);
b3Color edgeColor(0.0f, 0.0f, 0.0f, 1.0f);
DrawTriangle(p2, p3, p3, edgeColor);
}
@ -1126,7 +1153,7 @@ void DebugDraw::DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& co
for (u32 i = 0; i < count; ++i)
{
b3Vec3 p2 = vertices[i];
m_lines->Vertex(p1, color);
m_lines->Vertex(p2, color);
@ -1143,7 +1170,7 @@ void DebugDraw::DrawSolidPolygon(const b3Vec3& normal, const b3Vec3* vertices, u
{
b3Vec3 p2 = vertices[i];
b3Vec3 p3 = vertices[i + 1];
m_triangles->Vertex(p1, fillColor, normal);
m_triangles->Vertex(p2, fillColor, normal);
m_triangles->Vertex(p3, fillColor, normal);
@ -1171,7 +1198,7 @@ void DebugDraw::DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 r
}
n1.Normalize();
// Build a quaternion to rotate the tangent about the normal.
u32 kEdgeCount = 20;
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
@ -1185,7 +1212,7 @@ void DebugDraw::DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 r
m_lines->Vertex(p1, color);
m_lines->Vertex(p2, color);
n1 = n2;
p1 = p2;
}
@ -1195,7 +1222,7 @@ void DebugDraw::DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, floa
{
b3Color fillColor(color.r, color.g, color.b, color.a);
b3Color frameColor(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 1.0f);
// Build a tangent vector to normal.
b3Vec3 u = b3Cross(normal, b3Vec3(1.0f, 0.0f, 0.0f));
b3Vec3 v = b3Cross(normal, b3Vec3(0.0f, 1.0f, 0.0f));
@ -1223,7 +1250,7 @@ void DebugDraw::DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, floa
{
b3Vec3 n2 = b3Mul(q, n1);
b3Vec3 p2 = center + radius * n2;
m_triangles->Vertex(center, fillColor, normal);
m_triangles->Vertex(p1, fillColor, normal);
m_triangles->Vertex(p2, fillColor, normal);
@ -1281,35 +1308,29 @@ void DebugDraw::DrawAABB(const b3AABB3& aabb, const b3Color& color)
b3Vec3 vs[8];
// Face 1
vs[0] = lower;
vs[1] = b3Vec3(lower.x, upper.y, lower.z);
vs[2] = b3Vec3(upper.x, upper.y, lower.z);
vs[3] = b3Vec3(upper.x, lower.y, lower.z);
// Face 2
vs[4] = upper;
vs[5] = b3Vec3(upper.x, lower.y, upper.z);
vs[6] = b3Vec3(lower.x, lower.y, upper.z);
vs[7] = b3Vec3(lower.x, upper.y, upper.z);
// Face 1 edges
DrawSegment(vs[0], vs[1], color);
DrawSegment(vs[1], vs[2], color);
DrawSegment(vs[2], vs[3], color);
DrawSegment(vs[3], vs[0], color);
// Face 2 edges
DrawSegment(vs[4], vs[5], color);
DrawSegment(vs[5], vs[6], color);
DrawSegment(vs[6], vs[7], color);
DrawSegment(vs[7], vs[4], color);
// Face 3 edges
DrawSegment(vs[2], vs[4], color);
DrawSegment(vs[5], vs[3], color);
// Face 4 edges
DrawSegment(vs[6], vs[0], color);
DrawSegment(vs[1], vs[7], color);
}
@ -1349,9 +1370,15 @@ void DebugDraw::DrawCapsule(const b3CapsuleShape* s, const b3Color& c, const b3T
if (height > 0.0f)
{
{
b3Mat33 R;
R.y = (1.0f / height) * (c1 - c2);
R.z = b3Perp(R.y);
R.x = b3Cross(R.y, R.z);
b3Transform xfc;
xfc.rotation = xf.rotation;
xfc.position = xf * ( 0.5f * (c1 + c2) );
xfc.position = xf * (0.5f * (c1 + c2));
xfc.rotation = xf.rotation * R;
m_solid->DrawCylinder(radius, height, c, xfc);
}
@ -1409,13 +1436,13 @@ void DebugDraw::DrawMesh(const b3MeshShape* s, const b3Color& c, const b3Transfo
b3Vec3 n1 = b3Cross(p2 - p1, p3 - p1);
n1.Normalize();
m_triangles->Vertex(p1, c, n1);
m_triangles->Vertex(p2, c, n1);
m_triangles->Vertex(p3, c, n1);
b3Vec3 n2 = -n1;
m_triangles->Vertex(p1, c, n2);
m_triangles->Vertex(p3, c, n2);
m_triangles->Vertex(p2, c, n2);
@ -1481,7 +1508,7 @@ void DebugDraw::Draw(const b3World& world)
DrawShape(s, c, xf);
}
}
g_debugDraw->Submit();
}

View File

@ -20,7 +20,6 @@
#define DEBUG_DRAW_H
#include <bounce/bounce.h>
#include "mat44.h"
struct DrawPoints;
struct DrawLines;
@ -28,6 +27,23 @@ struct DrawTriangles;
struct DrawWire;
struct DrawSolid;
struct Ray3
{
b3Vec3 A() const
{
return origin;
}
b3Vec3 B() const
{
return origin + fraction * direction;
}
b3Vec3 direction;
b3Vec3 origin;
float32 fraction;
};
class Camera
{
public:
@ -38,15 +54,15 @@ public:
m_width = 1024.0f;
m_height = 768.0f;
m_zNear = 1.0f;
m_zFar = 500.0f;
m_zFar = 1000.0f;
m_fovy = 0.25f * B3_PI;
m_zoom = 10.0f;
}
Mat44 BuildProjectionMatrix() const;
Mat44 BuildViewMatrix() const;
b3Mat44 BuildProjectionMatrix() const;
b3Mat44 BuildViewMatrix() const;
b3Transform BuildViewTransform() const;
Mat44 BuildWorldMatrix() const;
b3Mat44 BuildWorldMatrix() const;
b3Transform BuildWorldTransform() const;
b3Vec2 ConvertWorldToScreen(const b3Vec3& pw) const;

View File

@ -16,13 +16,18 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
#if defined(__APPLE_CC__)
#include <OpenGL/gl3.h>
#else
#include <glad/glad.h>
#include <glfw/glfw3.h>
#endif
#include <imgui/imgui.h>
#include <imgui/imgui_impl_glfw_gl3.h>
#include <testbed/tests/test.h>
#include <glfw/glfw3.h>
GLFWwindow* g_window;
Settings g_settings;
Test* g_test;
@ -35,13 +40,13 @@ bool g_rightDown;
bool g_shiftDown;
b3Vec2 g_ps0;
void WindowSize(int w, int h)
static void WindowSize(int w, int h)
{
g_camera.m_width = float32(w);
g_camera.m_height = float32(h);
}
void MouseMove(GLFWwindow* w, double x, double y)
static void MouseMove(GLFWwindow* w, double x, double y)
{
b3Vec2 ps;
ps.Set(float32(x), float32(y));
@ -83,7 +88,7 @@ void MouseMove(GLFWwindow* w, double x, double y)
}
}
void MouseWheel(GLFWwindow* w, double dx, double dy)
static void MouseWheel(GLFWwindow* w, double dx, double dy)
{
float32 n = b3Clamp(float32(dy), -1.0f, 1.0f);
if (g_shiftDown)
@ -92,7 +97,7 @@ void MouseWheel(GLFWwindow* w, double dx, double dy)
}
}
void MouseButton(GLFWwindow* w, int button, int action, int mods)
static void MouseButton(GLFWwindow* w, int button, int action, int mods)
{
double x, y;
glfwGetCursorPos(w, &x, &y);
@ -147,7 +152,7 @@ void MouseButton(GLFWwindow* w, int button, int action, int mods)
}
}
void KeyButton(GLFWwindow* w, int button, int scancode, int action, int mods)
static void KeyButton(GLFWwindow* w, int button, int scancode, int action, int mods)
{
switch (action)
{
@ -163,12 +168,12 @@ void KeyButton(GLFWwindow* w, int button, int scancode, int action, int mods)
{
if (button == GLFW_KEY_DOWN)
{
g_camera.m_zoom += 0.05f;
g_camera.m_zoom += 0.2f;
}
if (button == GLFW_KEY_UP)
{
g_camera.m_zoom -= 0.05f;
g_camera.m_zoom -= 0.2f;
}
}
else
@ -199,30 +204,30 @@ void KeyButton(GLFWwindow* w, int button, int scancode, int action, int mods)
}
}
void Char(GLFWwindow* w, unsigned int codepoint)
static void Char(GLFWwindow* w, unsigned int codepoint)
{
ImGui_ImplGlfwGL3_CharCallback(w, codepoint);
}
void CreateInterface()
static void CreateInterface()
{
ImGui_ImplGlfwGL3_Init(g_window, false);
ImGuiIO& io = ImGui::GetIO();
io.Fonts[0].AddFontDefault();
}
void DestroyInterface()
static void DestroyInterface()
{
ImGui_ImplGlfwGL3_Shutdown();
}
bool GetTestName(void*, int idx, const char** name)
static bool GetTestName(void*, int idx, const char** name)
{
*name = g_tests[idx].name;
return true;
}
void Interface()
static void Interface()
{
ImGui::SetNextWindowPos(ImVec2(g_camera.m_width, 0.0f));
ImGui::SetNextWindowSize(ImVec2(250.0f, g_camera.m_height));
@ -255,11 +260,18 @@ void Interface()
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");
@ -271,8 +283,8 @@ void Interface()
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);
//ImGui::Checkbox("Convex Cache", &g_settings.convexCache);
if (ImGui::Button("Play/Pause", buttonSize))
{
@ -283,7 +295,7 @@ void Interface()
g_settings.pause = true;
g_settings.singleStep = true;
}
ImGui::Separator();
ImGui::Text("View");
@ -296,6 +308,7 @@ void Interface()
ImGui::Checkbox("Contact Points", &g_settings.drawContactPoints);
ImGui::Checkbox("Contact Normals", &g_settings.drawContactNormals);
ImGui::Checkbox("Contact Tangents", &g_settings.drawContactTangents);
ImGui::Checkbox("Contact Areas", &g_settings.drawContactAreas);
ImGui::Checkbox("Statistics", &g_settings.drawStats);
ImGui::Checkbox("Profile", &g_settings.drawProfile);
@ -303,10 +316,16 @@ void Interface()
ImGui::PopStyleVar();
}
void Step()
static void Step()
{
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;
@ -314,7 +333,6 @@ void Step()
t.y = 0.0f;
t.z = -0.5f * float32(n);
b3Color color(0.5f, 0.5f, 0.5f, 1.0f);
for (int i = 0; i < n; i += 1)
{
for (int j = 0; j < n; j += 1)
@ -347,16 +365,16 @@ void Step()
g_debugDraw->Submit();
}
void Run()
static void Run()
{
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClearDepth(1.0f);
double t1 = glfwGetTime();
@ -489,5 +507,6 @@ int main(int argc, char** args)
// Destroy g_window
glfwTerminate();
return 0;
}

View File

@ -1,131 +0,0 @@
/*
* 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 MAT44_H
#define MAT44_H
#include <bounce/bounce.h>
struct Vec4
{
Vec4() { }
Vec4(float32 _x, float32 _y, float32 _z, float32 _w) : x(_x), y(_y), z(_z), w(_w) { }
void SetZero()
{
x = y = z = w = 0.0f;
}
void Set(float32 _x, float32 _y, float32 _z, float32 _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
}
float32 x, y, z, w;
};
inline Vec4 operator+(const Vec4& a, const Vec4& b)
{
return Vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
}
inline Vec4 operator*(float32 s, const Vec4& v)
{
return Vec4(s * v.x, s * v.y, s * v.z, s * v.w);
}
struct Mat44
{
Mat44() { }
Mat44(const Vec4& _x, const Vec4& _y, const Vec4& _z, const Vec4& _w) : x(_x), y(_y), z(_z), w(_w) { }
void SetIdentity()
{
x.Set(1.0f, 0.0f, 0.0f, 0.0f);
y.Set(0.0f, 1.0f, 0.0f, 0.0f);
z.Set(0.0f, 0.0f, 1.0f, 0.0f);
w.Set(0.0f, 0.0f, 0.0f, 1.0f);
}
Vec4 x, y, z, w;
};
inline Vec4 operator*(const Mat44& A, const Vec4& v)
{
return v.x * A.x + v.y * A.y + v.z * A.z + v.w * A.w;
}
inline b3Vec3 operator*(const Mat44& A, const b3Vec3& v)
{
Vec4 q = v.x * A.x + v.y * A.y + v.z * A.z + A.w;
return b3Vec3(q.x, q.y, q.z);
}
inline Mat44 operator*(const Mat44& A, const Mat44& B)
{
return Mat44(A * B.x, A * B.y, A * B.z, A * B.w);
}
inline Mat44 GetMat44(const b3Transform& T)
{
return Mat44(
Vec4(T.rotation.x.x, T.rotation.x.y, T.rotation.x.z, 0.0f),
Vec4(T.rotation.y.x, T.rotation.y.y, T.rotation.y.z, 0.0f),
Vec4(T.rotation.z.x, T.rotation.z.y, T.rotation.z.z, 0.0f),
Vec4(T.position.x, T.position.y, T.position.z, 1.0f));
}
inline b3Transform GetTransform(const Mat44& T)
{
b3Transform xf;
xf.rotation.x.Set(T.x.x, T.x.y, T.x.z);
xf.rotation.y.Set(T.y.x, T.y.y, T.y.z);
xf.rotation.z.Set(T.z.x, T.z.y, T.z.z);
xf.position.Set(T.w.x, T.w.y, T.w.z);
return xf;
}
inline float32 RandomFloat(float32 a, float32 b)
{
float32 x = float32(rand()) / float32(RAND_MAX);
float32 diff = b - a;
float32 r = x * diff;
return a + r;
}
struct Ray3
{
b3Vec3 Start() const
{
return origin;
}
b3Vec3 End() const
{
return origin + fraction * direction;
}
b3Vec3 direction;
b3Vec3 origin;
float32 fraction;
};
#endif

View File

@ -20,8 +20,8 @@
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 bool b3_enableConvexCache;
extern b3Draw* b3_debugDraw;
extern Settings g_settings;
@ -29,21 +29,86 @@ extern DebugDraw* g_debugDraw;
extern Camera g_camera;
extern Profiler* g_profiler;
static void BuildGrid(b3Mesh* mesh, u32 w, u32 h, bool randomY = false)
{
b3Vec3 t;
t.x = -0.5f * float32(w);
t.y = 0.0f;
t.z = -0.5f * float32(h);
mesh->vertexCount = w * h;
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
for (u32 i = 0; i < w; ++i)
{
for (u32 j = 0; j < h; ++j)
{
u32 v1 = i * w + j;
b3Vec3 v;
v.x = float32(i);
v.y = randomY ? RandomFloat(0.0f, 1.0f) : 0.0f;
v.z = float32(j);
v += t;
mesh->vertices[v1] = v;
}
}
mesh->triangleCount = 2 * (w - 1) * (h - 1);
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
u32 triangleCount = 0;
for (u32 i = 0; i < w - 1; ++i)
{
for (u32 j = 0; j < h - 1; ++j)
{
u32 v1 = i * w + j;
u32 v2 = (i + 1) * w + j;
u32 v3 = (i + 1) * w + (j + 1);
u32 v4 = i * w + (j + 1);
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t1 = mesh->triangles + triangleCount;
++triangleCount;
t1->v1 = v3;
t1->v2 = v2;
t1->v3 = v1;
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t2 = mesh->triangles + triangleCount;
++triangleCount;
t2->v1 = v1;
t2->v2 = v4;
t2->v3 = v3;
}
}
B3_ASSERT(triangleCount == mesh->triangleCount);
mesh->BuildTree();
}
Test::Test()
{
b3_allocCalls = 0;
b3_gjkCalls = 0;
b3_gjkIters = 0;
b3_gjkMaxIters = 0;
b3_convexCache = g_settings.convexCache;
b3_convexCalls = 0;
b3_convexCacheHits = 0;
b3_enableConvexCache = g_settings.convexCache;
b3_debugDraw = g_debugDraw;
m_world.SetContactListener(this);
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);
b3Quat q_y(b3Vec3(0.0f, 1.0f, 0.0f), 0.15f * B3_PI);
b3Quat q_x(b3Quat(b3Vec3(1.0f, 0.0f, 0.0f), -0.15f * B3_PI));
g_camera.m_q = q_y * q_x;
g_camera.m_zoom = 50.0f;
g_camera.m_center.SetZero();
@ -51,255 +116,17 @@ Test::Test()
m_mouseJoint = NULL;
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(50.0f, 1.0f, 50.0f);
m_groundHull.SetTransform(xf);
b3Transform m;
m.position.SetZero();
m.rotation = b3Diagonal(50.0f, 1.0f, 50.0f);
m_groundHull.SetTransform(m);
}
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(1.0f, 1.0f, 1.0f);
m_boxHull.SetTransform(xf);
}
m_boxHull.SetIdentity();
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(1.0f, 5.0f, 1.0f);
m_tallHull.SetTransform(xf);
}
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(2.0f, 4.0f, 0.5f);
m_doorHull.SetTransform(xf);
}
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(25.0f, 0.5f, 25.0f);
m_rampHull.SetTransform(xf);
}
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(1.0f, 0.5f, 3.0f);
m_plankHull.SetTransform(xf);
}
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(4.05f, 2.0f * B3_LINEAR_SLOP, 4.05f);
m_thinHull.SetTransform(xf);
}
{
const u32 w = 5;
const u32 h = 5;
b3Vec3 t;
t.x = -0.5f * float32(w);
t.y = 0.0f;
t.z = -0.5f * float32(h);
b3Mesh* mesh = m_meshes + e_clothMesh;
mesh->vertexCount = w * h;
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
for (u32 i = 0; i < w; ++i)
{
for (u32 j = 0; j < h; ++j)
{
u32 v1 = i * w + j;
b3Vec3 v;
v.x = float32(i);
v.y = RandomFloat(0.0f, 0.5f);
v.z = float32(j);
v += t;
mesh->vertices[v1] = v;
}
}
mesh->triangleCount = 2 * (w - 1) * (h - 1);
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
u32 triangleCount = 0;
for (u32 i = 0; i < w - 1; ++i)
{
for (u32 j = 0; j < h - 1; ++j)
{
u32 v1 = i * w + j;
u32 v2 = (i + 1) * w + j;
u32 v3 = (i + 1) * w + (j + 1);
u32 v4 = i * w + (j + 1);
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t1 = mesh->triangles + triangleCount;
++triangleCount;
t1->v1 = v3;
t1->v2 = v2;
t1->v3 = v1;
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t2 = mesh->triangles + triangleCount;
++triangleCount;
t2->v1 = v1;
t2->v2 = v4;
t2->v3 = v3;
}
}
B3_ASSERT(triangleCount == mesh->triangleCount);
mesh->BuildTree();
}
{
const u32 w = 50;
const u32 h = 50;
b3Vec3 t;
t.x = -0.5f * float32(w);
t.y = 0.0f;
t.z = -0.5f * float32(h);
b3Mesh* mesh = m_meshes + e_gridMesh;
mesh->vertexCount = w * h;
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
for (u32 i = 0; i < w; ++i)
{
for (u32 j = 0; j < h; ++j)
{
u32 v1 = i * w + j;
b3Vec3 v;
v.x = float32(i);
v.y = 0.0f;
v.z = float32(j);
v += t;
mesh->vertices[v1] = v;
}
}
// 2 triangles per quad
mesh->triangleCount = 2 * (w - 1) * (h - 1);
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
u32 triangleCount = 0;
for (u32 i = 0; i < w - 1; ++i)
{
for (u32 j = 0; j < h - 1; ++j)
{
u32 v1 = i * w + j;
u32 v2 = (i + 1) * w + j;
u32 v3 = (i + 1) * w + (j + 1);
u32 v4 = i * w + (j + 1);
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t1 = mesh->triangles + triangleCount;
++triangleCount;
t1->v1 = v3;
t1->v2 = v2;
t1->v3 = v1;
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t2 = mesh->triangles + triangleCount;
++triangleCount;
t2->v1 = v1;
t2->v2 = v4;
t2->v3 = v3;
}
}
B3_ASSERT(triangleCount == mesh->triangleCount);
mesh->BuildTree();
}
{
const u32 w = 50;
const u32 h = 50;
b3Vec3 t;
t.x = -0.5f * float32(w);
t.y = 0.0f;
t.z = -0.5f * float32(h);
b3Mesh* mesh = m_meshes + e_terrainMesh;
mesh->vertexCount = w * h;
mesh->vertices = (b3Vec3*)b3Alloc(mesh->vertexCount * sizeof(b3Vec3));
for (u32 i = 0; i < w; ++i)
{
for (u32 j = 0; j < h; ++j)
{
u32 v1 = i * w + j;
b3Vec3 v;
v.x = 2.0f * float32(i);
v.y = RandomFloat(0.0f, 0.5f);
v.z = 2.0f *float32(j);
v += t;
mesh->vertices[v1] = v;
}
}
mesh->triangleCount = 2 * (w - 1) * (h - 1);
mesh->triangles = (b3Triangle*)b3Alloc(mesh->triangleCount * sizeof(b3Triangle));
u32 triangleCount = 0;
for (u32 i = 0; i < w - 1; ++i)
{
for (u32 j = 0; j < h - 1; ++j)
{
u32 v1 = i * w + j;
u32 v2 = (i + 1) * w + j;
u32 v3 = (i + 1) * w + (j + 1);
u32 v4 = i * w + (j + 1);
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t1 = mesh->triangles + triangleCount;
++triangleCount;
t1->v1 = v3;
t1->v2 = v2;
t1->v3 = v1;
B3_ASSERT(triangleCount < mesh->triangleCount);
b3Triangle* t2 = mesh->triangles + triangleCount;
++triangleCount;
t2->v1 = v1;
t2->v2 = v4;
t2->v3 = v3;
}
}
B3_ASSERT(triangleCount == mesh->triangleCount);
mesh->BuildTree();
}
BuildGrid(m_meshes + e_gridMesh, 50, 50);
BuildGrid(m_meshes + e_terrainMesh, 50, 50, true);
BuildGrid(m_meshes + e_clothMesh, 10, 10);
}
Test::~Test()
@ -345,10 +172,10 @@ void Test::Step()
b3_gjkCalls = 0;
b3_gjkIters = 0;
b3_gjkMaxIters = 0;
b3_convexCache = g_settings.convexCache;
b3_convexCalls = 0;
b3_convexCacheHits = 0;
b3_enableConvexCache = g_settings.convexCache;
// Step
ProfileBegin();
@ -369,6 +196,7 @@ void Test::Step()
drawFlags += g_settings.drawContactPoints * b3Draw::e_contactPointsFlag;
drawFlags += g_settings.drawContactNormals * b3Draw::e_contactNormalsFlag;
drawFlags += g_settings.drawContactTangents * b3Draw::e_contactTangentsFlag;
drawFlags += g_settings.drawContactAreas * b3Draw::e_contactAreasFlag;
g_debugDraw->SetFlags(drawFlags);
m_world.DebugDraw();
@ -448,7 +276,7 @@ void Test::MouseMove(const Ray3& pw)
float32 w1 = 1.0f - t;
float32 w2 = t;
b3Vec3 target = w1 * pw.Start() + w2 * pw.End();
b3Vec3 target = w1 * pw.A() + w2 * pw.B();
m_mouseJoint->SetTarget(target);
}
}
@ -468,8 +296,8 @@ void Test::MouseLeftDown(const Ray3& pw)
}
// Perform the ray cast
b3Vec3 p1 = pw.Start();
b3Vec3 p2 = pw.End();
b3Vec3 p1 = pw.A();
b3Vec3 p2 = pw.B();
b3RayCastSingleOutput out;
if (m_world.RayCastSingle(&out, p1, p2))

View File

@ -20,20 +20,25 @@
#include <testbed/tests/quickhull_test.h>
#include <testbed/tests/cluster_test.h>
#include <testbed/tests/distance_test.h>
#include <testbed/tests/capsule_distance.h>
#include <testbed/tests/collide_test.h>
#include <testbed/tests/capsule_collision.h>
#include <testbed/tests/capsule_and_hull_collision.h>
#include <testbed/tests/capsule_and_hull_collision_1.h>
#include <testbed/tests/capsule_and_hull_collision_2.h>
#include <testbed/tests/hull_collision.h>
#include <testbed/tests/hull_collision_2.h>
#include <testbed/tests/linear_motion.h>
#include <testbed/tests/angular_motion.h>
#include <testbed/tests/multiple_shapes.h>
#include <testbed/tests/initial_overlap.h>
#include <testbed/tests/capsule_and_hull_contact_1.h>
#include <testbed/tests/quadric_shapes.h>
#include <testbed/tests/multiple_shapes.h>
#include <testbed/tests/gyro_test.h>
#include <testbed/tests/spring.h>
#include <testbed/tests/weld_test.h>
#include <testbed/tests/newton_cradle.h>
#include <testbed/tests/cone_test.h>
#include <testbed/tests/hinge_motor.h>
#include <testbed/tests/hinge_chain.h>
#include <testbed/tests/newton_cradle.h>
#include <testbed/tests/ragdoll.h>
#include <testbed/tests/mesh_contact_test.h>
#include <testbed/tests/sphere_stack.h>
@ -51,27 +56,32 @@
#include <testbed/tests/varying_friction.h>
#include <testbed/tests/varying_restitution.h>
#include <testbed/tests/cloth_test.h>
#include <testbed/tests/tumbler.h>
TestEntry g_tests[] =
{
{ "Quickhull Test", &QuickhullTest::Create },
{ "Cluster Test", &Cluster::Create },
{ "Distance Test", &Distance::Create },
{ "Capsule Distance", &CapsuleDistance::Create },
{ "Capsule Collision", &CapsuleCollision::Create },
{ "Capsule and Hull Collision", &CapsuleAndHull::Create },
{ "Hull Collision", &HullAndHull::Create },
{ "Capsule and Hull Collision (1)", &CapsuleAndHullCollision1::Create },
{ "Capsule and Hull Collision (2)", &CapsuleAndHullCollision2::Create },
{ "Hull Collision (1)", &HullAndHull::Create },
{ "Hull Collision (2)", &HullAndHull2::Create },
{ "Capsule and Hull Contact (1)", &CapsuleAndHullContact1::Create },
{ "Linear Motion", &LinearMotion::Create },
{ "Angular Motion", &AngularMotion::Create },
{ "Multiple Shapes", &MultipleShapes::Create },
{ "Quadric Shapes", &QuadricShapes::Create },
{ "Thin Boxes", &Thin::Create },
{ "Gyroscopic Test", &GyroTest::Create },
{ "Springs", &Spring::Create },
{ "Weld Test", &WeldTest::Create },
{ "Newton's Cradle", &NewtonCradle::Create },
{ "Cone Test", &ConeTest::Create },
{ "Hinge Motor", &HingeMotor::Create },
{ "Hinge Chain", &HingeChain::Create },
{ "Ragdoll", &Ragdoll::Create },
{ "Thin Boxes", &Thin::Create },
{ "Newton's Cradle", &NewtonCradle::Create },
{ "Mesh Contact Test", &MeshContactTest::Create },
{ "Sphere Stack", &SphereStack::Create },
{ "Capsule Stack", &CapsuleStack::Create },
@ -87,5 +97,7 @@ TestEntry g_tests[] =
{ "Varying Friction", &VaryingFriction::Create },
{ "Varying Restitution", &VaryingRestitution::Create },
{ "Cloth", &Cloth::Create },
{ "Tumbler", &Tumbler::Create },
{ "Initial Overlap", &InitialOverlap::Create },
{ NULL, NULL }
};

View File

@ -24,56 +24,33 @@ class AngularMotion : public Test
public:
AngularMotion()
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(0.0f, 0.0f, 0.0f);
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
m_body = m_world.CreateBody(bdef);
bd.type = e_dynamicBody;
bd.angularVelocity.Set(0.0f, B3_PI, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3CapsuleShape shape;
shape.m_centers[0].Set(0.0f, 1.0f, 0.0f);
shape.m_centers[1].Set(0.0f, -1.0f, 0.0f);
shape.m_centers[0].Set(0.0f, 0.0f, -1.0f);
shape.m_centers[1].Set(0.0f, 0.0f, 1.0f);
shape.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.shape = &shape;
sdef.density = 1.0f;
m_body->CreateShape(sdef);
b3MassData data;
m_body->GetMassData(&data);
m_body->SetMassData(&data);
b3Vec3 g(0.0f, 0.0f, 0.0f);
m_world.SetGravity(g);
}
void Step()
{
Test::Step();
b3Vec3 v(0.0f, 0.0f, 0.0f);
m_body->SetLinearVelocity(v);
b3Vec3 p = m_body->GetSweep().worldCenter;
b3Quat quat = m_body->GetSweep().orientation;
b3Vec3 axis;
float32 angle;
quat.GetAxisAngle(&axis, &angle);
body->CreateShape(sdef);
b3Vec3 q(0.0f, 0.0f, 0.0f);
m_body->SetTransform(q, axis, angle);
b3SphereJointDef jd;
jd.Initialize(ground, body, b3Vec3(0.0f, 0.0f, 0.0f));
m_world.CreateJoint(jd);
}
static Test* Create()
{
return new AngularMotion();
}
b3Body* m_body;
};
#endif

View File

@ -33,7 +33,7 @@ public:
{
g_camera.m_center.Set(2.5f, -2.0f, 5.5f);
g_camera.m_zoom = 40.0f;
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
@ -45,17 +45,22 @@ public:
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.userData = NULL;
sdef.friction = 1.0f;
b3Shape* shape = body->CreateShape(sdef);
body->CreateShape(sdef);
}
b3Vec3 stackOrigin;
stackOrigin.Set(0.0f, 4.05f, 0.0f);
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();
b3Vec3 boxScale;
boxScale.Set(2.05f, 2.05f, 2.05f);
boxHull.SetTransform(m);
b3Vec3 stackOrigin(0.0f, 4.05f, 0.0f);
for (u32 i = 0; i < e_rowCount; ++i)
{
@ -65,24 +70,25 @@ public:
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_dynamicBody;
bdef.orientation.Set(b3Vec3(0.0f, 1.0f, 0.0f), 0.5f * B3_PI);
bdef.position.x = float32(i) * boxScale.x;
bdef.position.y = 1.5f * float32(j) * boxScale.y;
bdef.position.y = 2.5f * float32(j) * boxScale.y;
bdef.position.z = float32(k) * boxScale.z;
bdef.position += stackOrigin;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.density = 0.5f;
sdef.density = 0.1f;
sdef.friction = 0.3f;
sdef.shape = &hs;
sdef.userData = NULL;
b3Shape* shape = body->CreateShape(sdef);
body->CreateShape(sdef);
}
}
}
@ -94,4 +100,4 @@ public:
}
};
#endif
#endif

View File

@ -16,18 +16,18 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CAPSULE_HULL_H
#define CAPSULE_HULL_H
#ifndef CAPSULE_HULL_COLLISION_1_H
#define CAPSULE_HULL_COLLISION_1_H
class CapsuleAndHull : public Collide
class CapsuleAndHullCollision1 : public Collide
{
public:
CapsuleAndHull()
CapsuleAndHullCollision1()
{
m_xfA.position.Set(0.0f, 0.0f, 0.0f);
m_xfA.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.55f * B3_PI));
m_sA.m_centers[0].Set(0.0f, -1.0f, 0.0f);
m_sA.m_centers[0].Set(1.0f, -1.0f, 0.0f);
m_sA.m_centers[1].Set(0.0f, 1.0f, 0.0f);
m_sA.m_radius = 2.0f;
@ -49,7 +49,7 @@ public:
static Test* Create()
{
return new CapsuleAndHull();
return new CapsuleAndHullCollision1();
}
b3CapsuleShape m_sA;

View File

@ -0,0 +1,60 @@
/*
* 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 CAPSULE_HULL_2_H
#define CAPSULE_HULL_2_H
class CapsuleAndHullCollision2 : public Collide
{
public:
CapsuleAndHullCollision2()
{
m_xfA.position.Set(0.0f, 0.0f, 0.0f);
m_xfA.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.55f * B3_PI));
m_sA.m_centers[0].Set(0.0f, 0.0f, 0.0f);
m_sA.m_centers[1].Set(0.0f, 0.0f, 0.0f);
m_sA.m_radius = 0.05f;
m_xfB.position.Set(0.f, 0.0f, 0.0f);
m_xfB.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.0f * B3_PI));
b3Transform xf;
xf.SetIdentity();
xf.rotation = b3Diagonal(4.0f, 1.0f, 4.0f);
m_box.SetTransform(xf);
m_sB.m_hull = &m_box;
m_shapeA = &m_sA;
m_shapeB = &m_sB;
m_cache.count = 0;
}
static Test* Create()
{
return new CapsuleAndHullCollision2();
}
b3CapsuleShape m_sA;
b3HullShape m_sB;
b3BoxHull m_box;
};
#endif

View File

@ -0,0 +1,69 @@
/*
* 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 CAPSULE_HULL_CONTACT_1_H
#define CAPSULE_HULL_CONTACT_1_H
class CapsuleAndHullContact1 : public Test
{
public:
CapsuleAndHullContact1()
{
{
b3BodyDef bd;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
body->CreateShape(sd);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(0.0f, 10.0f, 0.0f);
bdef.orientation.Set(b3Vec3(0.0f, 0.0f, -1.0f), 1.5f * B3_PI);
bdef.linearVelocity.Set(0.005f, -10.0f, 0.005f);
bdef.angularVelocity.Set(2000.0f * B3_PI, 2000.0f * B3_PI, 10000.0f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3CapsuleShape capsule;
capsule.m_centers[0].Set(0.0f, 4.0f, 0.0f);
capsule.m_centers[1].Set(0.0f, -4.0f, 0.0f);
capsule.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &capsule;
sd.density = 0.1f;
body->CreateShape(sd);
}
}
static Test* Create()
{
return new CapsuleAndHullContact1();
}
};
#endif

View File

@ -1,128 +0,0 @@
/*
* 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 CAPSULE_DISTANCE_H
#define CAPSULE_DISTANCE_H
extern DebugDraw* g_debugDraw;
extern Camera g_camera;
class CapsuleDistance : public Test
{
public:
CapsuleDistance()
{
g_camera.m_zoom = 25.0f;
m_xfA.SetIdentity();
m_xfA.position.Set(-5.0f, 0.0f, 0.0f);
m_xfA.rotation.SetIdentity();
m_shapeA.m_centers[0].Set(0.0f, -2.0f, 0.0f);
m_shapeA.m_centers[1].Set(0.0f, 2.0f, 0.0f);
m_shapeA.m_radius = 1.0f;
m_xfB.SetIdentity();
m_xfB.position.Set(5.0f, 0.0f, 0.0f);
m_xfB.rotation.SetIdentity();
m_shapeB.m_centers[0].Set(0.0f, -2.0f, 0.0f);
m_shapeB.m_centers[1].Set(0.0f, 2.0f, 0.0f);
m_shapeB.m_radius = 1.0f;
}
void Step()
{
b3Capsule edgeA;
edgeA.vertices[0] = m_xfA * m_shapeA.m_centers[0];
edgeA.vertices[1] = m_xfA * m_shapeA.m_centers[1];
edgeA.radius = m_shapeA.m_radius;
b3Capsule edgeB;
edgeB.vertices[0] = m_xfB * m_shapeB.m_centers[0];
edgeB.vertices[1] = m_xfB * m_shapeB.m_centers[1];
edgeB.radius = m_shapeB.m_radius;
b3Vec3 pointA, pointB;
b3ClosestPointsOnSegments(&pointA, &pointB, edgeA.vertices[0], edgeA.vertices[1], edgeB.vertices[1], edgeB.vertices[0]);
if (b3Distance(pointA, pointB) > 0.0f)
{
g_debugDraw->DrawPoint(pointA, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawPoint(pointB, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(pointA, pointB, b3Color(1.0f, 1.0f, 1.0f));
}
g_debugDraw->DrawTransform(m_xfA);
g_debugDraw->DrawTransform(m_xfB);
m_world.DrawShape(m_xfA, &m_shapeA);
m_world.DrawShape(m_xfB, &m_shapeB);
}
void KeyDown(int key)
{
if (key == GLFW_KEY_LEFT)
{
m_xfB.position.x -= 0.05f;
}
if (key == GLFW_KEY_RIGHT)
{
m_xfB.position.x += 0.05f;
}
if (key == GLFW_KEY_UP)
{
m_xfB.position.y += 0.05f;
}
if (key == GLFW_KEY_DOWN)
{
m_xfB.position.y -= 0.05f;
}
if (key == GLFW_KEY_X)
{
b3Quat qx(b3Vec3(1.0f, 0.0f, 0.0f), 0.05f * B3_PI);
b3Mat33 xfx = b3ConvertQuatToRot(qx);
m_xfB.rotation = m_xfB.rotation * xfx;
}
if (key == GLFW_KEY_Y)
{
b3Quat qy(b3Vec3(0.0f, 1.0f, 0.0f), 0.05f * B3_PI);
b3Mat33 xfy = b3ConvertQuatToRot(qy);
m_xfB.rotation = m_xfB.rotation * xfy;
}
}
static Test* Create()
{
return new CapsuleDistance();
}
b3CapsuleShape m_shapeA;
b3Transform m_xfA;
b3CapsuleShape m_shapeB;
b3Transform m_xfB;
};
#endif

View File

@ -24,9 +24,9 @@ class CapsuleStack : public Test
public:
enum
{
e_rowCount = 5,
e_rowCount = 1,
e_columnCount = 5,
e_depthCount = 5
e_depthCount = 1
};
CapsuleStack()
@ -57,8 +57,8 @@ public:
b3ShapeDef sdef;
sdef.shape = &capsule;
sdef.density = 1.0f;
sdef.friction = 0.3f;
sdef.density = 0.1f;
sdef.friction = 0.4f;
const u32 c = e_rowCount * e_columnCount * e_depthCount;
b3Body* bs[c];
@ -78,7 +78,7 @@ public:
bdef.type = b3BodyType::e_dynamicBody;
bdef.position.x = (2.0f + separation) * float32(i) * (0.5f * height + radius);
bdef.position.y = (2.0f + separation) * float32(j) * radius;
bdef.position.y = 2.0f + (2.0f + separation) * float32(j) * radius;
bdef.position.z = (2.0f + separation) * float32(k) * radius;
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
@ -108,7 +108,7 @@ public:
b3Vec3 position = p - center;
// move up
position.y += 0.5f * aabb.Height() + radius;
position.y += 5.0f + 0.5f * aabb.Height() + radius;
// maintain orientation
b3Vec3 axis;

View File

@ -33,18 +33,24 @@ public:
b3ClothDef def;
def.mesh = m_meshes + e_clothMesh;
def.density = 0.2f;
def.gravity.Set(-10.0f, 1.0f, 0.0f);
def.k1 = 0.5f;
def.k2 = 0.05f;
def.kd = 0.1f;
def.gravity.Set(2.5f, 5.0f, -10.0f);
def.k1 = 0.2f;
def.k2 = 0.1f;
def.kd = 0.005f;
def.r = 1.0f;
m_cloth.Initialize(def);
m_aabb.m_lower.Set(-5.0f, -1.0f, -6.0f);
m_aabb.m_upper.Set(5.0f, 1.0f, -4.0f);
b3Particle* vs = m_cloth.GetVertices();
for (u32 i = 0; i < 5; ++i)
for (u32 i = 0; i < m_cloth.GetVertexCount(); ++i)
{
vs[i].im = 0.0f;
if (m_aabb.Contains(vs[i].p))
{
vs[i].im = 0.0f;
}
}
}
@ -66,6 +72,8 @@ public:
m_cloth.Step(dt, g_settings.positionIterations);
m_cloth.Draw(g_debugDraw);
//g_debugDraw->DrawAABB(m_aabb, b3Color_black);
}
static Test* Create()
@ -74,6 +82,7 @@ public:
}
b3Cloth m_cloth;
b3AABB3 m_aabb;
};
#endif

View File

@ -38,33 +38,33 @@ public:
cache.featureCache.m_featurePair.state = b3SATCacheType::e_empty;
b3Manifold manifold;
manifold.GuessImpulses();
manifold.Initialize();
b3CollideShapeAndShape(manifold, m_xfA, m_shapeA, m_xfB, m_shapeB, &cache);
b3WorldManifold wm;
wm.Initialize(&manifold, m_xfA, m_shapeA->m_radius, m_xfB, m_shapeB->m_radius);
for (u32 i = 0; i < wm.pointCount; ++i)
for (u32 i = 0; i < manifold.pointCount; ++i)
{
b3WorldManifoldPoint* wmp = wm.points + i;
b3Vec3 pw = wmp->point;
b3WorldManifold wm;
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);
g_debugDraw->DrawPoint(pw, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(pw, pw + wmp->normal, b3Color(1.0f, 1.0f, 1.0f));
g_debugDraw->DrawSegment(pw, pw + wm.points[i].normal, b3Color(1.0f, 1.0f, 1.0f));
}
if (wm.pointCount > 0)
if (g_settings.drawFaces)
{
g_debugDraw->DrawPoint(wm.center, 4.0f, b3Color(1.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(wm.center, wm.center + wm.normal, b3Color(1.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(wm.center, wm.center + wm.tangent1, b3Color(1.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(wm.center, wm.center + wm.tangent2, b3Color(1.0f, 1.0f, 0.0f));
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);
}
m_world.DrawShape(m_xfA, m_shapeA);
m_world.DrawShape(m_xfB, m_shapeB);
if (g_settings.drawVerticesEdges)
{
m_world.DrawShape(m_xfA, m_shapeA);
m_world.DrawShape(m_xfB, m_shapeB);
}
}
virtual void KeyDown(int key)

View File

@ -0,0 +1,84 @@
/*
* 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 CONE_TEST_H
#define CONE_TEST_H
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;
{
b3BodyDef bd;
//bd.type = e_dynamicBody;
bd.position.Set(0.0f, 0.0f, 0.0f);
ref = m_world.CreateBody(bd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.0f, 2.0f, 0.0f);
bd.angularVelocity.Set(0.0f, 0.05f * B3_PI, 0.0f);
head = m_world.CreateBody(bd);
b3CapsuleShape cs;
cs.m_centers[0].Set(0.0f, 0.15f, 0.0f);
cs.m_centers[1].Set(0.0f, -0.15f, 0.0f);
cs.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 10.0f;
head->CreateShape(sd);
}
{
b3Vec3 anchor(0.0f, 0.0f, 0.0f);
b3Vec3 axis(0.0f, 1.0f, 0.0f);
float32 coneAngle = 0.5f * B3_PI;
b3ConeJointDef cd;
cd.Initialize(ref, head, axis, anchor, coneAngle);
cd.enableLimit = true;
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
// Invalidate the orientation
b3Vec3 axis(1.0f, 0.0f, 0.0f);
float32 angle = B3_PI;
head->SetTransform(head->GetPosition(), axis, angle);
}
static Test* Create()
{
return new ConeTest();
}
};
#endif

View File

@ -54,22 +54,22 @@ public:
{
b3GJKFeaturePair featurePair = b3GetFeaturePair(m_cache);
for (u32 i = 0; i < featurePair.countA; ++i)
for (u32 i = 0; i < featurePair.count1; ++i)
{
u32 index = featurePair.indexA[i];
u32 index = featurePair.index1[i];
g_debugDraw->DrawPoint(m_xfA * m_proxyA.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f));
}
for (u32 i = 0; i < featurePair.countB; ++i)
for (u32 i = 0; i < featurePair.count2; ++i)
{
u32 index = featurePair.indexB[i];
u32 index = featurePair.index2[i];
g_debugDraw->DrawPoint(m_xfB * m_proxyB.GetVertex(index), 4.0f, b3Color(1.0f, 1.0f, 0.0f));
}
}
g_debugDraw->DrawPoint(out.pointA, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawPoint(out.pointB, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(out.pointA, out.pointB, b3Color(1.0f, 1.0f, 1.0f));
g_debugDraw->DrawPoint(out.point1, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawPoint(out.point2, 4.0f, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(out.point1, out.point2, b3Color(1.0f, 1.0f, 1.0f));
g_debugDraw->DrawTransform(m_xfA);
g_debugDraw->DrawTransform(m_xfB);

View File

@ -0,0 +1,119 @@
/*
* 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 GYRO_TEST_H
#define GYRO_TEST_H
#include <testbed/tests/quickhull_test.h>
extern DebugDraw* g_debugDraw;
extern Camera g_camera;
extern Settings g_settings;
class GyroTest : public Test
{
public:
GyroTest()
{
{
b3StackArray<b3Vec3, 32> points;
ConstructCylinder(points, 0.95f, 4.0f);
const u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_cylinderHull = ConvertHull(hull);
b3Free(p);
}
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.orientation.Set(b3Vec3(1.0f, 0.0f, 0.0f), 0.5f * B3_PI);
bdef.position.Set(0.0f, 10.0f, 0.0f);
bdef.angularVelocity.Set(0.0f, 0.0f, 4.0f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(1.0f, 0.5f, 7.0f);
m_rotorBox.SetTransform(xf);
b3HullShape hull;
hull.m_hull = &m_rotorBox;
b3ShapeDef sdef;
sdef.density = 0.1f;
sdef.shape = &hull;
body->CreateShape(sdef);
}
{
b3HullShape hull;
hull.m_hull = &m_cylinderHull;
b3ShapeDef sdef;
sdef.density = 0.2f;
sdef.shape = &hull;
body->CreateShape(sdef);
}
}
m_world.SetGravity(b3Vec3(0.0f, 0.0f, 0.0f));
}
~GyroTest()
{
{
b3Free(m_cylinderHull.vertices);
b3Free(m_cylinderHull.edges);
b3Free(m_cylinderHull.faces);
b3Free(m_cylinderHull.planes);
}
}
static Test* Create()
{
return new GyroTest();
}
b3BoxHull m_rotorBox;
b3Hull m_cylinderHull;
};
#endif

View File

@ -28,6 +28,14 @@ public:
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;
xf.position.SetZero();
xf.rotation = b3Diagonal(2.0f, 4.0f, 0.5f);
doorHull.SetTransform(xf);
}
float32 x = -50.0f;
float32 y = 0.0f;
@ -39,7 +47,7 @@ public:
lastHinge = m_world.CreateBody(bd);
b3HullShape hull;
hull.m_hull = &m_doorHull;
hull.m_hull = &doorHull;
b3ShapeDef sdef;
sdef.shape = &hull;
@ -57,7 +65,7 @@ public:
b3Body* hinge = m_world.CreateBody(bd);
b3HullShape hull;
hull.m_hull = &m_doorHull;
hull.m_hull = &doorHull;
b3ShapeDef sdef;
sdef.shape = &hull;
@ -71,7 +79,7 @@ public:
b3RevoluteJointDef jd;
jd.Initialize(lastHinge, hinge, hingeAxis, hingeAnchor, 0.0f, 0.5f * B3_PI);
jd.collideLinked = true;
jd.collideLinked = false;
b3RevoluteJoint* rj = (b3RevoluteJoint*)m_world.CreateJoint(jd);
}

View File

@ -41,50 +41,60 @@ public:
{
b3BodyDef bd;
bd.position.Set(-2.0f, 5.05f, 0.0f);
bd.type = b3BodyType::e_staticBody;
bd.position.Set(0.0f, 7.0f, 0.0f);
hinge = m_world.CreateBody(bd);
b3CapsuleShape shape;
shape.m_centers[0].Set(0.0f, -3.5f, 0.0f);
shape.m_centers[1].Set(0.0f, 3.5f, 0.0f);
shape.m_centers[0].Set(0.0f, 0.0f, -4.0f);
shape.m_centers[1].Set(0.0f, 0.0f, 4.0f);
shape.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &shape;
sd.density = 1.0f;
hinge->CreateShape(sd);
m_hinge = hinge;
m_body = hinge;
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(1.0f, 5.05f, 0.0f);
bd.position.Set(2.0f, 7.0f, 0.0f);
door = m_world.CreateBody(bd);
m_doorBox.Set(1.0f, 0.5f, 4.0f);
b3HullShape hull;
hull.m_hull = &m_doorHull;
hull.m_hull = &m_doorBox;
b3ShapeDef sdef;
sdef.shape = &hull;
sdef.density = 2.0f;
sdef.density = 1.0f;
door->CreateShape(sdef);
}
{
b3Vec3 hingeAxis(0.0f, 1.0f, 0.0f);
b3Vec3 hingeAnchor(-2.0f, 5.0f, 0.0f);
b3Vec3 axis(0.0f, 0.0f, 1.0f);
b3Vec3 anchor(0.0f, 7.0f, 0.0f);
b3RevoluteJointDef jd;
jd.Initialize(hinge, door, hingeAxis, hingeAnchor, 0.0f, 0.5f * B3_PI);
jd.Initialize(hinge, door, axis, anchor, 0.0f, B3_PI);
jd.motorSpeed = B3_PI;
jd.maxMotorTorque = 10000.0f;
jd.maxMotorTorque = door->GetMass() * 10000.0f;
jd.enableMotor = true;
m_rj = (b3RevoluteJoint*)m_world.CreateJoint(jd);
}
// Invalidate the orientation
b3Vec3 axis(1.0f, 0.0f, 0.0f);
float32 angle = B3_PI;
door->SetTransform(door->GetPosition(), axis, angle);
}
void KeyDown(int button)
@ -101,17 +111,17 @@ public:
if (button == GLFW_KEY_D)
{
m_hinge->SetType(e_dynamicBody);
m_body->SetType(e_dynamicBody);
}
if (button == GLFW_KEY_S)
{
m_hinge->SetType(e_staticBody);
m_body->SetType(e_staticBody);
}
if (button == GLFW_KEY_K)
{
m_hinge->SetType(e_kinematicBody);
m_body->SetType(e_kinematicBody);
}
}
@ -120,7 +130,8 @@ public:
return new HingeMotor();
}
b3Body* m_hinge;
b3BoxHull m_doorBox;
b3Body* m_body;
b3RevoluteJoint* m_rj;
};

View File

@ -24,21 +24,24 @@ class HullAndHull : public Collide
public:
HullAndHull()
{
b3Transform xf;
xf.rotation = b3Diagonal(1.0f, 2.0f, 1.0f);
xf.position.SetZero();
b3Transform m;
m.rotation = b3Diagonal(1.0f, 2.0f, 1.0f);
m.position.Set(0.0f, 2.0f, 0.0f);
m_box1.SetTransform(m);
m_box.SetTransform(xf);
m.rotation = b3Diagonal(1.0f, 1.0f, 1.0f);
m.position.Set(0.0f, 0.0f, 0.0f);
m_box2.SetTransform(m);
b3Quat qA(0.0f, 1.0f, 0.0f, 0.025f * B3_PI);
m_xfA.SetIdentity();
m_xfA.position.Set(0.0186814368f, 1.96078217f, 0.0253920462f);
m_xfA.rotation = b3ConvertQuatToRot(qA);
m_sA.m_hull = &m_box;
m_xfA.position.SetZero();
m_xfA.rotation.SetIdentity();
m_sA.m_hull = &m_box1;
m_xfB.SetIdentity();
m_xfB.position.Set(0.f, 0.0f, 0.0f);
m_sB.m_hull = &m_box;
m_xfB.position.Set(0.0f, 0.0f, 0.0f);
m_xfB.rotation.SetIdentity();
m_sB.m_hull = &m_box2;
m_cache.count = 0;
m_shapeA = &m_sA;
@ -50,7 +53,8 @@ public:
return new HullAndHull();
}
b3BoxHull m_box;
b3BoxHull m_box1;
b3BoxHull m_box2;
b3HullShape m_sA;
b3HullShape m_sB;
};

View File

@ -0,0 +1,60 @@
/*
* 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 HULL_HULL2_H
#define HULL_HULL2_H
class HullAndHull2 : public Collide
{
public:
HullAndHull2()
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(1.0f, 2.0f, 1.0f);
m_box.SetTransform(xf);
m_sA.m_hull = &m_box;
m_sB.m_hull = &m_box;
m_xfA.position.Set(1.500000, 1.000000, 0.000000);
m_xfA.rotation.x.Set(0.707107, 0.000000, -0.707107);
m_xfA.rotation.y.Set(0.000000, 1.000000, 0.000000);
m_xfA.rotation.z.Set(0.707107, 0.000000, 0.707107);
m_xfB.position.Set(-1.300000, 0.000000, 0.000000);
m_xfB.rotation.x.Set(0.809017, 0.266849, -0.523721);
m_xfB.rotation.y.Set(0.000000, 0.891007, 0.453991);
m_xfB.rotation.z.Set(0.587785, -0.367286, 0.720840);
m_cache.count = 0;
m_shapeA = &m_sA;
m_shapeB = &m_sB;
}
static Test* Create()
{
return new HullAndHull2();
}
b3BoxHull m_box;
b3HullShape m_sA;
b3HullShape m_sB;
};
#endif

View File

@ -0,0 +1,102 @@
/*
* 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 INITIAL_OVERLAP_H
#define INITIAL_OVERLAP_H
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);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
body->CreateShape(sd);
}
b3Vec3 boxScale(1.0f, 0.5f, 2.0f);
static b3BoxHull boxHull;
b3Transform m;
m.rotation = b3Diagonal(boxScale.x, boxScale.y, boxScale.z);
m.position.SetZero();
boxHull.SetTransform(m);
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.0f, 1.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.1f;
sd.friction = 0.3f;
body->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.0f, 1.5f, 0.0f);
b3Quat q_y(b3Vec3(0.0f, 1.0f, 0.0f), 0.4f * B3_PI);
b3Quat q_z(b3Vec3(0.0f, 0.0f, 1.0f), 0.04f * B3_PI);
b3Quat q = q_z * q_y;
bd.orientation = q;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.1f;
sd.friction = 0.3f;
body->CreateShape(sd);
}
}
static Test* Create()
{
return new InitialOverlap();
}
};
#endif

View File

@ -46,8 +46,15 @@ public:
body->CreateShape(sd);
}
b3Vec3 boxScale;
boxScale.Set(1.0f, 0.5f, 3.0f);
b3Vec3 boxScale(1.0f, 0.5f, 3.0f);
static b3BoxHull boxHull;
b3Transform m;
m.rotation = b3Diagonal(boxScale.x, boxScale.y, boxScale.z);
m.position.SetZero();
boxHull.SetTransform(m);
float32 y = 2.0f;
@ -65,12 +72,12 @@ public:
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_plankHull;
hs.m_hull = &boxHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.1f;
sd.friction = 0.1f;
sd.friction = 0.3f;
body->CreateShape(sd);
}
@ -91,7 +98,7 @@ public:
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_plankHull;
hs.m_hull = &boxHull;
b3ShapeDef sd;
sd.shape = &hs;
@ -111,4 +118,4 @@ public:
}
};
#endif
#endif

View File

@ -24,8 +24,6 @@ class MultipleShapes : public Test
public:
MultipleShapes()
{
g_camera.m_center.Set(2.0f, -2.0f, 0.0f);
g_camera.m_zoom = 50.0f;
g_settings.drawCenterOfMasses = true;
{
@ -79,6 +77,7 @@ public:
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.0f, 0.0f, 0.0f);
bd.angularVelocity.Set(0.0f, 200.0f * B3_PI, 0.0f);
b3Body* body = m_world.CreateBody(bd);

View File

@ -34,35 +34,6 @@ public:
g_camera.m_zoom = 20.0f;
g_settings.drawCenterOfMasses = true;
{
b3StackArray<b3Vec3, 32> points;
ConstructCone(points);
u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_coneHull = ConvertHull(hull);
b3Free(p);
}
{
b3StackArray<b3Vec3, 32> points;
ConstructCylinder(points);
const u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_cylinderHull = ConvertHull(hull);
b3Free(p);
}
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
@ -79,10 +50,63 @@ public:
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(2.0f, 5.0f, 0.0f);
bdef.position.Set(-10.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.density = 0.1f;
sdef.friction = 0.3f;
sdef.shape = &sphere;
body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-5.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3CapsuleShape capsule;
capsule.m_centers[0].Set(0.0f, 0.0f, -1.0f);
capsule.m_centers[1].Set(0.0f, 0.0f, 1.0f);
capsule.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.density = 0.1f;
sdef.friction = 0.2f;
sdef.shape = &capsule;
body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(0.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
{
b3StackArray<b3Vec3, 32> points;
ConstructCone(points);
u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_coneHull = ConvertHull(hull);
b3Free(p);
}
b3HullShape hull;
hull.m_hull = &m_coneHull;
@ -97,16 +121,30 @@ public:
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-2.0f, 5.0f, 0.0f);
bdef.position.Set(4.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
{
b3StackArray<b3Vec3, 32> points;
ConstructCylinder(points);
const u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_cylinderHull = ConvertHull(hull);
b3Free(p);
}
b3HullShape hull;
hull.m_hull = &m_cylinderHull;
b3ShapeDef sdef;
sdef.density = 0.1f;
sdef.friction = 0.3f;
sdef.friction = 0.2f;
sdef.shape = &hull;
body->CreateShape(sdef);

View File

@ -266,28 +266,26 @@ inline b3Hull ConvertHull(const qhHull& hull)
inline void ConstructCylinder(b3Array<b3Vec3>& points, float32 radius = 1.0f, float32 height = 1.0f)
{
u32 kEdgeCount = 20;
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
b3Vec3 normal(0.0f, 1.0f, 0.0f);
b3Quat q(normal, kAngleInc);
points.Resize(4 * kEdgeCount);
u32 j = 0;
{
b3Vec3 center(0.0f, 0.0f, 0.0f);
b3Vec3 normal;
normal.Set(0.0f, 1.0f, 0.0f);
u32 kEdgeCount = 20;
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
float32 cosInc = cos(kAngleInc);
float32 sinInc = sin(kAngleInc);
float32 tInc = 1.0f - cosInc;
b3Vec3 n1 = b3Perp(normal);
b3Vec3 n1(1.0f, 0.0f, 0.0f);
b3Vec3 v1 = center + radius * n1;
for (u32 i = 0; i < kEdgeCount; ++i)
{
// Rodrigues' rotation formula
b3Vec3 n2 = cosInc * n1 + sinInc * b3Cross(normal, n1) + tInc * b3Dot(normal, n1) * normal;
b3Vec3 n2 = b3Mul(q, n1);
b3Vec3 v2 = center + radius * n2;
points.PushBack(v1);
points.PushBack(v2);
points[j++] = v1;
points[j++] = v2;
n1 = n2;
v1 = v2;
@ -296,26 +294,15 @@ inline void ConstructCylinder(b3Array<b3Vec3>& points, float32 radius = 1.0f, fl
{
b3Vec3 center(0.0f, height, 0.0f);
b3Vec3 normal;
normal.Set(0.0f, 1.0f, 0.0f);
u32 kEdgeCount = 20;
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
float32 cosInc = cos(kAngleInc);
float32 sinInc = sin(kAngleInc);
float32 tInc = 1.0f - cosInc;
b3Vec3 n1 = b3Perp(normal);
b3Vec3 n1(1.0f, 0.0f, 0.0f);
b3Vec3 v1 = center + radius * n1;
for (u32 i = 0; i < kEdgeCount; ++i)
{
// Rodrigues' rotation formula
b3Vec3 n2 = cosInc * n1 + sinInc * b3Cross(normal, n1) + tInc * b3Dot(normal, n1) * normal;
b3Vec3 n2 = b3Mul(q, n1);
b3Vec3 v2 = center + radius * n2;
points.PushBack(v1);
points.PushBack(v2);
points[j++] = v1;
points[j++] = v2;
n1 = n2;
v1 = v2;
@ -325,36 +312,34 @@ inline void ConstructCylinder(b3Array<b3Vec3>& points, float32 radius = 1.0f, fl
inline void ConstructCone(b3Array<b3Vec3>& points, float32 radius = 1.0f, float32 height = 1.0f)
{
u32 kEdgeCount = 20;
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
b3Vec3 normal(0.0f, 1.0f, 0.0f);
b3Quat q(normal, kAngleInc);
points.Resize(2 * kEdgeCount + 1);
u32 j = 0;
{
b3Vec3 center(0.0f, 0.0f, 0.0f);
b3Vec3 normal;
normal.Set(0.0f, 1.0f, 0.0f);
u32 kEdgeCount = 20;
float32 kAngleInc = 2.0f * B3_PI / float32(kEdgeCount);
float32 cosInc = cos(kAngleInc);
float32 sinInc = sin(kAngleInc);
float32 tInc = 1.0f - cosInc;
b3Vec3 n1 = b3Perp(normal);
b3Vec3 n1(1.0f, 0.0f, 0.0f);
b3Vec3 v1 = center + radius * n1;
for (u32 i = 0; i < kEdgeCount; ++i)
{
// Rodrigues' rotation formula
b3Vec3 n2 = cosInc * n1 + sinInc * b3Cross(normal, n1) + tInc * b3Dot(normal, n1) * normal;
b3Vec3 n2 = b3Mul(q, n1);
b3Vec3 v2 = center + radius * n2;
points.PushBack(v1);
points.PushBack(v2);
points[j++] = v1;
points[j++] = v2;
n1 = n2;
v1 = v2;
}
}
b3Vec3 c(0.0f, height, 0.0f);
points.PushBack(c);
points[j++] = c;
}
class QuickhullTest : public Test

View File

@ -35,7 +35,7 @@ public:
sd.shape = &hs;
ground->CreateShape(sd);
}
b3Body* head;
b3Body* hip;
b3Body* lArm;
@ -106,10 +106,10 @@ public:
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 0.25f;
lArm->CreateShape(sd);
}
// Link left arm to chest
{
b3ConeJointDef cd;
@ -139,7 +139,7 @@ public:
rArm->CreateShape(sd);
}
// Link right arm to chest
{
b3ConeJointDef cd;
@ -209,7 +209,7 @@ public:
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
}
void KeyDown(int button)
{
}
@ -220,4 +220,4 @@ public:
}
};
#endif
#endif

View File

@ -64,9 +64,17 @@ public:
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(2.0f, 4.0f, 0.5f);
boxHull.SetTransform(xf);
}
b3HullShape hs;
hs.m_hull = &m_tallHull;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;

View File

@ -42,9 +42,17 @@ public:
bd.position.Set(0.0f, 6.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
static b3BoxHull boxHull;
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(2.0f, 4.0f, 0.5f);
boxHull.SetTransform(xf);
}
b3HullShape hs;
hs.m_hull = &m_tallHull;
hs.m_hull = &boxHull;
b3ShapeDef sd;
sd.shape = &hs;

View File

@ -33,7 +33,7 @@ public:
{
{
b3BodyDef bd;
bd.type = b3BodyType::e_staticBody;
bd.type = e_staticBody;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;

View File

@ -64,7 +64,7 @@ public:
frame = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.density = 0.1f;
sdef.friction = 0.3f;
sdef.shape = &box;
@ -82,7 +82,7 @@ public:
b3ShapeDef sdef;
sdef.shape = &sphere;
sdef.density = 1.0f;
sdef.density = 0.1f;
sdef.friction = 1.0f;
wheelLF->CreateShape(sdef);
@ -108,7 +108,7 @@ public:
wheelRF = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.density = 0.1f;
sdef.friction = 1.0f;
sdef.shape = &sphere;
@ -136,7 +136,7 @@ public:
b3ShapeDef sdef;
sdef.shape = &sphere;
sdef.density = 1.0f;
sdef.density = 0.1f;
sdef.friction = 1.0f;
wheelLB->CreateShape(sdef);
@ -162,7 +162,7 @@ public:
wheelRB = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.density = 0.1f;
sdef.friction = 1.0f;
sdef.shape = &sphere;

View File

@ -27,6 +27,14 @@
#include <testbed/framework/debug_draw.h>
#include <testbed/framework/profiler.h>
inline float32 RandomFloat(float32 a, float32 b)
{
float32 x = float32(rand()) / float32(RAND_MAX);
float32 diff = b - a;
float32 r = x * diff;
return a + r;
}
struct Settings
{
Settings()
@ -45,8 +53,9 @@ struct Settings
drawContactPoints = true;
drawContactNormals = false;
drawContactTangents = false;
drawStats = true;
drawProfile = true;
drawContactAreas = false;
drawStats = false;
drawProfile = false;
drawGrid = true;
pause = false;
singleStep = false;
@ -56,6 +65,8 @@ struct Settings
int lastTestID;
int testID;
bool pause;
bool singleStep;
float32 hertz;
int velocityIterations;
@ -63,6 +74,7 @@ struct Settings
bool sleep;
bool warmStart;
bool convexCache;
bool drawCenterOfMasses;
bool drawBounds;
bool drawVerticesEdges;
@ -72,11 +84,10 @@ struct Settings
bool drawContactPoints;
bool drawContactNormals;
bool drawContactTangents;
bool drawContactAreas;
bool drawStats;
bool drawProfile;
bool drawGrid;
bool pause;
bool singleStep;
};
class Test;
@ -132,22 +143,15 @@ public:
virtual void KeyDown(int button) { }
virtual void KeyUp(int button) { }
virtual void Dump() { }
b3World m_world;
b3RayCastSingleOutput m_rayHit; // local space
b3BoxHull m_groundHull;
b3BoxHull m_boxHull;
b3BoxHull m_tallHull;
b3BoxHull m_doorHull;
b3BoxHull m_rampHull;
b3BoxHull m_plankHull;
b3BoxHull m_thinHull;
b3Hull* m_qhull;
b3Mesh m_meshes[e_maxMeshes];
b3RayCastSingleOutput m_rayHit; // ray hit local space
b3MouseJoint* m_mouseJoint;
b3BoxHull m_groundHull;
b3BoxHull m_boxHull;
b3Mesh m_meshes[e_maxMeshes];
};
#endif

View File

@ -49,6 +49,16 @@ public:
b3Shape* shape = body->CreateShape(sdef);
}
static b3BoxHull thinHull;
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(4.05f, 2.0f * B3_LINEAR_SLOP, 4.05f);
thinHull.SetTransform(xf);
}
b3Vec3 stackOrigin;
stackOrigin.Set(0.0f, 4.05f, 0.0f);
@ -73,7 +83,7 @@ public:
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_thinHull;
hs.m_hull = &thinHull;
b3ShapeDef sdef;
sdef.shape = &hs;

View File

@ -0,0 +1,337 @@
/*
* 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 TUMBLER_TEST_H
#define TUMBLER_TEST_H
#include <testbed/tests/quickhull_test.h>
extern DebugDraw* g_debugDraw;
extern Camera g_camera;
extern Settings g_settings;
class Tumbler : public Test
{
public:
enum
{
e_count = 100
};
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);
bd.type = e_dynamicBody;
b3Body* rotor = m_world.CreateBody(bd);
{
static b3BoxHull box;
b3Transform m;
m.position.Set(0.0f, -45.0f, 0.0f);
m.rotation = b3Diagonal(50.0f, 1.0f, 200.0f);
box.SetTransform(m);
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 5.0f;
sd.shape = &hs;
rotor->CreateShape(sd);
}
{
static b3BoxHull box;
b3Transform m;
m.position.Set(0.0f, 50.0f, 0.0f);
m.rotation = b3Diagonal(50.0f, 1.0f, 200.0f);
box.SetTransform(m);
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 5.0f;
sd.shape = &hs;
rotor->CreateShape(sd);
}
{
static b3BoxHull box;
b3Transform m;
m.position.Set(0.0f, 5.0f, -200.0f);
m.rotation = b3Diagonal(50.0f, 50.0f, 1.0f);
box.SetTransform(m);
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 5.0f;
sd.shape = &hs;
rotor->CreateShape(sd);
}
{
static b3BoxHull box;
b3Transform m;
m.position.Set(0.0f, 5.0f, 200.0f);
m.rotation = b3Diagonal(50.0f, 50.0f, 1.0f);
box.SetTransform(m);
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 5.0f;
sd.shape = &hs;
rotor->CreateShape(sd);
}
{
static b3BoxHull box;
b3Transform m;
m.position.Set(-50.0f, 5.0f, 0.0f);
m.rotation = b3Diagonal(1.0f, 50.0f, 200.0f);
box.SetTransform(m);
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 5.0f;
sd.shape = &hs;
rotor->CreateShape(sd);
}
{
static b3BoxHull box;
b3Transform m;
m.position.Set(50.0f, 5.0f, 0.0f);
m.rotation = b3Diagonal(1.0f, 50.0f, 200.0f);
box.SetTransform(m);
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 5.0f;
sd.shape = &hs;
rotor->CreateShape(sd);
}
{
b3RevoluteJointDef jd;
jd.Initialize(ground, rotor, b3Vec3(0.0f, 0.0f, -1.0f), ground->GetPosition(), -B3_PI, B3_PI);
jd.motorSpeed = 0.05f * B3_PI;
jd.maxMotorTorque = 1000.0f * rotor->GetMass();
jd.enableMotor = true;
b3Joint* joint = (b3RevoluteJoint*)m_world.CreateJoint(jd);
}
}
{
b3StackArray<b3Vec3, 32> points;
ConstructCone(points);
u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_coneHull = ConvertHull(hull);
b3Free(p);
}
{
b3StackArray<b3Vec3, 32> points;
ConstructCylinder(points);
const u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
qhHull hull;
hull.Construct(p, points);
m_cylinderHull = ConvertHull(hull);
b3Free(p);
}
m_count = 0;
}
~Tumbler()
{
{
b3Free(m_coneHull.vertices);
b3Free(m_coneHull.edges);
b3Free(m_coneHull.faces);
b3Free(m_coneHull.planes);
}
{
b3Free(m_cylinderHull.vertices);
b3Free(m_cylinderHull.edges);
b3Free(m_cylinderHull.faces);
b3Free(m_cylinderHull.planes);
}
}
void Step()
{
if(m_count < e_count)
{
++m_count;
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-10.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.3f;
sdef.shape = &sphere;
body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-5.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3CapsuleShape capsule;
capsule.m_centers[0].Set(0.0f, 0.0f, -1.0f);
capsule.m_centers[1].Set(0.0f, 0.0f, 1.0f);
capsule.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.density = 0.1f;
sdef.friction = 0.2f;
sdef.shape = &capsule;
body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(0.0f, 0.0f, 0.0f);
bdef.angularVelocity.Set(0.0f, 0.05f * B3_PI, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull box;
box.SetIdentity();
b3HullShape hs;
hs.m_hull = &box;
b3ShapeDef sd;
sd.density = 0.05f;
sd.shape = &hs;
body->CreateShape(sd);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(0.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hull;
hull.m_hull = &m_coneHull;
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.3f;
sdef.shape = &hull;
body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(4.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hull;
hull.m_hull = &m_cylinderHull;
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.2f;
sdef.shape = &hull;
body->CreateShape(sdef);
}
}
Test::Step();
}
static Test* Create()
{
return new Tumbler();
}
u32 m_count;
b3Hull m_coneHull;
b3Hull m_cylinderHull;
};
#endif

View File

@ -40,15 +40,24 @@ public:
ground->CreateShape(sdef);
}
static b3BoxHull rampHull;
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(25.0f, 0.5f, 25.0f);
rampHull.SetTransform(xf);
}
{
b3BodyDef bdef;
bdef.position.Set(-20.0f, 20.0f, 0.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), -0.1f * B3_PI);
b3Body* ramp = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_rampHull;
hs.m_hull = &rampHull;
b3ShapeDef sdef;
sdef.shape = &hs;
@ -64,7 +73,7 @@ public:
b3Body* ramp = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_rampHull;
hs.m_hull = &rampHull;
b3ShapeDef sdef;
sdef.shape = &hs;
@ -80,7 +89,7 @@ public:
b3Body* ramp = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_rampHull;
hs.m_hull = &rampHull;
b3ShapeDef sdef;
sdef.shape = &hs;
@ -96,7 +105,7 @@ public:
b3Body* ramp = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_rampHull;
hs.m_hull = &rampHull;
b3ShapeDef sdef;
sdef.shape = &hs;

View File

@ -33,17 +33,17 @@ public:
b3ShapeDef sd;
sd.shape = &shape;
ground->CreateShape(sd);
}
b3Body* hinge, *door;
b3Body* bA, *bB;
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(-2.0f, 5.05f, 0.0f);
hinge = m_world.CreateBody(bd);
bA = m_world.CreateBody(bd);
b3CapsuleShape shape;
shape.m_centers[0].Set(0.0f, -3.5f, 0.0f);
@ -54,34 +54,46 @@ public:
sd.shape = &shape;
sd.density = 1.0f;
hinge->CreateShape(sd);
bA->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.orientation.Set(b3Vec3(1.0f, 0.0f, 0.0f), 0.25f * B3_PI);
bd.position.Set(1.0f, 5.05f, 0.0f);
door = m_world.CreateBody(bd);
bB = m_world.CreateBody(bd);
static b3BoxHull doorHull;
{
b3Transform xf;
xf.position.SetZero();
xf.rotation = b3Diagonal(2.0f, 4.0f, 0.5f);
doorHull.SetTransform(xf);
}
b3HullShape hull;
hull.m_hull = &m_doorHull;
hull.m_hull = &doorHull;
b3ShapeDef sdef;
sdef.shape = &hull;
sdef.density = 2.0f;
sdef.density = 1.0f;
door->CreateShape(sdef);
}
{
b3Vec3 hingeAnchor(-2.0f, 5.0f, 0.0f);
b3WeldJointDef jd;
jd.Initialize(hinge, door, hingeAnchor);
bB->CreateShape(sdef);
b3WeldJoint* wj = (b3WeldJoint*)m_world.CreateJoint(jd);
{
b3Vec3 anchor(-2.0f, 5.0f, 0.0f);
b3WeldJointDef jd;
jd.Initialize(bA, bB, anchor);
b3WeldJoint* wj = (b3WeldJoint*)m_world.CreateJoint(jd);
}
// Invalidate the orientation
b3Vec3 axis(1.0f, 0.0f, 0.0f);
float32 angle = B3_PI;
bB->SetTransform(bB->GetPosition(), axis, angle);
}
}