add event profiler, json profile dump, cleanup

This commit is contained in:
Irlan
2017-02-24 20:11:49 -03:00
parent e1038cfb31
commit 689425d9ef
64 changed files with 16135 additions and 531 deletions

View File

@@ -22,7 +22,7 @@
// Implementation of the GJK (Gilbert-Johnson-Keerthi) algorithm
// using Voronoi regions and Barycentric coordinates.
u32 b3_gjkCalls, b3_gjkIters, b3_gjkMaxIters;
u32 b3_gjkCalls = 0, b3_gjkIters = 0, b3_gjkMaxIters = 0;
b3Vec3 b3Simplex::GetSearchDirection(const b3Vec3& Q) const
{

View File

@@ -22,8 +22,8 @@
#include <stdarg.h>
#include <stdlib.h>
u32 b3_allocCalls;
u32 b3_maxAllocCalls;
u32 b3_allocCalls = 0;
u32 b3_maxAllocCalls = 0;
b3Version b3_version = { 1, 0, 0 };

View File

@@ -242,8 +242,50 @@ void b3Body::ResetMass()
{
m_invMass = 1.0f / m_mass;
localCenter *= m_invMass;
// Center inertia about the center of mass.
m_I = b3MoveToCOM(m_I, m_mass, localCenter);
m_invI = b3Inverse(m_I);
m_worldInvI = b3RotateToFrame(m_invI, m_xf.rotation);
// Fix rotation.
if (m_flags & e_fixedRotationX)
{
m_invI.y.y = 0.0f;
m_invI.z.y = 0.0f;
m_invI.y.z = 0.0f;
m_invI.z.z = 0.0f;
m_worldInvI.y.y = 0.0f;
m_worldInvI.z.y = 0.0f;
m_worldInvI.y.z = 0.0f;
m_worldInvI.z.z = 0.0f;
}
if (m_flags & e_fixedRotationY)
{
m_invI.x.x = 0.0f;
m_invI.x.z = 0.0f;
m_invI.z.x = 0.0f;
m_invI.z.z = 0.0f;
m_worldInvI.x.x = 0.0f;
m_worldInvI.x.z = 0.0f;
m_worldInvI.z.x = 0.0f;
m_worldInvI.z.z = 0.0f;
}
if (m_flags & e_fixedRotationZ)
{
m_invI.x.x = 0.0f;
m_invI.x.y = 0.0f;
m_invI.y.x = 0.0f;
m_invI.y.y = 0.0f;
m_worldInvI.x.x = 0.0f;
m_worldInvI.x.y = 0.0f;
m_worldInvI.y.x = 0.0f;
m_worldInvI.y.y = 0.0f;
}
}
else
{
@@ -252,61 +294,6 @@ void b3Body::ResetMass()
m_invMass = 1.0f;
}
// Fix rotation.
if (m_flags & e_fixedRotationX)
{
m_I.y.y = 0.0f;
m_I.z.y = 0.0f;
m_I.y.z = 0.0f;
m_I.z.z = 0.0f;
m_invI.y.y = 0.0f;
m_invI.z.y = 0.0f;
m_invI.y.z = 0.0f;
m_invI.z.z = 0.0f;
m_worldInvI.y.y = 0.0f;
m_worldInvI.z.y = 0.0f;
m_worldInvI.y.z = 0.0f;
m_worldInvI.z.z = 0.0f;
}
if (m_flags & e_fixedRotationY)
{
m_I.x.x = 0.0f;
m_I.x.z = 0.0f;
m_I.z.x = 0.0f;
m_I.z.z = 0.0f;
m_invI.x.x = 0.0f;
m_invI.x.z = 0.0f;
m_invI.z.x = 0.0f;
m_invI.z.z = 0.0f;
m_worldInvI.x.x = 0.0f;
m_worldInvI.x.z = 0.0f;
m_worldInvI.z.x = 0.0f;
m_worldInvI.z.z = 0.0f;
}
if (m_flags & e_fixedRotationZ)
{
m_I.x.x = 0.0f;
m_I.x.y = 0.0f;
m_I.y.x = 0.0f;
m_I.y.y = 0.0f;
m_invI.x.x = 0.0f;
m_invI.x.y = 0.0f;
m_invI.y.x = 0.0f;
m_invI.y.y = 0.0f;
m_worldInvI.x.x = 0.0f;
m_worldInvI.x.y = 0.0f;
m_worldInvI.y.x = 0.0f;
m_worldInvI.y.y = 0.0f;
}
// Move center of mass.
b3Vec3 oldCenter = m_sweep.worldCenter;
m_sweep.localCenter = localCenter;
@@ -343,6 +330,88 @@ bool b3Body::ShouldCollide(const b3Body* other) const
return true;
}
void b3Body::GetMassData(b3MassData* data) const
{
data->mass = m_mass;
data->I = m_I;
data->center = m_sweep.localCenter;
}
void b3Body::SetMassData(const b3MassData* massData)
{
if (m_type != e_dynamicBody)
{
return;
}
m_invMass = 0.0f;
m_I.SetZero();
m_invI.SetZero();
m_worldInvI.SetZero();
m_mass = massData->mass;
if (m_mass > 0.0f)
{
m_invMass = 1.0f / m_mass;
m_I = b3MoveToCOM(massData->I, m_mass, massData->center);
m_invI = b3Inverse(m_I);
m_worldInvI = b3RotateToFrame(m_invI, m_xf.rotation);
if (m_flags & e_fixedRotationX)
{
m_invI.y.y = 0.0f;
m_invI.z.y = 0.0f;
m_invI.y.z = 0.0f;
m_invI.z.z = 0.0f;
m_worldInvI.y.y = 0.0f;
m_worldInvI.z.y = 0.0f;
m_worldInvI.y.z = 0.0f;
m_worldInvI.z.z = 0.0f;
}
if (m_flags & e_fixedRotationY)
{
m_invI.x.x = 0.0f;
m_invI.x.z = 0.0f;
m_invI.z.x = 0.0f;
m_invI.z.z = 0.0f;
m_worldInvI.x.x = 0.0f;
m_worldInvI.x.z = 0.0f;
m_worldInvI.z.x = 0.0f;
m_worldInvI.z.z = 0.0f;
}
if (m_flags & e_fixedRotationZ)
{
m_invI.x.x = 0.0f;
m_invI.x.y = 0.0f;
m_invI.y.x = 0.0f;
m_invI.y.y = 0.0f;
m_worldInvI.x.x = 0.0f;
m_worldInvI.x.y = 0.0f;
m_worldInvI.y.x = 0.0f;
m_worldInvI.y.y = 0.0f;
}
}
else
{
m_mass = 1.0f;
m_invMass = 1.0f;
}
// Move center of mass.
b3Vec3 oldCenter = m_sweep.worldCenter;
m_sweep.localCenter = massData->center;
m_sweep.worldCenter0 = m_sweep.worldCenter = b3Mul(m_xf, m_sweep.localCenter);
// Update center of mass velocity.
m_linearVelocity += b3Cross(m_angularVelocity, m_sweep.worldCenter - oldCenter);
}
void b3Body::SetType(b3BodyType type)
{
if (m_type == type)

View File

@@ -22,6 +22,7 @@
#include <bounce/dynamics/shapes/shape.h>
#include <bounce/dynamics/body.h>
#include <bounce/dynamics/world_listeners.h>
#include <bounce/common/profiler.h>
b3ContactManager::b3ContactManager() :
m_convexBlocks(sizeof(b3ConvexContact)),
@@ -166,6 +167,8 @@ void b3ContactManager::FindNewContacts()
void b3ContactManager::UpdateContacts()
{
B3_PROFILE("Update Contacts");
// Update the state of all contacts.
b3Contact* c = m_contactList.m_head;
while (c)

View File

@@ -22,7 +22,7 @@
#include <bounce/dynamics/shapes/capsule_shape.h>
#include <bounce/collision/shapes/capsule.h>
bool b3AreParalell(const b3Capsule& hullA, const b3Capsule& hullB)
static bool b3AreParalell(const b3Capsule& hullA, const b3Capsule& hullB)
{
b3Vec3 E1 = hullA.vertices[1] - hullA.vertices[0];
float32 L1 = b3Length(E1);
@@ -59,6 +59,34 @@ void b3CollideCapsuleAndCapsule(b3Manifold& manifold,
hullB.radius = sB->m_radius;
float32 totalRadius = hullA.radius + hullB.radius;
// todo return small distance output struct?
b3Vec3 pointA, pointB;
b3ClosestPointsOnSegments(&pointA, &pointB, hullA.vertices[0], hullA.vertices[1], hullB.vertices[0], hullB.vertices[1]);
float32 distance = b3Distance(pointA, pointB);
if (distance > totalRadius)
{
return;
}
if (distance > B3_EPSILON)
{
b3Vec3 normal = (pointB - pointA) / distance;
b3Vec3 center = 0.5f * (pointA + hullA.radius * normal + pointB - hullB.radius * normal);
manifold.pointCount = 1;
manifold.points[0].triangleKey = B3_NULL_TRIANGLE;
manifold.points[0].key = 0;
manifold.points[0].localNormal = b3MulT(xfA.rotation, normal);
manifold.points[0].localPoint = b3MulT(xfA, pointA);
manifold.points[0].localPoint2 = b3MulT(xfB, pointB);
manifold.center = center;
manifold.normal = normal;
manifold.tangent1 = b3Perp(normal);
manifold.tangent2 = b3Cross(manifold.tangent1, normal);
return;
}
if (b3AreParalell(hullA, hullB))
{
@@ -108,36 +136,7 @@ void b3CollideCapsuleAndCapsule(b3Manifold& manifold,
manifold.normal = normal;
manifold.tangent1 = b3Perp(normal);
manifold.tangent2 = b3Cross(manifold.tangent1, normal);
return;
}
}
}
b3Vec3 pointA, pointB;
b3ClosestPointsOnSegments(&pointA, &pointB, hullA.vertices[0], hullA.vertices[1], hullB.vertices[0], hullB.vertices[1]);
if (b3DistanceSquared(pointA, pointB) > totalRadius * totalRadius)
{
return;
}
float32 distance = b3Distance(pointA, pointB);
if (distance > B3_EPSILON)
{
b3Vec3 normal = (pointB - pointA) / distance;
b3Vec3 center = 0.5f * (pointA + hullA.radius * normal + pointB - hullB.radius * normal);
manifold.pointCount = 1;
manifold.points[0].triangleKey = B3_NULL_TRIANGLE;
manifold.points[0].key = 0;
manifold.points[0].localNormal = b3MulT(xfA.rotation, normal);
manifold.points[0].localPoint = b3MulT(xfA, pointA);
manifold.points[0].localPoint2 = b3MulT(xfB, pointB);
manifold.center = center;
manifold.normal = normal;
manifold.tangent1 = b3Perp(normal);
manifold.tangent2 = b3Cross(manifold.tangent1, normal);
}
}

View File

@@ -241,7 +241,7 @@ void b3CollideHulls(b3Manifold& manifold,
//
bool b3_enableConvexCache = true;
u32 b3_convexCalls, b3_convexCacheHits;
u32 b3_convexCalls = 0, b3_convexCacheHits = 0;
void b3CollideHullAndHull(b3Manifold& manifold,
const b3Transform& xfA, const b3HullShape* sA,

View File

@@ -48,11 +48,13 @@ const b3Color b3Color_blue(0.0f, 0.0f, 1.0f);
const b3Color b3Color_yellow(1.0f, 1.0f, 0.0f);
const b3Color b3Color_pink(1.0f, 0.0f, 1.0f);
b3Draw* b3_debugDraw = NULL;
void b3World::DebugDraw() const
{
B3_ASSERT(m_debugDraw);
B3_ASSERT(b3_debugDraw);
u32 flags = m_debugDraw->m_flags;
u32 flags = b3_debugDraw->m_flags;
if (flags & b3Draw::e_centerOfMassesFlag)
{
@@ -60,7 +62,7 @@ void b3World::DebugDraw() const
{
b3Transform xf = b->m_xf;
xf.position = b->m_sweep.worldCenter;
m_debugDraw->DrawTransform(xf);
b3_debugDraw->DrawTransform(xf);
}
}
@@ -83,7 +85,7 @@ void b3World::DebugDraw() const
for (b3Shape* s = b->m_shapeList.m_head; s; s = s->m_next)
{
const b3AABB3& aabb = m_contactMan.m_broadPhase.GetAABB(s->m_broadPhaseID);
m_debugDraw->DrawAABB(aabb, b3Color_pink);
b3_debugDraw->DrawAABB(aabb, b3Color_pink);
}
}
}
@@ -122,18 +124,18 @@ void b3World::DebugDraw() const
if (flags & b3Draw::e_contactPointsFlag)
{
m_debugDraw->DrawPoint(p, 4.0f, b3Color_yellow);
b3_debugDraw->DrawPoint(p, 4.0f, b3Color_yellow);
}
if (flags & b3Draw::e_contactNormalsFlag)
{
m_debugDraw->DrawSegment(p, p + n, b3Color_yellow);
b3_debugDraw->DrawSegment(p, p + n, b3Color_yellow);
}
if (flags & b3Draw::e_contactTangentsFlag)
{
m_debugDraw->DrawSegment(p, p + t1, b3Color_yellow);
m_debugDraw->DrawSegment(p, p + t2, b3Color_yellow);
b3_debugDraw->DrawSegment(p, p + t1, b3Color_yellow);
b3_debugDraw->DrawSegment(p, p + t2, b3Color_yellow);
}
}
@@ -152,18 +154,18 @@ void b3World::DebugDraw() const
if (flags & b3Draw::e_contactPointsFlag)
{
m_debugDraw->DrawPoint(p, 4.0f, mp->persisting ? b3Color_green : b3Color_red);
b3_debugDraw->DrawPoint(p, 4.0f, mp->persisting ? b3Color_green : b3Color_red);
}
if (flags & b3Draw::e_contactNormalsFlag)
{
m_debugDraw->DrawSegment(p, p + n, b3Color_white);
b3_debugDraw->DrawSegment(p, p + n, b3Color_white);
}
if (flags & b3Draw::e_contactTangentsFlag)
{
m_debugDraw->DrawSegment(p, p + t1, b3Color_yellow);
m_debugDraw->DrawSegment(p, p + t2, b3Color_yellow);
b3_debugDraw->DrawSegment(p, p + t1, b3Color_yellow);
b3_debugDraw->DrawSegment(p, p + t2, b3Color_yellow);
}
}
}
@@ -179,7 +181,7 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const
{
const b3SphereShape* sphere = (b3SphereShape*)shape;
b3Vec3 p = xf * sphere->m_center;
m_debugDraw->DrawPoint(p, 4.0f, wireColor);
b3_debugDraw->DrawPoint(p, 4.0f, wireColor);
break;
}
case e_capsuleShape:
@@ -187,9 +189,9 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const
const b3CapsuleShape* capsule = (b3CapsuleShape*)shape;
b3Vec3 p1 = xf * capsule->m_centers[0];
b3Vec3 p2 = xf * capsule->m_centers[1];
m_debugDraw->DrawPoint(p1, 4.0f, wireColor);
m_debugDraw->DrawPoint(p2, 4.0f, wireColor);
m_debugDraw->DrawSegment(p1, p2, wireColor);
b3_debugDraw->DrawPoint(p1, 4.0f, wireColor);
b3_debugDraw->DrawPoint(p2, 4.0f, wireColor);
b3_debugDraw->DrawSegment(p1, p2, wireColor);
break;
}
case e_hullShape:
@@ -204,7 +206,7 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const
b3Vec3 p1 = xf * hull->vertices[edge->origin];
b3Vec3 p2 = xf * hull->vertices[twin->origin];
m_debugDraw->DrawSegment(p1, p2, wireColor);
b3_debugDraw->DrawSegment(p1, p2, wireColor);
}
break;
}
@@ -220,7 +222,7 @@ void b3World::DrawShape(const b3Transform& xf, const b3Shape* shape) const
b3Vec3 p2 = xf * mesh->vertices[t->v2];
b3Vec3 p3 = xf * mesh->vertices[t->v3];
m_debugDraw->DrawTriangle(p1, p2, p3, wireColor);
b3_debugDraw->DrawTriangle(p1, p2, p3, wireColor);
}
break;
}
@@ -240,31 +242,31 @@ void b3World::DrawJoint(const b3Joint* joint) const
case e_mouseJoint:
{
b3MouseJoint* o = (b3MouseJoint*)joint;
o->Draw(m_debugDraw);
o->Draw(b3_debugDraw);
break;
}
case e_springJoint:
{
b3SpringJoint* o = (b3SpringJoint*)joint;
o->Draw(m_debugDraw);
o->Draw(b3_debugDraw);
break;
}
case e_revoluteJoint:
{
b3RevoluteJoint* o = (b3RevoluteJoint*)joint;
o->Draw(m_debugDraw);
o->Draw(b3_debugDraw);
break;
}
case e_sphereJoint:
{
b3SphereJoint* o = (b3SphereJoint*)joint;
o->Draw(m_debugDraw);
o->Draw(b3_debugDraw);
break;
}
case e_coneJoint:
{
b3ConeJoint* o = (b3ConeJoint*)joint;
o->Draw(m_debugDraw);
o->Draw(b3_debugDraw);
break;
}
default:

