first commit

This commit is contained in:
Irlan Robson
2016-12-18 18:39:47 -02:00
commit 8f29bc7e21
232 changed files with 103257 additions and 0 deletions

View File

@ -0,0 +1,245 @@
/*
* 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 BODY_TYPES_H
#define BODY_TYPES_H
class BodyTypes : public Test
{
public:
BodyTypes()
{
g_camera.m_zoom = 50.0f;
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(0.0f, 3.5f, 0.0f);
bd.linearVelocity.Set(0.0f, 0.0f, 0.0f);
bd.angularVelocity.Set(0.0f, B3_PI, 0.0f);
m_body = m_world.CreateBody(bd);
b3CapsuleShape cap;
cap.m_centers[0].Set(0.0f, 2.0f, 0.0f);
cap.m_centers[1].Set(0.0f, -2.0f, 0.0f);
cap.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = ∩
sd.density = 1.5f;
sd.friction = 0.7f;
m_body->CreateShape(sd);
}
}
void Step()
{
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);
}
void KeyDown(int button)
{
if (button == GLFW_KEY_S)
{
m_body->SetType(e_staticBody);
}
if (button == GLFW_KEY_K)
{
m_body->SetType(e_kinematicBody);
}
if (button == GLFW_KEY_D)
{
m_body->SetType(e_dynamicBody);
}
if (button == GLFW_KEY_SPACE)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(RandomFloat(-20.0f, 20.0f), RandomFloat(10.0f, 20.0f), RandomFloat(-20.0f, 20.0f));
b3Vec3 n = m_body->GetTransform().position - bd.position;
n.Normalize();
bd.linearVelocity = 100.0f * n;
b3Body* enemy = m_world.CreateBody(bd);
b3SphereShape shape;
shape.m_center.Set(0.0f, 0.0f, 0.0f);
shape.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &shape;
sd.density = 1.0f;
sd.friction = 1.0f;
enemy->CreateShape(sd);
}
if (m_body->GetType() == e_staticBody)
{
if (button == GLFW_KEY_LEFT)
{
b3Vec3 p = m_body->GetSweep().worldCenter;
b3Quat q = m_body->GetSweep().orientation;
p.x -= 1.0f;
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
}
if (button == GLFW_KEY_RIGHT)
{
b3Vec3 p = m_body->GetSweep().worldCenter;
b3Quat q = m_body->GetSweep().orientation;
p.x += 1.0f;
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
}
if (button == GLFW_KEY_UP)
{
b3Vec3 p = m_body->GetSweep().worldCenter;
b3Quat q = m_body->GetSweep().orientation;
p.z += 1.0f;
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
}
if (button == GLFW_KEY_DOWN)
{
b3Vec3 p = m_body->GetSweep().worldCenter;
b3Quat q = m_body->GetSweep().orientation;
p.z -= 1.0f;
m_body->SetTransform(p, b3Vec3(q.x, q.y, q.z), q.w);
}
}
if (m_body->GetType() == e_kinematicBody)
{
if (button == GLFW_KEY_LEFT)
{
b3Vec3 v = m_body->GetLinearVelocity();
b3Vec3 w = m_body->GetAngularVelocity();
v.x -= 5.0f;
w.y -= 0.25f * B3_PI;
m_body->SetLinearVelocity(v);
m_body->SetAngularVelocity(w);
}
if (button == GLFW_KEY_RIGHT)
{
b3Vec3 v = m_body->GetLinearVelocity();
b3Vec3 w = m_body->GetAngularVelocity();
v.x += 5.0f;
w.y += 0.25f * B3_PI;
m_body->SetLinearVelocity(v);
m_body->SetAngularVelocity(w);
}
if (button == GLFW_KEY_UP)
{
b3Vec3 v = m_body->GetLinearVelocity();
b3Vec3 w = m_body->GetAngularVelocity();
v.z -= 5.0f;
w.y -= 0.25f * B3_PI;
m_body->SetLinearVelocity(v);
m_body->SetAngularVelocity(w);
}
if (button == GLFW_KEY_DOWN)
{
b3Vec3 v = m_body->GetLinearVelocity();
b3Vec3 w = m_body->GetAngularVelocity();
v.z += 5.0f;
w.y += 0.25f * B3_PI;
m_body->SetLinearVelocity(v);
m_body->SetAngularVelocity(w);
}
}
if (m_body->GetType() == e_dynamicBody)
{
if (button == GLFW_KEY_LEFT)
{
m_body->ApplyForceToCenter(b3Vec3(-100.0f, 0.0f, 0.0f), true);
}
if (button == GLFW_KEY_RIGHT)
{
m_body->ApplyForceToCenter(b3Vec3(100.0f, 0.0f, 0.0f), true);
}
if (button == GLFW_KEY_UP)
{
m_body->ApplyForceToCenter(b3Vec3(0.0f, 0.0f, -100.0f), true);
}
if (button == GLFW_KEY_DOWN)
{
m_body->ApplyForceToCenter(b3Vec3(0.0f, 0.0f, 100.0f), true);
}
}
}
static Test* Create()
{
return new BodyTypes();
}
b3Body* m_body;
};
#endif

View File

@ -0,0 +1,97 @@
/*
* 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 BOX_STACK_H
#define BOX_STACK_H
class BoxStack : public Test
{
public:
enum
{
e_rowCount = 1,
e_columnCount = 5,
e_depthCount = 1
};
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;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.userData = nullptr;
sdef.friction = 1.0f;
b3Shape* shape = body->CreateShape(sdef);
}
b3Vec3 stackOrigin;
stackOrigin.Set(0.0f, 4.05f, 0.0f);
b3Vec3 boxScale;
boxScale.Set(2.05f, 2.05f, 2.05f);
for (u32 i = 0; i < e_rowCount; ++i)
{
for (u32 j = 0; j < e_columnCount; ++j)
{
for (u32 k = 0; k < e_depthCount; ++k)
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_dynamicBody;
bdef.position.x = float32(i) * boxScale.x;
bdef.position.y = 1.5f * float32(j) * boxScale.y;
bdef.position.z = float32(k) * boxScale.z;
bdef.position += stackOrigin;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 0.5f;
sdef.friction = 0.3f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
}
}
}
static Test* Create()
{
return new BoxStack();
}
};
#endif

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_H
#define CAPSULE_HULL_H
class CapsuleAndHull : public Collide
{
public:
CapsuleAndHull()
{
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[1].Set(0.0f, 1.0f, 0.0f);
m_sA.m_radius = 2.0f;
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 CapsuleAndHull();
}
b3CapsuleShape m_sA;
b3HullShape m_sB;
b3BoxHull m_box;
};
#endif

View File

@ -0,0 +1,57 @@
/*
* 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_COLLISION_H
#define CAPSULE_COLLISION_H
class CapsuleCollision : public Collide
{
public:
CapsuleCollision()
{
m_xfA.SetIdentity();
m_xfA.position.Set(0.0f, 0.0f, 0.0f);
//m_xfA.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.25f * B3_PI));
m_xfA.rotation.SetIdentity();
m_sA.m_centers[0].Set(0.0f, -5.0f, 0.0f);
m_sA.m_centers[1].Set(0.0f, 5.0f, 0.0f);
m_sA.m_radius = 1.0f;
m_xfB.SetIdentity();
m_xfB.position.Set(0.f, 0.0f, 0.0f);
//m_xfB.rotation = b3ConvertQuatToRot(b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.251f * B3_PI));
m_xfB.rotation.SetIdentity();
m_sB.m_centers[0].Set(0.0f, -1.0f, 0.0f);
m_sB.m_centers[1].Set(0.0f, 1.0f, 0.0f);
m_sB.m_radius = 1.0f;
m_cache.count = 0;
m_shapeA = &m_sA;
m_shapeB = &m_sB;
}
static Test* Create()
{
return new CapsuleCollision();
}
b3CapsuleShape m_sA;
b3CapsuleShape m_sB;
};
#endif

View File

@ -0,0 +1,128 @@
/*
* 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, b3Color(1.0f, 0.0f, 0.0f));
g_debugDraw->DrawPoint(pointB, b3Color(1.0f, 0.0f, 0.0f));
g_debugDraw->DrawSegment(pointA, pointB, b3Color(1.0f, 1.0f, 0.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

@ -0,0 +1,75 @@
/*
* 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_STACK_H
#define CAPSULE_STACK_H
class CapsuleStack : public Test
{
public:
CapsuleStack()
{
{
b3BodyDef bd;
bd.type = b3BodyType::e_staticBody;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.0f;
sd.friction = 1.0f;
sd.restitution = 0.0f;
b3Shape* shape = body->CreateShape(sd);
}
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
{
b3BodyDef bdef;
bdef.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
bdef.position.Set(0.0f, y, 0.0f);
bdef.linearVelocity.Set(0.0f, -1.0f, 0.0f);
bdef.type = b3BodyType::e_dynamicBody;
b3Body* body = m_world.CreateBody(bdef);
b3CapsuleShape capsule;
capsule.m_centers[0].Set(0.0f, -1.0f, 0.0f);
capsule.m_centers[1].Set(0.0f, 1.0f, 0.0f);
capsule.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.shape = &capsule;
sdef.density = 1.0f;
sdef.friction = 0.3f;
b3Shape* shape = body->CreateShape(sdef);
}
}
static Test* Create()
{
return new CapsuleStack();
}
};
#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 CHARACTER_H
#define CHARACTER_H
class Character : public Test
{
public:
Character()
{
{
b3BodyDef bdef;
b3Body* ground = m_world.CreateBody(bdef);
b3MeshShape ms;
ms.m_mesh = m_meshes + e_gridMesh;
b3ShapeDef sd;
sd.shape = &ms;
ground->CreateShape(sd);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_dynamicBody;
bdef.fixedRotationY = true;
bdef.position.Set(0.0f, 5.0f, 0.0f);
m_character = m_world.CreateBody(bdef);
b3CapsuleShape cap;
cap.m_centers[0].Set(0.0f, 1.0f, 0.0f);
cap.m_centers[1].Set(0.0f, -1.0f, 0.0f);
cap.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.shape = &cap;
sdef.density = 1.0f;
sdef.friction = 0.5f;
m_character->CreateShape(sdef);
}
}
void RayHit()
{
if (m_rayHit.m_shape)
{
if (m_rayHit.m_shape->GetBody() != m_character)
{
Test::RayHit();
}
}
}
void Step()
{
if (m_rayHit.m_shape)
{
if (m_rayHit.m_shape->GetBody() != m_character)
{
b3Vec3 point = m_rayHit.m_point;
b3Vec3 normal = m_rayHit.m_normal;
const b3Transform& xf = m_character->GetTransform();
b3Vec3 n = point - xf.position;
n.Normalize();
m_character->ApplyForceToCenter(100.0f * n, true);
g_debugDraw->DrawSolidCircle(normal, point + (0.05f * normal), 5.0f, b3Color(0.5f, 0.5f, 1.0f, 0.5f));
}
}
Test::Step();
}
static Test* Create()
{
return new Character();
}
b3Body* m_character;
};
#endif

View File

@ -0,0 +1,89 @@
/*
* 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 CLUSTER_H
#define CLUSTER_H
#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
b3StackArray<b3Observation, 256> tempObservations;
tempObservations.Resize(90);
for (u32 i = 0; i < tempObservations.Count(); ++i)
{
float32 x = RandomFloat(-1.0f, 1.0f);
float32 y = RandomFloat(-1.0f, 1.0f);
float32 z = RandomFloat(-1.0f, 1.0f);
tempObservations[i].point.Set(x, y, z);
tempObservations[i].point = b3Normalize(tempObservations[i].point);
tempObservations[i].cluster = 0xFFFFFFFF;
}
// Initialize clusters
b3StackArray<b3Cluster, 3> tempClusters;
b3InitializeClusters(tempClusters, tempObservations);
// Clusterize
b3Clusterize(m_clusters, m_observs, tempClusters, tempObservations);
for (u32 i = 0; i < m_clusters.Count(); ++i)
{
m_colors[i] = b3Color(RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f), RandomFloat(0.0f, 1.0f));
}
}
void Step()
{
for (u32 i = 0; i < m_clusters.Count(); ++i)
{
g_debugDraw->DrawSegment(b3Vec3(0, 0, 0), m_clusters[i].centroid, b3Color(1, 1, 1));
g_debugDraw->DrawPoint(m_clusters[i].centroid, m_colors[i]);
for (u32 j = 0; j < m_observs.Count(); ++j)
{
b3Observation obs = m_observs[j];
if (obs.cluster == i)
{
g_debugDraw->DrawPoint(obs.point, m_colors[i]);
}
}
}
}
static Test* Create()
{
return new Cluster();
}
b3StackArray<b3Observation, 256> m_observs;
b3StackArray<b3Cluster, 3> m_clusters;
b3Color m_colors[3];
};
#endif

View File

@ -0,0 +1,118 @@
/*
* 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 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()
{
b3ConvexCache cache;
cache.simplexCache.count = 0;
cache.featureCache.m_featurePair.state = b3SATCacheType::e_empty;
b3Manifold manifold;
manifold.GuessImpulses();
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)
{
b3WorldManifoldPoint* wmp = wm.points + i;
b3Vec3 pw = wmp->point;
b3Vec2 ps = g_camera.ConvertWorldToScreen(pw);
g_debugDraw->DrawPoint(pw, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(pw, pw + wmp->normal, b3Color(1.0f, 1.0f, 1.0f));
}
if (wm.pointCount > 0)
{
g_debugDraw->DrawPoint(wm.center, 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));
}
m_world.DrawShape(m_xfA, m_shapeA);
m_world.DrawShape(m_xfB, m_shapeB);
}
virtual 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;
}
}
b3Shape* m_shapeA;
b3Transform m_xfA;
b3Shape* m_shapeB;
b3Transform m_xfB;
b3SimplexCache m_cache;
};
#endif

View File

@ -0,0 +1,136 @@
/*
* 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 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();
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_hull = &m_boxHull;
m_proxyA.Set(&m_shapeA, 0);
m_proxyB.Set(&m_shapeB, 0);
m_cache.count = 0;
}
void Step()
{
b3GJKOutput out = b3GJK(m_xfA, m_proxyA, m_xfB, m_proxyB, false, &m_cache);
if (0 < m_cache.count && m_cache.count < 4)
{
b3GJKFeaturePair featurePair = b3GetFeaturePair(m_cache);
for (u32 i = 0; i < (u32)featurePair.typeA; ++i)
{
u32 index = featurePair.indexA[i];
g_debugDraw->DrawPoint(m_xfA * m_proxyA.GetVertex(index), b3Color(1.0f, 1.0f, 0.0f));
}
for (u32 i = 0; i < (u32)featurePair.typeB; ++i)
{
u32 index = featurePair.indexB[i];
g_debugDraw->DrawPoint(m_xfB * m_proxyB.GetVertex(index), b3Color(1.0f, 1.0f, 0.0f));
}
}
g_debugDraw->DrawPoint(out.pointA, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawPoint(out.pointB, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawSegment(out.pointA, out.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 Distance();
}
b3CapsuleShape m_shapeA;
b3Transform m_xfA;
b3ShapeGJKProxy m_proxyA;
b3HullShape m_shapeB;
b3Transform m_xfB;
b3ShapeGJKProxy m_proxyB;
b3SimplexCache m_cache;
};
#endif

View File

@ -0,0 +1,90 @@
/*
* 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 HINGE_CHAIN_H
#define HINGE_CHAIN_H
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();
float32 x = -50.0f;
float32 y = 0.0f;
b3Body* lastHinge;
{
b3BodyDef bd;
bd.position.Set(x, y, 0.0f);
lastHinge = m_world.CreateBody(bd);
b3HullShape hull;
hull.m_hull = &m_doorHull;
b3ShapeDef sdef;
sdef.shape = &hull;
lastHinge->CreateShape(sdef);
}
x += 4.25f;
for (u32 i = 0; i < 20; ++i)
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(x, y, 0.0f);
b3Body* hinge = m_world.CreateBody(bd);
b3HullShape hull;
hull.m_hull = &m_doorHull;
b3ShapeDef sdef;
sdef.shape = &hull;
sdef.density = 1.0f;
hinge->CreateShape(sdef);
{
b3Vec3 hingeAxis(0.0f, 1.0f, 0.0f);
b3Vec3 hingeAnchor(x - 2.25f, y, 0.0f);
b3RevoluteJointDef jd;
jd.Initialize(lastHinge, hinge, hingeAxis, hingeAnchor, 0.0f, 0.5f * B3_PI);
jd.collideLinked = true;
b3RevoluteJoint* rj = (b3RevoluteJoint*)m_world.CreateJoint(jd);
}
x += 4.25f;
lastHinge = hinge;
}
}
static Test* Create()
{
return new HingeChain();
}
};
#endif

View File

@ -0,0 +1,127 @@
/*
* 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 HINGE_MOTOR_H
#define HINGE_MOTOR_H
class HingeMotor : public Test
{
public:
HingeMotor()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape shape;
shape.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &shape;
ground->CreateShape(sd);
}
b3Body* hinge, *door;
{
b3BodyDef bd;
bd.position.Set(-2.0f, 5.05f, 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_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &shape;
sd.density = 1.0f;
hinge->CreateShape(sd);
m_hinge = hinge;
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(1.0f, 5.05f, 0.0f);
door = m_world.CreateBody(bd);
b3HullShape hull;
hull.m_hull = &m_doorHull;
b3ShapeDef sdef;
sdef.shape = &hull;
sdef.density = 2.0f;
door->CreateShape(sdef);
}
{
b3Vec3 hingeAxis(0.0f, 1.0f, 0.0f);
b3Vec3 hingeAnchor(-2.0f, 5.0f, 0.0f);
b3RevoluteJointDef jd;
jd.Initialize(hinge, door, hingeAxis, hingeAnchor, 0.0f, 0.5f * B3_PI);
jd.motorSpeed = B3_PI;
jd.maxMotorTorque = 10000.0f;
m_rj = (b3RevoluteJoint*)m_world.CreateJoint(jd);
}
}
void KeyDown(int button)
{
if (button == GLFW_KEY_M)
{
m_rj->SetEnableMotor(!m_rj->IsMotorEnabled());
}
if (button == GLFW_KEY_L)
{
m_rj->SetEnableLimit(!m_rj->IsLimitEnabled());
}
if (button == GLFW_KEY_D)
{
m_hinge->SetType(e_dynamicBody);
}
if (button == GLFW_KEY_S)
{
m_hinge->SetType(e_staticBody);
}
if (button == GLFW_KEY_K)
{
m_hinge->SetType(e_kinematicBody);
}
}
static Test* Create()
{
return new HingeMotor();
}
b3Body* m_hinge;
b3RevoluteJoint* m_rj;
};
#endif

View File

@ -0,0 +1,58 @@
/*
* 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_HULL_H
#define HULL_HULL_H
class HullAndHull : public Collide
{
public:
HullAndHull()
{
b3Transform xf;
xf.rotation = b3Diagonal(1.0f, 2.0f, 1.0f);
xf.position.SetZero();
m_box.SetTransform(xf);
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_xfB.SetIdentity();
m_xfB.position.Set(0.f, 0.0f, 0.0f);
m_sB.m_hull = &m_box;
m_cache.count = 0;
m_shapeA = &m_sA;
m_shapeB = &m_sB;
}
static Test* Create()
{
return new HullAndHull();
}
b3BoxHull m_box;
b3HullShape m_sA;
b3HullShape m_sB;
};
#endif

View File

@ -0,0 +1,114 @@
/*
* 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 JENGA_H
#define JENGA_H
class Jenga : public Test
{
public:
enum
{
e_layerCount = 20,
e_depthCount = 3,
};
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);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
body->CreateShape(sd);
}
b3Vec3 boxScale;
boxScale.Set(1.0f, 0.5f, 3.0f);
float32 y = 2.0f;
for (u32 i = 0; i < e_layerCount / 2; ++i)
{
for (u32 j = 0; j < e_depthCount; ++j)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.x = 2.0f * float32(j) * boxScale.x;
bd.position.y = y;
bd.position.z = 0.0f;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_plankHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.1f;
sd.friction = 0.1f;
body->CreateShape(sd);
}
y += 2.05f * boxScale.y;
for (u32 j = 0; j < e_depthCount; ++j)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.orientation.Set(b3Vec3(0.0f, 1.0f, 0.0f), 0.5f * B3_PI);
bd.position.x = 2.0f * boxScale.x;
bd.position.y = y;
bd.position.z = -2.0f * boxScale.x + 2.0f * float32(j) * boxScale.x;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_plankHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.1f;
sd.friction = 0.1f;
body->CreateShape(sd);
}
y += 2.05f * boxScale.y;
}
}
static Test* Create()
{
return new Jenga();
}
};
#endif

View File

@ -0,0 +1,176 @@
/*
* 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 MESH_TEST_H
#define MESH_TEST_H
class MeshContactTest : public Test
{
public:
MeshContactTest()
{
{
b3BodyDef bd;
m_ground = m_world.CreateBody(bd);
b3MeshShape ms;
ms.m_mesh = m_meshes + e_gridMesh;
b3ShapeDef sd;
sd.shape = &ms;
m_ground->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(0.0f, 5.0f, 0.0f);
m_body = m_world.CreateBody(bd);
{
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &sphere;
sd.density = 1.0f;
sd.friction = 0.5f;
m_body->CreateShape(sd);
}
}
}
void KeyDown(int key)
{
if (key == GLFW_KEY_S || key == GLFW_KEY_C || key == GLFW_KEY_H)
{
if (m_body)
{
m_world.DestroyBody(m_body);
}
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(0.0f, 5.0f, 0.0f);
m_body = m_world.CreateBody(bd);
if (key == GLFW_KEY_S)
{
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &sphere;
sd.density = 1.0f;
sd.friction = 0.5f;
m_body->CreateShape(sd);
}
if (key == GLFW_KEY_C)
{
b3CapsuleShape capsule;
capsule.m_centers[0].Set(0.0f, -1.0f, 0.0f);
capsule.m_centers[1].Set(0.0f, 1.0f, 0.0f);
capsule.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &capsule;
sd.density = 1.0f;
sd.friction = 0.5f;
m_body->CreateShape(sd);
}
if (key == GLFW_KEY_H)
{
b3HullShape hull;
hull.m_hull = &m_boxHull;
b3ShapeDef sd;
sd.shape = &hull;
sd.density = 1.0f;
sd.friction = 0.5f;
m_body->CreateShape(sd);
}
}
if (key == GLFW_KEY_G || key == GLFW_KEY_T)
{
if (m_ground)
{
m_world.DestroyBody(m_ground);
}
b3BodyDef bd;
m_ground = m_world.CreateBody(bd);
if (key == GLFW_KEY_G)
{
b3MeshShape ms;
ms.m_mesh = m_meshes + e_gridMesh;
b3ShapeDef sd;
sd.shape = &ms;
m_ground->CreateShape(sd);
}
if (key == GLFW_KEY_T)
{
b3MeshShape ms;
ms.m_mesh = m_meshes + e_terrainMesh;
b3ShapeDef sd;
sd.shape = &ms;
m_ground->CreateShape(sd);
}
}
}
void Step()
{
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);
}
static Test* Create()
{
return new MeshContactTest();
}
b3Body* m_ground;
b3Body* m_body;
};
#endif

View File

@ -0,0 +1,124 @@
/*
* 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 NEWTON_CRADLE_H
#define NEWTON_CRADLE_H
class NewtonCradle : public Test
{
public:
NewtonCradle()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
b3CapsuleShape edge;
edge.m_centers[0].Set(0.0f, -10.0f, 0.0f);
edge.m_centers[1].Set(0.0f, 10.0f, 0.0f);
edge.m_radius = 0.5f;
b3Body* frame1, *frame2;
{
b3BodyDef bd;
bd.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
bd.position.Set(0.0f, 10.0f, -5.0f);
frame1 = m_world.CreateBody(bd);
b3ShapeDef sd;
sd.shape = &edge;
frame1->CreateShape(sd);
}
{
b3BodyDef bd;
bd.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
bd.position.Set(0.0f, 10.0f, 5.0f);
frame2 = m_world.CreateBody(bd);
b3ShapeDef sd;
sd.shape = &edge;
frame2->CreateShape(sd);
}
b3Vec3 center;
center.Set(-5.0f, 4.0f, 0.0f);
b3SphereShape vertex;
vertex.m_center.SetZero();
vertex.m_radius = 1.0f;
u32 count = 6;
for (u32 i = 0; i < count; ++i)
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position = center;
if (i == count - 1)
{
bd.linearVelocity.x = 5.0f;
}
b3Body* ball = m_world.CreateBody(bd);
b3ShapeDef sd;
sd.shape = &vertex;
sd.density = 1.0f;
sd.friction = 0.8f;
ball->CreateShape(sd);
b3Vec3 c1;
c1.x = center.x;
c1.y = 10.0f;
c1.z = 0.0f;
b3SphereJointDef jd1;
jd1.bodyA = frame1;
jd1.collideLinked = true;
jd1.bodyB = ball;
jd1.localAnchorA = b3MulT(frame1->GetTransform(), c1);
jd1.localAnchorB = b3MulT(ball->GetTransform(), c1);
m_world.CreateJoint(jd1);
center.x += 2.0f * vertex.m_radius;
}
}
static Test* Create()
{
return new NewtonCradle();
}
};
#endif

View File

@ -0,0 +1,104 @@
/*
* 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 PYRAMID_H
#define PYRAMID_H
class Pyramid : public Test
{
public:
enum
{
e_count = 10,
};
Pyramid()
{
g_camera.m_zoom = 100.0f;
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
b3Vec3 boxSize;
boxSize.Set(2.0f, 2.0f, 2.0f);
// shift to ground center
b3Vec3 translation;
translation.x = -0.5f * float32(e_count) * boxSize.x;
translation.y = 1.5f * boxSize.y;
translation.z = -0.5f * float32(e_count) * boxSize.z;
u32 count = e_count;
for (u32 i = 0; i < e_count; ++i)
{
u32 j0 = 0, k0 = 0;
for (u32 j = j0; j < count; ++j)
{
for (u32 k = k0; k < count; ++k)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.x = 1.05f * float32(j) * boxSize.x;
bd.position.y = 0.0f;
bd.position.z = 1.05f * float32(k) * boxSize.z;
bd.position += translation;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.5f;
sd.friction = 0.5f;
body->CreateShape(sd);
}
}
// reduce dimension
++j0;
++k0;
--count;
// increment column
translation.y += 1.5f * boxSize.y;
// track offset
translation.x += 0.5f * boxSize.x;
translation.z += 0.5f * boxSize.z;
}
}
static Test* Create()
{
return new Pyramid();
}
};
#endif

View File

@ -0,0 +1,104 @@
/*
* 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 PYRAMIDS_H
#define PYRAMIDS_H
class Pyramids : public Test
{
public:
enum
{
e_count = 10,
e_depthCount = 10,
};
Pyramids()
{
g_camera.m_zoom = 100.0f;
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
b3Vec3 boxSize;
boxSize.Set(2.0f, 2.0f, 2.0f);
// shift to ground center
b3Vec3 translation;
translation.x = -0.5f * float32(e_count - 1) * 4.0f * boxSize.x;
translation.y = 1.5f * boxSize.y;
translation.z = -0.5f * float32(e_depthCount) * boxSize.z;
for (u32 i = 0; i < e_count; ++i)
{
// reset
translation.y = 1.5f * boxSize.y;
translation.z = -0.5f * float32(e_depthCount) * boxSize.z;
for (u32 j = 0; j < e_depthCount; ++j)
{
for (u32 k = j; k < e_depthCount; ++k)
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.x = 0.0f;
bd.position.y = 0.0f;
bd.position.z = 1.05f * float32(k) * boxSize.z;
bd.position += translation;
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.5f;
sd.friction = 0.5f;
body->CreateShape(sd);
}
// increment column
translation.y += 1.5f * boxSize.y;
// track offset
translation.z -= 0.5f * boxSize.z;
}
// increment row
translation.x += 4.0f * boxSize.x;
}
}
static Test* Create()
{
return new Pyramids();
}
};
#endif

View File

@ -0,0 +1,127 @@
/*
* 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 QUADRIC_H
#define QUADRIC_H
#include <testbed\tests\quickhull_test.h>
extern DebugDraw* g_debugDraw;
extern Camera g_camera;
extern Settings g_settings;
class Quadric : public Test
{
public:
Quadric()
{
g_camera.m_zoom = 20.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();
{
qhHull hull;
b3StackArray<b3Vec3, 32> points;
ConstructCone(points);
u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
hull.Construct(p, points);
m_coneHull = ConvertHull(hull);
b3Free(p);
}
{
qhHull hull;
b3StackArray<b3Vec3, 32> points;
ConstructCylinder(points);
u32 size = qhGetMemorySize(points.Count());
void* p = b3Alloc(size);
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.position.Set(2.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hull;
hull.m_hull = &m_coneHull;
b3ShapeDef sdef;
sdef.density = 0.2f;
sdef.friction = 0.3f;
sdef.shape = &hull;
body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-2.0f, 5.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hull;
hull.m_hull = &m_cylinderHull;
b3ShapeDef sdef;
sdef.density = 0.2f;
sdef.friction = 0.3f;
sdef.shape = &hull;
body->CreateShape(sdef);
}
}
~Quadric()
{
}
static Test* Create()
{
return new Quadric();
}
b3Hull m_coneHull;
b3Hull m_cylinderHull;
};
#endif

View File

@ -0,0 +1,380 @@
/*
* 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 QHULL_H
#define QHULL_H
#include <bounce\quickhull\qh_hull.h>
extern DebugDraw* g_debugDraw;
extern Camera g_camera;
extern Settings g_settings;
struct Pair
{
void* key;
u8 value;
};
struct Map
{
void Add(const Pair& pair)
{
m_pairs.PushBack(pair);
}
Pair* Find(void* key)
{
for (u32 i = 0; i < m_pairs.Count(); ++i)
{
Pair* pair = m_pairs.Get(i);
if (pair->key == key)
{
return pair;
}
}
return nullptr;
}
b3StackArray<Pair, 256> m_pairs;
};
#define NULL_FEATURE 0xFF
inline b3Hull ConvertHull(const qhHull& hull)
{
u8 V = 0;
u8 E = 0;
u8 F = 0;
qhFace* face = hull.m_faceList.head;
while (face)
{
qhHalfEdge* e = face->edge;
do
{
++E;
++V;
e = e->next;
} while (e != face->edge);
++F;
face = face->next;
}
u8 vertexCount = 0;
b3Vec3* vertices = (b3Vec3*)b3Alloc(V * sizeof(b3Vec3));
u8 edgeCount = 0;
b3HalfEdge* edges = (b3HalfEdge*)b3Alloc(E * sizeof(b3HalfEdge));
u8 faceCount = 0;
b3Face* faces = (b3Face*)b3Alloc(F * sizeof(b3Face));
b3Plane* planes = (b3Plane*)b3Alloc(F * sizeof(b3Plane));
Map vertexMap;
Map edgeMap;
face = hull.m_faceList.head;
while (face)
{
B3_ASSERT(faceCount < F);
u8 iface = faceCount;
b3Face* f = faces + faceCount;
b3Plane* plane = planes + faceCount;
++faceCount;
*plane = face->plane;
b3StackArray<u8, 32> faceEdges;
qhHalfEdge* edge = face->edge;
do
{
qhHalfEdge* twin = edge->twin;
qhVertex* v1 = edge->tail;
qhVertex* v2 = twin->tail;
Pair* mte = edgeMap.Find(edge);
Pair* mv1 = vertexMap.Find(v1);
Pair* mv2 = vertexMap.Find(v2);
u8 iv1;
if (mv1)
{
iv1 = mv1->value;
}
else
{
B3_ASSERT(vertexCount < V);
iv1 = vertexCount;
vertices[iv1] = v1->position;
vertexMap.Add({ v1, iv1 });
++vertexCount;
}
u8 iv2;
if (mv2)
{
iv2 = mv2->value;
}
else
{
B3_ASSERT(vertexCount < V);
iv2 = vertexCount;
vertices[iv2] = v2->position;
vertexMap.Add({ v2, iv2 });
++vertexCount;
}
if (mte)
{
u8 ie2 = mte->value;
b3HalfEdge* e2 = edges + ie2;
B3_ASSERT(e2->face == NULL_FEATURE);
e2->face = iface;
faceEdges.PushBack(ie2);
}
else
{
B3_ASSERT(edgeCount < E);
u8 ie1 = edgeCount;
b3HalfEdge* e1 = edges + edgeCount;
++edgeCount;
B3_ASSERT(edgeCount < E);
u8 ie2 = edgeCount;
b3HalfEdge* e2 = edges + edgeCount;
++edgeCount;
e1->face = iface;
e1->origin = iv1;
e1->twin = ie2;
e2->face = NULL_FEATURE;
e2->origin = iv2;
e2->twin = ie1;
faceEdges.PushBack(ie1);
edgeMap.Add({ edge, ie1 } );
edgeMap.Add({ twin, ie2 } );
}
edge = edge->next;
} while (edge != face->edge);
f->edge = faceEdges[0];
for (u32 i = 0; i < faceEdges.Count(); ++i)
{
u32 j = i < faceEdges.Count() - 1 ? i + 1 : 0;
edges[faceEdges[i]].next = faceEdges[j];
}
face = face->next;
}
b3Hull out;
out.vertexCount = vertexCount;
out.vertices = vertices;
out.edgeCount = edgeCount;
out.edges = edges;
out.faceCount = faceCount;
out.faces = faces;
out.planes = planes;
out.centroid.SetZero();
for (u32 i = 0; i < vertexCount; ++i)
{
out.centroid += vertices[i];
}
out.centroid /= float32(vertexCount);
out.Validate();
return out;
}
inline void ConstructCylinder(b3Array<b3Vec3>& points, float32 radius = 1.0f, float32 height = 1.0f)
{
{
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 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 v2 = center + radius * n2;
points.PushBack(v1);
points.PushBack(v2);
n1 = n2;
v1 = v2;
}
}
{
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 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 v2 = center + radius * n2;
points.PushBack(v1);
points.PushBack(v2);
n1 = n2;
v1 = v2;
}
}
}
inline void ConstructCone(b3Array<b3Vec3>& points, float32 radius = 1.0f, float32 height = 1.0f)
{
{
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 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 v2 = center + radius * n2;
points.PushBack(v1);
points.PushBack(v2);
n1 = n2;
v1 = v2;
}
}
b3Vec3 c(0.0f, height, 0.0f);
points.PushBack(c);
}
class QuickhullTest : public Test
{
public:
QuickhullTest()
{
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.15f * B3_PI);
g_camera.m_center.SetZero();
b3BoxHull box;
box.SetIdentity();
b3StackArray<b3Vec3, 256> tetra;
b3Vec3 v1(-1.0f, 0.0f, 0.0f);
b3Vec3 v2(1.0f, 0.0f, 0.0f);
b3Vec3 v3(0.0f, 0.0f, -1.0f);
b3Vec3 v4 = 0.5f * (v1 + v2 + v3);
v4.y += 2.0f;
tetra.PushBack(v1);
tetra.PushBack(v2);
tetra.PushBack(v3);
tetra.PushBack(v4);
// Minkowski sum of box and tetrahedron
b3StackArray<b3Vec3, 256> points;
for (u32 i = 0; i < box.vertexCount; ++i)
{
for (u32 j = 0; j < tetra.Count(); ++j)
{
b3Vec3 p = box.vertices[i] - tetra[j];
points.PushBack(p);
}
}
u32 size = qhGetMemorySize(points.Count());
m_memory = b3Alloc(size);
m_qhull.Construct(m_memory, points);
}
~QuickhullTest()
{
b3Free(m_memory);
}
void Step()
{
m_qhull.Draw(g_debugDraw);
}
void KeyDown(int button)
{
if (button == GLFW_KEY_LEFT)
{
//m_index = b3Max(m_index - 1, 0);
}
if (button == GLFW_KEY_RIGHT)
{
//m_index = b3Min(m_index + 1, i32(horizon.Count()) - 1);
}
if (button == GLFW_KEY_I)
{
}
}
static Test* Create()
{
return new QuickhullTest();
}
void* m_memory;
qhHull m_qhull;
};
#endif

View File

@ -0,0 +1,223 @@
/*
* 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 RAGDOLL_H
#define RAGDOLL_H
class Ragdoll : public Test
{
public:
Ragdoll()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
b3Body* head;
b3Body* hip;
b3Body* lArm;
b3Body* rArm;
b3Body* lLeg;
b3Body* rLeg;
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.0f, 10.0f, 0.0f);
hip = m_world.CreateBody(bd);
hip->ApplyForceToCenter(b3Vec3(0.0f, 0.0f, -5000.0f), true);
b3CapsuleShape cs;
cs.m_centers[0].Set(0.0f, 0.5f, 0.0f);
cs.m_centers[1].Set(0.0f, -0.5f, 0.0f);
cs.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 1.0f;
hip->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.0f, 12.25f, 0.0f);
bd.angularVelocity.Set(0.0f, 0.0f, 0.005f);
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 = 5.0f;
head->CreateShape(sd);
}
// Link head to chest
{
b3ConeJointDef cd;
cd.bodyA = hip;
cd.bodyB = head;
cd.collideLinked = false;
cd.enableLimit = true;
cd.Initialize(hip, head, b3Vec3(0.0f, 1.0f, 0.0f), b3Vec3(0.0f, 11.55f, 0.0f), 0.25f * B3_PI);
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(-2.5f, 11.0f, 0.0f);
bd.orientation.Set(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
lArm = m_world.CreateBody(bd);
b3CapsuleShape cs;
cs.m_centers[0].Set(0.0f, 1.0f, 0.0f);
cs.m_centers[1].Set(0.0f, -1.0f, 0.0f);
cs.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 0.25f;
lArm->CreateShape(sd);
}
// Link left arm to chest
{
b3ConeJointDef cd;
cd.bodyA = hip;
cd.bodyB = lArm;
cd.collideLinked = false;
cd.enableLimit = true;
cd.Initialize(hip, lArm, b3Vec3(-1.0f, 0.0f, 0.0f), b3Vec3(-1.0f, 11.0f, 0.0f), B3_PI);
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(2.5f, 11.0f, 0.0f);
bd.orientation.Set(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
rArm = m_world.CreateBody(bd);
b3CapsuleShape cs;
cs.m_centers[0].Set(0.0f, 1.0f, 0.0f);
cs.m_centers[1].Set(0.0f, -1.0f, 0.0f);
cs.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 0.25f;
rArm->CreateShape(sd);
}
// Link right arm to chest
{
b3ConeJointDef cd;
cd.bodyA = hip;
cd.bodyB = rArm;
cd.collideLinked = false;
cd.enableLimit = true;
cd.Initialize(hip, rArm, b3Vec3(1.0f, 0.0f, 0.0f), b3Vec3(1.0f, 11.0f, 0.0f), B3_PI);
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(-0.5f, 6.0f, 0.0f);
lLeg = m_world.CreateBody(bd);
b3CapsuleShape cs;
cs.m_centers[0].Set(0.0f, 2.0f, 0.0f);
cs.m_centers[1].Set(0.0f, -2.0f, 0.0f);
cs.m_radius = 0.45f;
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 0.25f;
lLeg->CreateShape(sd);
}
// Link left leg to chest
{
b3ConeJointDef cd;
cd.bodyA = hip;
cd.bodyB = lLeg;
cd.collideLinked = false;
cd.enableLimit = true;
cd.Initialize(hip, lLeg, b3Vec3(0.0f, -1.0f, 0.0f), b3Vec3(-0.5f, 8.5f, 0.0f), 0.25f * B3_PI);
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
{
b3BodyDef bd;
bd.type = e_dynamicBody;
bd.position.Set(0.5f, 6.0f, 0.0f);
rLeg = m_world.CreateBody(bd);
b3CapsuleShape cs;
cs.m_centers[0].Set(0.0f, 2.0f, 0.0f);
cs.m_centers[1].Set(0.0f, -2.0f, 0.0f);
cs.m_radius = 0.45f;
b3ShapeDef sd;
sd.shape = &cs;
sd.density = 0.25f;
rLeg->CreateShape(sd);
}
// Link right leg to chest
{
b3ConeJointDef cd;
cd.bodyA = hip;
cd.bodyB = rLeg;
cd.collideLinked = false;
cd.enableLimit = true;
cd.Initialize(hip, rLeg, b3Vec3(0.0f, -1.0f, 0.0f), b3Vec3(0.5f, 8.5f, 0.0f), 0.25f * B3_PI);
b3ConeJoint* cj = (b3ConeJoint*)m_world.CreateJoint(cd);
}
}
void KeyDown(int button)
{
}
static Test* Create()
{
return new Ragdoll();
}
};
#endif

View File

@ -0,0 +1,271 @@
/*
* 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 RAY_CAST_H
#define RAY_CAST_H
extern Settings g_settings;
class RayCast : public Test
{
public:
RayCast()
{
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(0.0f, 2.0f, 10.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(-10.0f, 6.0f, -10.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_tallHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(10.0f, 2.0f, 0.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.20f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 0.0f;
sdef.friction = 0.0f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(-10.0f, 2.0f, 14.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), 0.05f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 0.0f;
sdef.friction = 0.0f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(-14.0f, 2.0f, 5.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.05f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 0.0f;
sdef.friction = 0.0f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(20.0f, 2.0f, 5.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.05f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 0.0f;
sdef.friction = 0.0f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(12.0f, 2.0f, 5.0f);
bdef.orientation = b3Quat(b3Vec3(0.0f, 1.0f, 0.0f), -0.35f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
b3SphereShape hs;
hs.m_radius = 2.5f;
b3ShapeDef sdef;
sdef.density = 0.0f;
sdef.friction = 0.0f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_staticBody;
bdef.position.Set(0.0f, 1.0f, -12.0f);
b3Body* body = m_world.CreateBody(bdef);
b3CapsuleShape hs;
hs.m_centers[0].Set(0.0f, 1.0f, 0.0f);
hs.m_centers[1].Set(0.0f, -1.0f, 0.0f);
hs.m_radius = 3.0f;
b3ShapeDef sdef;
sdef.density = 0.0f;
sdef.friction = 0.0f;
sdef.shape = &hs;
sdef.userData = nullptr;
b3Shape* shape = body->CreateShape(sdef);
}
m_p1.Set(0.0f, 2.0f, 0.0f);
m_p2.Set(50.0f, 2.0f, 0.0f);
m_p12.Set(0.0f, 2.0f, 0.0f);
m_p22.Set(-50.0f, 2.0f, 0.0f);
}
void CastRay(const b3Vec3 p1, const b3Vec3 p2) const
{
// Perform the ray cast
RayCastListener listener;
m_world.CastRay(&listener, p1, p2);
int hitId = listener.FindClosestHit();
if (hitId >= 0)
{
// Hit
// Replace current hit
RayCastHit rayHit = listener.m_hits[hitId];
b3Shape* shape = rayHit.m_shape;
b3Body* bodyA = m_groundBody;
b3Body* bodyB = shape->GetBody();
// Ray hit point in world space
b3Vec3 worldPointA = rayHit.m_point;
// xf from world space to the local space of the shape
b3Transform xf = shape->GetTransform();
// lp = xf^-1 * wp
b3Vec3 localPointA = b3MulT(xf, worldPointA);
extern DebugDraw* g_debugDraw;
g_debugDraw->DrawSegment(p1, worldPointA, b3Color(0.0f, 1.0f, 0.0f));
g_debugDraw->DrawPoint(worldPointA, b3Color(1.0f, 0.0f, 0.0f));
g_debugDraw->DrawSegment(worldPointA, worldPointA + rayHit.m_normal, b3Color(1.0f, 1.0f, 1.0f));
}
else
{
g_debugDraw->DrawSegment(p1, p2, b3Color(0.0f, 1.0f, 0.0f));
}
}
void Step()
{
float32 dt = g_settings.hertz > 0.0f ? 1.0f / g_settings.hertz : 0.0f;
b3Quat q(b3Vec3(0.0f, 1.0f, 0.0f), dt * 0.05f * B3_PI);
m_p1 = b3Mul(q, m_p1);
m_p2 = b3Mul(q, m_p2);
m_p12 = b3Mul(q, m_p12);
m_p22 = b3Mul(q, m_p22);
CastRay(m_p1, m_p2);
CastRay(m_p12, m_p22);
Test::Step();
}
static Test* Create()
{
return new RayCast();
}
b3Vec3 m_p1, m_p2;
b3Vec3 m_p12, m_p22;
};
#endif

View File

@ -0,0 +1,164 @@
/*
* 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 SENSOR_TEST_H
#define SENSOR_TEST_H
class SensorTest : public Test
{
public:
SensorTest()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
{
b3BodyDef bd;
bd.position.Set(0.0f, 6.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_tallHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.isSensor = true;
m_sensor = body->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(0.0f, 4.0f, 10.0f);
bd.linearVelocity.Set(0.0f, 0.0f, -5.0f);
m_character = m_world.CreateBody(bd);
b3CapsuleShape cap;
cap.m_centers[0].Set(0.0f, 2.0f, 0.0f);
cap.m_centers[1].Set(0.0f, -2.0f, 0.0f);
cap.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &cap;
sd.density = 1.5f;
sd.friction = 0.7f;
m_character->CreateShape(sd);
}
m_attack = false;
}
void BeginContact(b3Contact* c)
{
b3Shape* sA = c->GetShapeA();
b3Body* bA = sA->GetBody();
b3Shape* sB = c->GetShapeB();
b3Body* bB = sB->GetBody();
if (sA == m_sensor)
{
if (bB == m_character)
{
m_attack = true;
}
}
if (sB == m_sensor)
{
if (bA == m_character)
{
m_attack = true;
}
}
}
void EndContact(b3Contact* c)
{
b3Shape* sA = c->GetShapeA();
b3Body* bA = sA->GetBody();
b3Shape* sB = c->GetShapeB();
b3Body* bB = sB->GetBody();
if (sA == m_sensor)
{
}
if (sB == m_sensor)
{
}
}
void Step()
{
if (m_attack)
{
b3Body* sensorBody = m_sensor->GetBody();
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(RandomFloat(-20.0f, 20.0f), RandomFloat(10.0f, 20.0f), RandomFloat(-20.0f, 20.0f));
b3Vec3 n = m_character->GetTransform().position - bd.position;
n.Normalize();
bd.linearVelocity = 60.0f * n;
b3Body* enemy = m_world.CreateBody(bd);
b3SphereShape shape;
shape.m_center.Set(0.0f, 0.0f, 0.0f);
shape.m_radius = 0.5f;
b3ShapeDef sd;
sd.shape = &shape;
sd.density = 1.0f;
sd.friction = 1.0f;
enemy->CreateShape(sd);
m_attack = false;
}
Test::Step();
}
static Test* Create()
{
return new SensorTest();
}
b3Body* m_character;
b3Shape* m_sensor;
bool m_attack;
};
#endif

View File

@ -0,0 +1,108 @@
/*
* 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 SHAPE_STACK_H
#define SHAPE_STACK_H
class ShapeStack : public Test
{
public:
ShapeStack()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3MeshShape ms;
ms.m_mesh = m_meshes + e_gridMesh;
b3ShapeDef sd;
sd.shape = &ms;
ground->CreateShape(sd);
}
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(-10.0f, y, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.shape = &sphere;
sdef.density = 1.0f;
sdef.friction = 0.3f;
body->CreateShape(sdef);
}
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(0.0f, y, 0.0f);
bd.orientation = b3Quat(b3Vec3(0.0f, 0.0f, 1.0f), 0.5f * B3_PI);
b3Body* body = m_world.CreateBody(bd);
b3CapsuleShape capsule;
capsule.m_centers[0].Set(0.0f, -1.0f, 0.0f);
capsule.m_centers[1].Set(0.0f, 1.0f, 0.0f);
capsule.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &capsule;
sd.density = 1.0f;
sd.friction = 0.3f;
body->CreateShape(sd);
}
for (float32 y = 2.5f; y < 20.0f; y += 2.5f)
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(10.0f, y, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3HullShape hull;
hull.m_hull = &m_boxHull;
b3ShapeDef sd;
sd.shape = &hull;
sd.density = 1.0f;
sd.friction = 0.3f;
body->CreateShape(sd);
}
}
static Test* Create()
{
return new ShapeStack();
}
};
#endif

View File

@ -0,0 +1,93 @@
/*
* 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 SPHERE_STACK_H
#define SPHERE_STACK_H
class SphereStack : public Test
{
public:
enum
{
e_rowCount = 1,
e_columnCount = 5,
e_depthCount = 1
};
SphereStack()
{
{
b3BodyDef bd;
bd.type = b3BodyType::e_staticBody;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
sd.density = 0.0f;
sd.friction = 1.0f;
sd.restitution = 0.0f;
b3Shape* groundShape = ground->CreateShape(sd);
}
b3Vec3 stackOrigin;
stackOrigin.Set(0.0f, 5.0f, 0.0f);
float32 radius = 1.0f;
float32 diameter = 2.0f * radius;
for (u32 i = 0; i < e_rowCount; ++i)
{
for (u32 j = 0; j < e_columnCount; ++j)
{
for (u32 k = 0; k < e_depthCount; ++k)
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_dynamicBody;
bdef.position.x = float32(i) * diameter;
bdef.position.y = float32(j) * diameter;
bdef.position.z = float32(k) * diameter;
bdef.position += stackOrigin;
bdef.linearVelocity.Set(0.0f, -50.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = radius;
b3ShapeDef sdef;
sdef.shape = &sphere;
sdef.density = 1.0f;
sdef.friction = 0.3f;
b3Shape* shape = body->CreateShape(sdef);
}
}
}
}
static Test* Create()
{
return new SphereStack();
}
};
#endif

View File

@ -0,0 +1,191 @@
/*
* 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 SPRING_H
#define SPRING_H
class Spring : public Test
{
public:
Spring()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
// Car frame shape
{
b3Transform xf;
xf.SetIdentity();
xf.rotation = b3Diagonal(2.0f, 0.5f, 5.0f);
m_frameHull.SetTransform(xf);
}
b3HullShape box;
box.m_hull = &m_frameHull;
// Wheel shape
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
// Car frame
b3Body* frame;
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(0.0f, 10.0f, 0.0f);
frame = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.3f;
sdef.shape = &box;
frame->CreateShape(sdef);
}
b3Body* wheelLF;
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-1.0f, 7.0f, -4.5f);
bdef.fixedRotationY = true;
wheelLF = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.shape = &sphere;
sdef.density = 1.0f;
sdef.friction = 1.0f;
wheelLF->CreateShape(sdef);
}
{
b3SpringJointDef def;
def.Initialize(frame, wheelLF, b3Vec3(-1.0f, 9.0f, -4.5), b3Vec3(-1.0f, 9.0f, -4.5f));
def.collideLinked = true;
def.dampingRatio = 0.5f;
def.frequencyHz = 4.0f;
m_world.CreateJoint(def);
}
b3Body* wheelRF;
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(1.0f, 7.0, -4.5f);
bdef.fixedRotationY = true;
wheelRF = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 1.0f;
sdef.shape = &sphere;
wheelRF->CreateShape(sdef);
}
{
b3SpringJointDef def;
def.Initialize(frame, wheelRF, b3Vec3(1.0f, 9.0, -4.5), b3Vec3(1.0f, 9.0, -4.5f));
def.collideLinked = true;
def.dampingRatio = 0.5f;
def.frequencyHz = 4.0f;
m_world.CreateJoint(def);
}
b3Body* wheelLB;
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(-1.0f, 7.0f, 4.5f);
bdef.fixedRotationY = true;
wheelLB = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.shape = &sphere;
sdef.density = 1.0f;
sdef.friction = 1.0f;
wheelLB->CreateShape(sdef);
}
{
b3SpringJointDef def;
def.Initialize(frame, wheelLB, b3Vec3(-1.0f, 9.0f, 4.5f), b3Vec3(-1.0f, 9.0f, 4.5f));
def.collideLinked = true;
def.dampingRatio = 0.8f;
def.frequencyHz = 4.0f;
m_world.CreateJoint(def);
}
b3Body* wheelRB;
{
b3BodyDef bdef;
bdef.type = e_dynamicBody;
bdef.position.Set(1.0f, 7.0f, 4.5f);
bdef.fixedRotationY = true;
wheelRB = m_world.CreateBody(bdef);
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 1.0f;
sdef.shape = &sphere;
wheelRB->CreateShape(sdef);
}
{
b3SpringJointDef def;
def.Initialize(frame, wheelRB, b3Vec3(1.0f, 9.0f, 4.5f), b3Vec3(1.0f, 9.0f, 4.5f));
def.collideLinked = true;
def.frequencyHz = 4.0f;
def.dampingRatio = 0.8f;
m_world.CreateJoint(def);
}
}
static Test* Create()
{
return new Spring();
}
b3BoxHull m_frameHull;
};
#endif

View File

@ -0,0 +1,218 @@
/*
* 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 TEST_H
#define TEST_H
#include <glfw\glfw3.h>
#include <imgui\imgui.h>
#include "..\framework\debug_draw.h"
#include <bounce\bounce.h>
struct Settings
{
Settings()
{
hertz = 60.0f;
velocityIterations = 8;
positionIterations = 2;
sleep = false;
warmStart = true;
convexCache = true;
drawCenterOfMasses = false;
drawShapes = true;
drawBounds = false;
drawJoints = true;
drawContactPoints = true;
drawContactNormals = false;
drawContactTangents = false;
drawStats = true;
drawProfile = true;
drawGrid = false;;
pause = false;
singleStep = false;
lastTestID = -1;
testID = 0;
}
int lastTestID;
int testID;
float32 hertz;
int velocityIterations;
int positionIterations;
bool sleep;
bool warmStart;
bool convexCache;
bool drawCenterOfMasses;
bool drawBounds;
bool drawShapes;
bool drawSolidShapes;
bool drawJoints;
bool drawContactPoints;
bool drawContactNormals;
bool drawContactTangents;
bool drawStats;
bool drawProfile;
bool drawGrid;
bool pause;
bool singleStep;
};
class Test;
struct TestEntry
{
typedef Test* (*TestCreate)();
const char* name;
TestCreate create;
};
enum TestType
{
// Collision
e_QHull,
e_Cluster,
e_Distance,
e_CapsuleDistance,
e_CapsuleAndCapsule,
e_CapsuleAndHull,
e_HullAndHull,
// Dynamics
// Joints
e_NewtonCradle,
e_Vehicle,
e_Door,
e_HingeChain,
e_Ragdoll,
// Contacts
e_Quadric,
e_MeshContact,
// World
e_SphereStack,
e_CapsuleStack,
e_BoxStack,
e_ShapeStack,
e_Jenga,
e_Thin,
e_Pyramid,
e_Pyramids,
// World Queries
e_RayCast,
e_SensorTest,
e_Character,
e_BodyTypes,
e_VaryingFriction,
e_VaryingRestitution,
e_testCount
};
extern TestEntry g_tests[e_testCount];
struct RayCastHit
{
b3Shape* m_shape;
b3Vec3 m_point;
b3Vec3 m_normal;
float32 m_fraction;
};
class RayCastListener : public b3RayCastListener
{
public:
float32 ReportShape(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction)
{
RayCastHit hit;
hit.m_shape = shape;
hit.m_point = point;
hit.m_normal = normal;
hit.m_fraction = fraction;
m_hits.PushBack(hit);
// Continue.
return 1.0f;
}
int FindClosestHit() const
{
float32 minFraction = FLT_MAX;
int minIndex = -1;
for (u32 i = 0; i < m_hits.Count(); ++i)
{
const RayCastHit* hit = m_hits.Get(i);
if (hit->m_fraction < minFraction)
{
minFraction = hit->m_fraction;
minIndex = i;
}
}
return minIndex;
}
b3StackArray<RayCastHit, 256> m_hits;
};
class Test : public b3ContactListener
{
public:
enum Meshes
{
e_gridMesh,
e_terrainMesh,
e_maxMeshes,
};
Test();
virtual ~Test();
virtual void BeginContact(b3Contact* contact);
virtual void EndContact(b3Contact* contact);
virtual void PreSolve(b3Contact* contact);
virtual void Step();
virtual void RayHit();
virtual void MouseMove(const Ray3& pw);
virtual void MouseLeftDown(const Ray3& pw);
virtual void MouseLeftUp(const Ray3& pw);
virtual void KeyDown(int button) { }
virtual void KeyUp(int button) { }
b3World m_world;
b3Profile m_profile;
b3Profile m_maxProfile;
RayCastHit m_rayHit;
b3Body* m_groundBody;
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];
b3MouseJoint* m_mouseJoint;
};
#endif

View File

@ -0,0 +1,95 @@
/*
* 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 THIN_H
#define THIN_H
class Thin : public Test
{
public:
enum
{
e_rowCount = 1,
e_columnCount = 10,
e_depthCount = 1
};
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;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.friction = 1.0f;
b3Shape* shape = body->CreateShape(sdef);
}
b3Vec3 stackOrigin;
stackOrigin.Set(0.0f, 4.05f, 0.0f);
b3Vec3 boxScale;
boxScale.Set(4.05f, 2.05f, 4.05f);
for (u32 i = 0; i < e_rowCount; ++i)
{
for (u32 j = 0; j < e_columnCount; ++j)
{
for (u32 k = 0; k < e_depthCount; ++k)
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_dynamicBody;
bdef.position.x = float32(i) * boxScale.x;
bdef.position.y = 1.5f * float32(j) * boxScale.y;
bdef.position.z = float32(k) * boxScale.z;
bdef.position += stackOrigin;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_thinHull;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.density = 0.5f;
sdef.friction = 0.2f;
body->CreateShape(sdef);
}
}
}
}
static Test* Create()
{
return new Thin();
}
};
#endif

View File

@ -0,0 +1,165 @@
/*
* 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 VARYING_FRICTION_H
#define VARYING_FRICTION_H
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);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sdef;
sdef.shape = &hs;
ground->CreateShape(sdef);
}
{
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;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.friction = 0.4f;
ramp->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(20.0f, 30.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;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.friction = 0.3f;
ramp->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(-20.0f, 40.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;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.friction = 0.2f;
ramp->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(20.0f, 50.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;
b3ShapeDef sdef;
sdef.shape = &hs;
sdef.friction = 0.1f;
ramp->CreateShape(sdef);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(40.0f, 70.0f, -10.0f);
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.2f;
sdef.shape = &hs;
body->CreateShape(sdef);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(40.0f, 70.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.5f;
sdef.shape = &hs;
body->CreateShape(sdef);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(40.0f, 70.0f, 10.0f);
b3Body* body = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_boxHull;
b3ShapeDef sdef;
sdef.density = 1.0f;
sdef.friction = 0.8f;
sdef.shape = &hs;
body->CreateShape(sdef);
}
}
static Test* Create()
{
return new VaryingFriction();
}
};
#endif

View File

@ -0,0 +1,137 @@
/*
* 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 VARYING_RESTITUTION_H
#define VARYING_RESTITUTION_H
class VaryingRestitution : public Test
{
public:
VaryingRestitution()
{
{
b3BodyDef bd;
b3Body* ground = m_world.CreateBody(bd);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sd;
sd.shape = &hs;
ground->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(-10.0f, 10.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3SphereShape ball;
ball.m_center.SetZero();
ball.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &ball;
sd.density = 1.0f;
sd.restitution = 0.2f;
body->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(-5.0f, 10.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3SphereShape ball;
ball.m_center.SetZero();
ball.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &ball;
sd.density = 1.0f;
sd.restitution = 0.4f;
body->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(0.0f, 10.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3SphereShape ball;
ball.m_center.SetZero();
ball.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &ball;
sd.density = 1.0f;
sd.restitution = 0.6f;
body->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(5.0f, 10.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3SphereShape ball;
ball.m_center.SetZero();
ball.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &ball;
sd.density = 1.0f;
sd.restitution = 0.8f;
body->CreateShape(sd);
}
{
b3BodyDef bd;
bd.type = b3BodyType::e_dynamicBody;
bd.position.Set(10.0f, 10.0f, 0.0f);
b3Body* body = m_world.CreateBody(bd);
b3SphereShape ball;
ball.m_center.SetZero();
ball.m_radius = 1.0f;
b3ShapeDef sd;
sd.shape = &ball;
sd.density = 1.0f;
sd.restitution = 1.0f;
body->CreateShape(sd);
}
}
static Test* Create()
{
return new VaryingRestitution();
}
};
#endif