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

@ -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);
}
}