View File

@@ -24,7 +24,7 @@
#include <bounce/dynamics/contacts/contact.h>
#include <bounce/dynamics/contacts/contact_solver.h>
#include <bounce/common/memory/stack_allocator.h>
#include <bounce/common/time.h>
#include <bounce/common/profiler.h>
b3Island::b3Island(b3StackAllocator* allocator, u32 bodyCapacity, u32 contactCapacity, u32 jointCapacity)
{
@@ -83,7 +83,7 @@ void b3Island::Add(b3Joint* j)
++m_jointCount;
}
void b3Island::Solve(b3Profile* profile, const b3Vec3& gravity, float32 dt, u32 velocityIterations, u32 positionIterations, u32 flags)
void b3Island::Solve(const b3Vec3& gravity, float32 dt, u32 velocityIterations, u32 positionIterations, u32 flags)
{
float32 h = dt;
@@ -155,8 +155,8 @@ void b3Island::Solve(b3Profile* profile, const b3Vec3& gravity, float32 dt, u32
// 2. Initialize constraints
{
b3Time time;
B3_PROFILE("Initialize Constraints");
contactSolver.InitializeConstraints();
if (flags & e_warmStartBit)
@@ -170,14 +170,11 @@ void b3Island::Solve(b3Profile* profile, const b3Vec3& gravity, float32 dt, u32
{
jointSolver.WarmStart();
}
time.Update();
profile->solver.initializeContacts = time.GetElapsedMilis();
}
// 3. Solve velocity constraints
{
b3Time time;
B3_PROFILE("Solve Velocity Constraints");
for (u32 i = 0; i < velocityIterations; ++i)
{
@@ -189,9 +186,6 @@ void b3Island::Solve(b3Profile* profile, const b3Vec3& gravity, float32 dt, u32
{
contactSolver.StoreImpulses();
}
time.Update();
profile->solver.solveVelocity = time.GetElapsedMilis();
}
// 4. Integrate positions
@@ -230,7 +224,7 @@ void b3Island::Solve(b3Profile* profile, const b3Vec3& gravity, float32 dt, u32
// 5. Solve position constraints
{
b3Time time;
B3_PROFILE("Solve Position Constraints");
bool positionsSolved = false;
for (u32 i = 0; i < positionIterations; ++i)
@@ -244,9 +238,6 @@ void b3Island::Solve(b3Profile* profile, const b3Vec3& gravity, float32 dt, u32
break;
}
}
time.Update();
profile->solver.solvePosition = time.GetElapsedMilis();
}
// 6. Copy state buffers back to the bodies

View File

@@ -105,6 +105,7 @@ const b3Vec3& b3MouseJoint::GetTarget() const
void b3MouseJoint::SetTarget(const b3Vec3& target)
{
m_worldTargetA = target;
GetBodyB()->SetAwake(true);
}
void b3MouseJoint::Draw(b3Draw* draw) const

View File

@@ -24,7 +24,7 @@
#include <bounce/dynamics/contacts/contact.h>
#include <bounce/dynamics/joints/joint.h>
#include <bounce/dynamics/time_step.h>
#include <bounce/common/time.h>
#include <bounce/common/profiler.h>
extern u32 b3_allocCalls;
extern u32 b3_maxAllocCalls;
@@ -34,7 +34,6 @@ b3World::b3World() : m_bodyBlocks(sizeof(b3Body))
b3_allocCalls = 0;
b3_maxAllocCalls = 0;
m_debugDraw = NULL;
memset(&m_profile, 0, sizeof(b3Profile));
m_flags = e_clearForcesFlag;
m_sleeping = false;
@@ -68,11 +67,6 @@ void b3World::SetSleeping(bool flag)
}
}
void b3World::SetDebugDraw(b3Draw* debugDraw)
{
m_debugDraw = debugDraw;
}
b3Body* b3World::CreateBody(const b3BodyDef& def)
{
void* mem = m_bodyBlocks.Allocate();
@@ -104,9 +98,7 @@ void b3World::DestroyJoint(b3Joint* j)
void b3World::Step(float32 dt, u32 velocityIterations, u32 positionIterations)
{
memset(&m_profile, 0, sizeof(b3Profile));
b3Time stepTime;
B3_PROFILE("Step");
if (m_flags & e_shapeAddedFlag)
{
@@ -115,34 +107,22 @@ void b3World::Step(float32 dt, u32 velocityIterations, u32 positionIterations)
m_flags &= ~e_shapeAddedFlag;
}
// Update contacts. This is where some contacts might be destroyed.
m_contactMan.UpdateContacts();
// Integrate velocities, clear forces and torques, solve constraints, integrate positions.
if (dt > 0.0f)
{
// Update contacts. This is where some contacts might be destroyed.
b3Time time;
m_contactMan.UpdateContacts();
time.Update();
m_profile.collide.narrowphase = time.GetElapsedMilis();
Solve(dt, velocityIterations, positionIterations);
}
{
b3Time time;
if (dt > 0.0f)
{
Solve(dt, velocityIterations, positionIterations);
}
time.Update();
}
{
//todo
//SolveTOI
}
stepTime.Update();
m_profile.total = stepTime.GetElapsedMilis();
//SolveTOI
}
void b3World::Solve(float32 dt, u32 velocityIterations, u32 positionIterations)
{
B3_PROFILE("Solve");
// Clear all visited flags for the depth first search.
for (b3Body* b = m_bodyList.m_head; b; b = b->m_next)
{
@@ -289,7 +269,7 @@ void b3World::Solve(float32 dt, u32 velocityIterations, u32 positionIterations)
}
// Integrate velocities, clear forces and torques, solve constraints, integrate positions.
island.Solve(&m_profile, externalForce, dt, velocityIterations, positionIterations, islandFlags);
island.Solve(externalForce, dt, velocityIterations, positionIterations, islandFlags);
// Allow static bodies to participate in other islands.
for (u32 i = 0; i < island.m_bodyCount; ++i)
@@ -305,7 +285,8 @@ void b3World::Solve(float32 dt, u32 velocityIterations, u32 positionIterations)
m_stackAllocator.Free(stack);
{
b3Time time;
B3_PROFILE("Find New Pairs");
for (b3Body* b = m_bodyList.m_head; b; b = b->m_next)
{
// If a body didn't participate on a island then it didn't move
@@ -319,13 +300,10 @@ void b3World::Solve(float32 dt, u32 velocityIterations, u32 positionIterations)
b->SynchronizeShapes();
}
// Notify the contacts the shapes may have been moved.
// Notify the contacts the AABBs may have been moved.
m_contactMan.SynchronizeShapes();
m_contactMan.FindNewContacts();
time.Update();
m_profile.collide.broadphase = time.GetElapsedMilis();
}
}