Browse files

more work on box2D

  • Loading branch information...
1 parent 481ff28 commit f690d5cd674c88317b2997dbadc914bc6171a42e @totallyevil totallyevil committed Oct 10, 2012
View
33 external/Box2D/box2d/Collision/Shapes/b2ChainShape.cs
@@ -10,13 +10,42 @@ public class b2ChainShape : b2Shape
{
/// The vertices. Owned by this class.
protected b2Vec2[] m_vertices;
-
+ public b2Vec2[] Vertices
+ {
+ get { return (m_vertices); }
+ set { m_vertices = value; }
+ }
/// The vertex count.
protected int m_count;
-
+ public int Count
+ {
+ get { return (m_count); }
+ set { m_count = value; }
+ }
protected b2Vec2 m_prevVertex = new b2Vec2();
+ public b2Vec2 PrevVertex
+ {
+ get { return (m_prevVertex); }
+ set { m_prevVertex = value; }
+ }
+
protected b2Vec2 m_nextVertex = new b2Vec2();
+ public b2Vec2 NextVertex
+ {
+ get { return (m_nextVertex); }
+ set { m_nextVertex = value; }
+ }
protected bool m_hasPrevVertex, m_hasNextVertex;
+ public bool HasPrevVertex
+ {
+ get { return (m_hasPrevVertex); }
+ set { m_hasPrevVertex = value; }
+ }
+ public bool HasNextVertex
+ {
+ get { return (m_hasNextVertex); }
+ set { m_hasNextVertex = value; }
+ }
public b2ChainShape()
{
View
2 external/Box2D/box2d/Collision/b2BroadPhase.cs
@@ -238,7 +238,7 @@ public void Query<T>(T callback, b2AABB aabb)
m_tree.Query(callback, aabb);
}
- void RayCast<T>(T callback, b2RayCastInput input)
+ public void RayCast<T>(T callback, b2RayCastInput input)
{
m_tree.RayCast(callback, input);
}
View
771 external/Box2D/box2d/Dynamics/b2Body.cs
@@ -3,6 +3,8 @@
using System.Linq;
using System.Text;
using Box2D.Common;
+using Box2D.Collision;
+using Box2D.Collision.Shapes;
namespace Box2D.Dynamics
{
@@ -18,16 +20,16 @@ public enum b2BodyType
[Flags]
public enum b2BodyFlags
{
- e_islandFlag = 0x0001,
- e_awakeFlag = 0x0002,
- e_autoSleepFlag = 0x0004,
- e_bulletFlag = 0x0008,
- e_fixedRotationFlag = 0x0010,
- e_activeFlag = 0x0020,
- e_toiFlag = 0x0040
+ e_islandFlag = 0x0001,
+ e_awakeFlag = 0x0002,
+ e_autoSleepFlag = 0x0004,
+ e_bulletFlag = 0x0008,
+ e_fixedRotationFlag = 0x0010,
+ e_activeFlag = 0x0020,
+ e_toiFlag = 0x0040
}
-
+
public class b2Body
{
protected b2BodyType m_type;
@@ -51,33 +53,78 @@ public int IslandIndex
set { m_islandIndex = value; }
}
- protected b2Transform m_xf; // the body origin transform
+ protected b2Transform m_xf = new b2Transform(); // the body origin transform
public b2Transform XF
{
get { return (m_xf); }
set { m_xf = value; }
}
+ public b2Transform Transform
+ {
+ get { return (XF); }
+ set { XF = value; }
+ }
+ public b2Vec2 Position
+ {
+ get { return (m_xf.p); }
+ }
- protected b2Sweep m_sweep; // the swept motion for CCD
+ protected b2Sweep m_sweep = new b2Sweep(); // the swept motion for CCD
public b2Sweep Sweep
{
get { return (m_sweep); }
set { m_sweep = value; }
}
- protected b2Vec2 m_linearVelocity;
+ public float Angle
+ {
+ get { return (m_sweep.a); }
+ }
+ public b2Vec2 WorldCenter
+ {
+ get { return (m_sweep.c); }
+ }
+ public b2Vec2 LocalCenter
+ {
+ get { return (m_sweep.localCenter); }
+ }
+
+ protected b2Vec2 m_linearVelocity = new b2Vec2();
public b2Vec2 LinearVelocity
{
get { return (m_linearVelocity); }
- set { m_linearVelocity = value; }
+ set
+ {
+ if (m_type == b2BodyType.b2_staticBody)
+ {
+ return;
+ }
+ if (b2Math.b2Dot(value, value) > 0.0f)
+ {
+ SetAwake(true);
+ }
+ m_linearVelocity = value;
+ }
}
protected float m_angularVelocity;
public float AngularVelocity
{
get { return (m_angularVelocity); }
- set { m_angularVelocity = value; }
+ set
+ {
+ if (m_type == b2BodyType.b2_staticBody)
+ {
+ return;
+ }
+
+ if (value * value > 0.0f)
+ {
+ SetAwake(true);
+ }
+ m_angularVelocity = value;
+ }
}
- protected b2Vec2 m_force;
+ protected b2Vec2 m_force = new b2Vec2();
public b2Vec2 Force
{
get { return (m_force); }
@@ -154,12 +201,19 @@ public float I
get { return (m_I); }
set { m_I = value; }
}
+ public float Inertia
+ {
+ get
+ {
+ return m_I + m_mass * b2Math.b2Dot(m_sweep.localCenter, m_sweep.localCenter);
+ }
+ }
public float InvertedI
{
get { return (m_invI); }
set { m_invI = value; }
}
-
+
protected float m_linearDamping;
public float LinearDamping
@@ -193,6 +247,689 @@ public object UserData
get { return (m_userData); }
set { m_userData = value; }
}
-
- }
+
+ public b2Body(b2BodyDef bd, b2World world)
+ {
+ m_flags = 0;
+
+ if (bd.bullet)
+ {
+ m_flags |= b2BodyFlags.e_bulletFlag;
+ }
+ if (bd.fixedRotation)
+ {
+ m_flags |= b2BodyFlags.e_fixedRotationFlag;
+ }
+ if (bd.allowSleep)
+ {
+ m_flags |= b2BodyFlags.e_autoSleepFlag;
+ }
+ if (bd.awake)
+ {
+ m_flags |= b2BodyFlags.e_awakeFlag;
+ }
+ if (bd.active)
+ {
+ m_flags |= b2BodyFlags.e_activeFlag;
+ }
+
+ m_world = world;
+
+ m_xf.p = bd.position;
+ m_xf.q.Set(bd.angle);
+
+ m_sweep.localCenter.SetZero();
+ m_sweep.c0 = m_xf.p;
+ m_sweep.c = m_xf.p;
+ m_sweep.a0 = bd.angle;
+ m_sweep.a = bd.angle;
+ m_sweep.alpha0 = 0.0f;
+
+ m_jointList = null;
+ m_contactList = null;
+ m_prev = null;
+ m_next = null;
+
+ m_linearVelocity = bd.linearVelocity;
+ m_angularVelocity = bd.angularVelocity;
+
+ m_linearDamping = bd.linearDamping;
+ m_angularDamping = bd.angularDamping;
+ m_gravityScale = bd.gravityScale;
+
+ m_force.SetZero();
+ m_torque = 0.0f;
+
+ m_sleepTime = 0.0f;
+
+ m_type = bd.type;
+
+ if (m_type == b2BodyType.b2_dynamicBody)
+ {
+ m_mass = 1.0f;
+ m_invMass = 1.0f;
+ }
+ else
+ {
+ m_mass = 0.0f;
+ m_invMass = 0.0f;
+ }
+
+ m_I = 0.0f;
+ m_invI = 0.0f;
+
+ m_userData = bd.userData;
+
+ m_fixtureList = null;
+ m_fixtureCount = 0;
+ }
+
+ public virtual b2MassData GetMassData()
+ {
+ b2MassData data = new b2MassData();
+ data.mass = m_mass;
+ data.I = m_I + m_mass * b2Math.b2Dot(m_sweep.localCenter, m_sweep.localCenter);
+ data.center = m_sweep.localCenter;
+ return (data);
+ }
+ public virtual b2Vec2 GetWorldPoint(b2Vec2 localPoint)
+ {
+ return b2Math.b2Mul(m_xf, localPoint);
+ }
+
+ public virtual b2Vec2 GetWorldVector(b2Vec2 localVector)
+ {
+ return b2Math.b2Mul(m_xf.q, localVector);
+ }
+
+ public virtual b2Vec2 GetLocalPoint(b2Vec2 worldPoint)
+ {
+ return b2Math.b2MulT(m_xf, worldPoint);
+ }
+
+ public virtual b2Vec2 GetLocalVector(b2Vec2 worldVector)
+ {
+ return b2Math.b2MulT(m_xf.q, worldVector);
+ }
+
+ public virtual b2Vec2 GetLinearVelocityFromWorldPoint(b2Vec2 worldPoint)
+ {
+ return m_linearVelocity + b2Math.b2Cross(m_angularVelocity, worldPoint - m_sweep.c);
+ }
+
+ public virtual b2Vec2 GetLinearVelocityFromLocalPoint(b2Vec2 localPoint)
+ {
+ return GetLinearVelocityFromWorldPoint(GetWorldPoint(localPoint));
+ }
+ public virtual void SetBullet(bool flag)
+ {
+ if (flag)
+ {
+ m_flags |= b2BodyFlags.e_bulletFlag;
+ }
+ else
+ {
+ m_flags &= ~b2BodyFlags.e_bulletFlag;
+ }
+ }
+
+ public virtual bool IsBullet()
+ {
+ return (m_flags & b2BodyFlags.e_bulletFlag) == b2BodyFlags.e_bulletFlag;
+ }
+
+ public virtual void SetAwake(bool flag)
+ {
+ if (flag)
+ {
+ if ((m_flags & b2BodyFlags.e_awakeFlag) == 0)
+ {
+ m_flags |= b2BodyFlags.e_awakeFlag;
+ m_sleepTime = 0.0f;
+ }
+ }
+ else
+ {
+ m_flags &= ~b2BodyFlags.e_awakeFlag;
+ m_sleepTime = 0.0f;
+ m_linearVelocity.SetZero();
+ m_angularVelocity = 0.0f;
+ m_force.SetZero();
+ m_torque = 0.0f;
+ }
+ }
+
+ public virtual bool IsAwake()
+ {
+ return (m_flags & b2BodyFlags.e_awakeFlag) == b2BodyFlags.e_awakeFlag;
+ }
+
+ public virtual bool IsActive()
+ {
+ return (m_flags & b2BodyFlags.e_activeFlag) == b2BodyFlags.e_activeFlag;
+ }
+
+ public virtual void SetFixedRotation(bool flag)
+ {
+ if (flag)
+ {
+ m_flags |= b2BodyFlags.e_fixedRotationFlag;
+ }
+ else
+ {
+ m_flags &= ~b2BodyFlags.e_fixedRotationFlag;
+ }
+
+ ResetMassData();
+ }
+
+ public virtual bool IsFixedRotation()
+ {
+ return (m_flags & b2BodyFlags.e_fixedRotationFlag) == b2BodyFlags.e_fixedRotationFlag;
+ }
+
+ public virtual void SetSleepingAllowed(bool flag)
+ {
+ if (flag)
+ {
+ m_flags |= b2BodyFlags.e_autoSleepFlag;
+ }
+ else
+ {
+ m_flags &= ~b2BodyFlags.e_autoSleepFlag;
+ SetAwake(true);
+ }
+ }
+
+ public virtual bool IsSleepingAllowed()
+ {
+ return (m_flags & b2BodyFlags.e_autoSleepFlag) == b2BodyFlags.e_autoSleepFlag;
+ }
+ public virtual void ApplyForce(b2Vec2 force, b2Vec2 point)
+ {
+ if (m_type != b2BodyType.b2_dynamicBody)
+ {
+ return;
+ }
+
+ if (IsAwake() == false)
+ {
+ SetAwake(true);
+ }
+
+ m_force += force;
+ m_torque += b2Math.b2Cross(point - m_sweep.c, force);
+ }
+
+ public virtual void ApplyForceToCenter(b2Vec2 force)
+ {
+ if (m_type != b2BodyType.b2_dynamicBody)
+ {
+ return;
+ }
+
+ if (IsAwake() == false)
+ {
+ SetAwake(true);
+ }
+
+ m_force += force;
+ }
+
+ public virtual void ApplyTorque(float torque)
+ {
+ if (m_type != b2BodyType.b2_dynamicBody)
+ {
+ return;
+ }
+
+ if (IsAwake() == false)
+ {
+ SetAwake(true);
+ }
+
+ m_torque += torque;
+ }
+
+ public virtual void ApplyLinearImpulse(b2Vec2 impulse, b2Vec2 point)
+ {
+ if (m_type != b2BodyType.b2_dynamicBody)
+ {
+ return;
+ }
+
+ if (IsAwake() == false)
+ {
+ SetAwake(true);
+ }
+ m_linearVelocity += m_invMass * impulse;
+ m_angularVelocity += m_invI * b2Math.b2Cross(point - m_sweep.c, impulse);
+ }
+
+ public virtual void ApplyAngularImpulse(float impulse)
+ {
+ if (m_type != b2BodyType.b2_dynamicBody)
+ {
+ return;
+ }
+
+ if (IsAwake() == false)
+ {
+ SetAwake(true);
+ }
+ m_angularVelocity += m_invI * impulse;
+ }
+
+ public virtual void SynchronizeTransform()
+ {
+ m_xf.q.Set(m_sweep.a);
+ m_xf.p = m_sweep.c - b2Math.b2Mul(m_xf.q, m_sweep.localCenter);
+ }
+
+ public virtual void Advance(float alpha)
+ {
+ // Advance to the new safe time. This doesn't sync the broad-phase.
+ m_sweep.Advance(alpha);
+ m_sweep.c = m_sweep.c0;
+ m_sweep.a = m_sweep.a0;
+ m_xf.q.Set(m_sweep.a);
+ m_xf.p = m_sweep.c - b2Math.b2Mul(m_xf.q, m_sweep.localCenter);
+ }
+
+public virtual void SetType(b2BodyType type)
+{
+ if (m_world.IsLocked() == true)
+ {
+ return;
+ }
+
+ if (m_type == type)
+ {
+ return;
+ }
+
+ m_type = type;
+
+ ResetMassData();
+
+ if (m_type == b2BodyType.b2_staticBody)
+ {
+ m_linearVelocity.SetZero();
+ m_angularVelocity = 0.0f;
+ m_sweep.a0 = m_sweep.a;
+ m_sweep.c0 = m_sweep.c;
+ SynchronizeFixtures();
+ }
+
+ SetAwake(true);
+
+ m_force.SetZero();
+ m_torque = 0.0f;
+
+ // Since the body type changed, we need to flag contacts for filtering.
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ f.Refilter();
+ }
+}
+
+public virtual b2Fixture CreateFixture(b2FixtureDef def)
+{
+ if (m_world.IsLocked() == true)
+ {
+ return null;
+ }
+
+ b2Fixture fixture = new b2Fixture();
+ fixture.Create(this, def);
+
+ if (m_flags.HasFlag(b2BodyFlags.e_activeFlag))
+ {
+ b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
+ fixture.CreateProxies(broadPhase, m_xf);
+ }
+
+ fixture.Next = m_fixtureList;
+ m_fixtureList = fixture;
+ ++m_fixtureCount;
+
+ fixture.m_body = this;
+
+ // Adjust mass properties if needed.
+ if (fixture.m_density > 0.0f)
+ {
+ ResetMassData();
+ }
+
+ // Let the world know we have a new fixture. This will cause new contacts
+ // to be created at the beginning of the next time step.
+ m_world.WorldFlags |= b2WorldFlags.e_newFixture;
+
+ return fixture;
+}
+
+public virtual b2Fixture CreateFixture(b2Shape shape, float density)
+{
+ b2FixtureDef def;
+ def.shape = shape;
+ def.density = density;
+
+ return CreateFixture(&def);
+}
+
+public virtual void DestroyFixture(b2Fixture fixture)
+{
+ b2Assert(m_world.IsLocked() == false);
+ if (m_world.IsLocked() == true)
+ {
+ return;
+ }
+
+ b2Assert(fixture.m_body == this);
+
+ // Remove the fixture from this body's singly linked list.
+ b2Assert(m_fixtureCount > 0);
+ b2Fixture* node = &m_fixtureList;
+ bool found = false;
+ while (*node != null)
+ {
+ if (*node == fixture)
+ {
+ *node = fixture.Next;
+ found = true;
+ break;
+ }
+
+ node = &(*node).Next;
+ }
+
+ // You tried to remove a shape that is not attached to this body.
+ b2Assert(found);
+
+ // Destroy any contacts associated with the fixture.
+ b2ContactEdge* edge = m_contactList;
+ while (edge)
+ {
+ b2Contact* c = edge.contact;
+ edge = edge.next;
+
+ b2Fixture fixtureA = c.GetFixtureA();
+ b2Fixture fixtureB = c.GetFixtureB();
+
+ if (fixture == fixtureA || fixture == fixtureB)
+ {
+ // This destroys the contact and removes it from
+ // this body's contact list.
+ m_world.ContactManager.Destroy(c);
+ }
+ }
+
+ b2BlockAllocator* allocator = m_world.m_blockAllocator;
+
+ if (m_flags & e_activeFlag)
+ {
+ b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
+ fixture.DestroyProxies(broadPhase);
+ }
+
+ fixture.Destroy(allocator);
+ fixture.m_body = null;
+ fixture.Next = null;
+ fixture.~b2Fixture();
+ allocator.Free(fixture, sizeof(b2Fixture));
+
+ --m_fixtureCount;
+
+ // Reset the mass data.
+ ResetMassData();
+}
+
+public virtual void ResetMassData()
+{
+ // Compute mass data from shapes. Each shape has its own density.
+ m_mass = 0.0f;
+ m_invMass = 0.0f;
+ m_I = 0.0f;
+ m_invI = 0.0f;
+ m_sweep.localCenter.SetZero();
+
+ // Static and kinematic bodies have zero mass.
+ if (m_type == b2_staticBody || m_type == b2_kinematicBody)
+ {
+ m_sweep.c0 = m_xf.p;
+ m_sweep.c = m_xf.p;
+ m_sweep.a0 = m_sweep.a;
+ return;
+ }
+
+ b2Assert(m_type == b2_dynamicBody);
+
+ // Accumulate mass over all fixtures.
+ b2Vec2 localCenter = b2Vec2_zero;
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ if (f.m_density == 0.0f)
+ {
+ continue;
+ }
+
+ b2MassData massData;
+ f.GetMassData(&massData);
+ m_mass += massData.mass;
+ localCenter += massData.mass * massData.center;
+ m_I += massData.I;
+ }
+
+ // Compute center of mass.
+ if (m_mass > 0.0f)
+ {
+ m_invMass = 1.0f / m_mass;
+ localCenter *= m_invMass;
+ }
+ else
+ {
+ // Force all dynamic bodies to have a positive mass.
+ m_mass = 1.0f;
+ m_invMass = 1.0f;
+ }
+
+ if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0)
+ {
+ // Center the inertia about the center of mass.
+ m_I -= m_mass * b2Dot(localCenter, localCenter);
+ b2Assert(m_I > 0.0f);
+ m_invI = 1.0f / m_I;
+
+ }
+ else
+ {
+ m_I = 0.0f;
+ m_invI = 0.0f;
+ }
+
+ // Move center of mass.
+ b2Vec2 oldCenter = m_sweep.c;
+ m_sweep.localCenter = localCenter;
+ m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter);
+
+ // Update center of mass velocity.
+ m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter);
+}
+
+public virtual void SetMassData(b2MassData massData)
+{
+ b2Assert(m_world.IsLocked() == false);
+ if (m_world.IsLocked() == true)
+ {
+ return;
+ }
+
+ if (m_type != b2_dynamicBody)
+ {
+ return;
+ }
+
+ m_invMass = 0.0f;
+ m_I = 0.0f;
+ m_invI = 0.0f;
+
+ m_mass = massData.mass;
+ if (m_mass <= 0.0f)
+ {
+ m_mass = 1.0f;
+ }
+
+ m_invMass = 1.0f / m_mass;
+
+ if (massData.I > 0.0f && (m_flags & e_fixedRotationFlag) == 0)
+ {
+ m_I = massData.I - m_mass * b2Dot(massData.center, massData.center);
+ b2Assert(m_I > 0.0f);
+ m_invI = 1.0f / m_I;
+ }
+
+ // Move center of mass.
+ b2Vec2 oldCenter = m_sweep.c;
+ m_sweep.localCenter = massData.center;
+ m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter);
+
+ // Update center of mass velocity.
+ m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter);
+}
+
+public virtual bool ShouldCollide(b2Body other)
+{
+ // At least one body should be dynamic.
+ if (m_type != b2_dynamicBody && other.m_type != b2_dynamicBody)
+ {
+ return false;
+ }
+
+ // Does a joint prevent collision?
+ for (b2JointEdge* jn = m_jointList; jn; jn = jn.next)
+ {
+ if (jn.other == other)
+ {
+ if (jn.joint.m_collideConnected == false)
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+public virtual void SetTransform(b2Vec2 position, float angle)
+{
+ if (m_world.IsLocked() == true)
+ {
+ return;
+ }
+
+ m_xf.q.Set(angle);
+ m_xf.p = position;
+
+ m_sweep.c = b2Mul(m_xf, m_sweep.localCenter);
+ m_sweep.a = angle;
+
+ m_sweep.c0 = m_sweep.c;
+ m_sweep.a0 = angle;
+
+ b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ f.Synchronize(broadPhase, m_xf, m_xf);
+ }
+
+ m_world.ContactManager.FindNewContacts();
+}
+
+public virtual void SynchronizeFixtures()
+{
+ b2Transform xf1 = new b2Transform();
+ xf1.q.Set(m_sweep.a0);
+ xf1.p = m_sweep.c0 - b2Mul(xf1.q, m_sweep.localCenter);
+
+ b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ f.Synchronize(broadPhase, xf1, m_xf);
+ }
+}
+
+public virtual void SetActive(bool flag)
+{
+
+ if (flag == IsActive())
+ {
+ return;
+ }
+
+ if (flag)
+ {
+ m_flags |= b2BodyFlags.e_activeFlag;
+
+ // Create all proxies.
+ b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ f.CreateProxies(broadPhase, m_xf);
+ }
+
+ // Contacts are created the next time step.
+ }
+ else
+ {
+ m_flags &= ~b2BodyFlags.e_activeFlag;
+
+ // Destroy all proxies.
+ b2BroadPhase broadPhase = m_world.ContactManager.BroadPhase;
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ f.DestroyProxies(broadPhase);
+ }
+
+ // Destroy the attached contacts.
+ b2ContactEdge ce = m_contactList;
+ while (ce != null)
+ {
+ b2ContactEdge ce0 = ce;
+ ce = ce.Next;
+ m_world.ContactManager.Destroy(ce0.contact);
+ }
+ m_contactList = null;
+ }
+}
+
+public virtual void Dump()
+{
+ int bodyIndex = m_islandIndex;
+
+ System.Diagnostics.Debug.WriteLine("{");
+ System.Diagnostics.Debug.WriteLine(" b2BodyDef bd;");
+ System.Diagnostics.Debug.WriteLine(" bd.type = b2BodyType({0});", m_type);
+ System.Diagnostics.Debug.WriteLine(" bd.position.Set({0:N5}, {1:N5});", m_xf.p.x, m_xf.p.y);
+ System.Diagnostics.Debug.WriteLine(" bd.angle = {0:N5};", m_sweep.a);
+ System.Diagnostics.Debug.WriteLine(" bd.linearVelocity.Set({0:N5}, {1:N5});", m_linearVelocity.x, m_linearVelocity.y);
+ System.Diagnostics.Debug.WriteLine(" bd.angularVelocity = {0:N5};", m_angularVelocity);
+ System.Diagnostics.Debug.WriteLine(" bd.linearDamping = {0:N5};", m_linearDamping);
+ System.Diagnostics.Debug.WriteLine(" bd.angularDamping = {0:N5};", m_angularDamping);
+ System.Diagnostics.Debug.WriteLine(" bd.allowSleep = bool({0});", m_flags & e_autoSleepFlag);
+ System.Diagnostics.Debug.WriteLine(" bd.awake = bool({0});", m_flags & e_awakeFlag);
+ System.Diagnostics.Debug.WriteLine(" bd.fixedRotation = bool({0});", m_flags & e_fixedRotationFlag);
+ System.Diagnostics.Debug.WriteLine(" bd.bullet = bool({0});", m_flags & e_bulletFlag);
+ System.Diagnostics.Debug.WriteLine(" bd.active = bool({0});", m_flags & e_activeFlag);
+ System.Diagnostics.Debug.WriteLine(" bd.gravityScale = {0:N5};", m_gravityScale);
+ System.Diagnostics.Debug.WriteLine(" bodies[{0}] = m_world.CreateBody(&bd);", m_islandIndex);
+ System.Diagnostics.Debug.WriteLine("");
+ for (b2Fixture f = m_fixtureList; f != null; f = f.Next)
+ {
+ System.Diagnostics.Debug.WriteLine(" {");
+ f.Dump(bodyIndex);
+ System.Diagnostics.Debug.WriteLine(" }");
+ }
+ System.Diagnostics.Debug.WriteLine("}");
+}
+}
}
View
347 external/Box2D/box2d/Dynamics/b2Fixture.cs
@@ -0,0 +1,347 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Box2D.Collision.Shapes;
+using Box2D.Collision;
+using Box2D.Common;
+
+namespace Box2D.Dynamics
+{
+ /// This holds contact filtering data.
+ public struct b2Filter
+ {
+ public b2Filter(ushort cat, ushort mask, int group)
+ {
+ categoryBits = cat;
+ maskBits = mask;
+ groupIndex = group;
+ }
+
+ /// The collision category bits. Normally you would just set one bit.
+ public ushort categoryBits;
+
+ /// The collision mask bits. This states the categories that this
+ /// shape would accept for collision.
+ public ushort maskBits;
+
+ /// Collision groups allow a certain group of objects to never collide (negative)
+ /// or always collide (positive). Zero means no collision group. Non-zero group
+ /// filtering always wins against the mask bits.
+ public int groupIndex;
+
+ public static b2Filter Default = new b2Filter()
+ {
+ categoryBits = 0x0001,
+ maskBits = 0xFFFF,
+ groupIndex = 0
+ };
+ }
+
+ public class b2Fixture
+ {
+ private float m_density;
+ public float Density
+ {
+ get { return (m_density); }
+ set { m_density = value; }
+ }
+ private b2Fixture m_next;
+ public b2Fixture Next
+ {
+ get { return (m_next); }
+ set { m_next = value; }
+ }
+ private b2Body m_body;
+ public b2Body Body
+ {
+ get { return (m_body); }
+ set { m_body = value; }
+ }
+ private b2Shape m_shape;
+ public b2Shape Shape
+ {
+ get { return (m_shape); }
+ set { m_shape = value; }
+ }
+ public b2ShapeType ShapeType
+ {
+ get { return (m_shape.GetShapeType()); }
+ }
+ private float m_friction;
+ public float Friction
+ {
+ get { return (m_friction); }
+ set { m_friction = value; }
+ }
+ private float m_restitution;
+ public float Restitution
+ {
+ get { return (m_restitution); }
+ set { m_restitution = value; }
+ }
+
+ private List<b2FixtureProxy> m_proxies = new List<b2FixtureProxy>();
+ public IList<b2FixtureProxy> Proxies
+ {
+ get
+ {
+ return (m_proxies);
+ }
+ }
+ private int m_proxyCount;
+ public int ProxyCount
+ {
+ get { return (m_proxies.Count); }
+ }
+ private b2Filter m_filter;
+ public b2Filter Filter
+ {
+ get { return (m_filter); }
+ set { m_filter = value; Refilter(); }
+ }
+ private bool m_isSensor;
+ public bool IsSensor
+ {
+ get { return (m_isSensor); }
+ set
+ {
+ if (value != m_isSensor)
+ {
+ m_body.SetAwake(true);
+ m_isSensor = value;
+ }
+ }
+ }
+
+ object m_userData;
+ public object UserData
+ {
+ get { return (m_userData); }
+ set { m_userData = value; }
+ }
+ public virtual bool TestPoint(b2Vec2 p)
+ {
+ return m_shape.TestPoint(m_body.Transform, p);
+ }
+
+ public virtual bool RayCast(out b2RayCastOutput output, b2RayCastInput input, int childIndex)
+ {
+ return m_shape.RayCast(out output, input, m_body.Transform, childIndex);
+ }
+
+ public virtual b2MassData GetMassData()
+ {
+ b2MassData data;
+ data = m_shape.ComputeMass(m_density);
+ return (data);
+ }
+
+ public virtual b2AABB GetAABB(int childIndex)
+ {
+ return m_proxies[childIndex].aabb;
+ }
+
+ public void Create(b2Body body, b2FixtureDef def)
+ {
+ m_userData = def.userData;
+ m_friction = def.friction;
+ m_restitution = def.restitution;
+
+ m_body = body;
+ m_next = null;
+
+ m_filter = def.filter;
+
+ m_isSensor = def.isSensor;
+
+ m_shape = def.shape.Clone();
+
+ // Reserve proxy space
+ int childCount = m_shape.GetChildCount();
+ for (int i = 0; i < childCount; ++i)
+ {
+ b2FixtureProxy proxy = new b2FixtureProxy();
+ proxy.fixture = null;
+ proxy.proxyId = b2BroadPhase.e_nullProxy;
+ m_proxies.Add(proxy);
+ }
+ m_proxyCount = 0;
+
+ m_density = def.density;
+ }
+
+ public virtual void Destroy()
+ {
+ m_proxies = null;
+ m_shape = null;
+ }
+
+ public virtual void CreateProxies(b2BroadPhase broadPhase, b2Transform xf)
+ {
+ // Create proxies in the broad-phase.
+ m_proxyCount = m_shape.GetChildCount();
+
+ for (int i = 0; i < m_proxyCount; ++i)
+ {
+ b2FixtureProxy proxy = m_proxies[i];
+ proxy.aabb = m_shape.ComputeAABB(xf, i);
+ proxy.proxyId = broadPhase.CreateProxy(proxy.aabb, proxy);
+ proxy.fixture = this;
+ proxy.childIndex = i;
+ }
+ }
+ public virtual void DestroyProxies(b2BroadPhase broadPhase)
+ {
+ // Destroy proxies in the broad-phase.
+ for (int i = 0; i < m_proxyCount; ++i)
+ {
+ b2FixtureProxy proxy = m_proxies[i];
+ broadPhase.DestroyProxy(proxy.proxyId);
+ proxy.proxyId = b2BroadPhase.e_nullProxy;
+ }
+ m_proxies.Clear();
+ m_proxyCount = 0;
+ }
+ public virtual void Synchronize(b2BroadPhase broadPhase, b2Transform transform1, b2Transform transform2)
+ {
+ if (m_proxyCount == 0)
+ {
+ return;
+ }
+
+ for (int i = 0; i < m_proxyCount; ++i)
+ {
+ b2FixtureProxy proxy = m_proxies[i];
+
+ // Compute an AABB that covers the swept shape (may miss some rotation effect).
+ b2AABB aabb1, aabb2;
+ aabb1 = m_shape.ComputeAABB(transform1, proxy.childIndex);
+ aabb2 = m_shape.ComputeAABB(transform2, proxy.childIndex);
+
+ proxy.aabb.Combine(aabb1, aabb2);
+
+ b2Vec2 displacement = transform2.p - transform1.p;
+
+ broadPhase.MoveProxy(proxy.proxyId, proxy.aabb, displacement);
+ }
+ }
+ public virtual void SetFilterData(b2Filter filter)
+ {
+ m_filter = filter;
+
+ Refilter();
+ }
+ public virtual void Refilter()
+ {
+ if (m_body == null)
+ {
+ return;
+ }
+
+ // Flag associated contacts for filtering.
+ b2ContactEdge edge = m_body.ContactList;
+ while (edge != null)
+ {
+ b2Contact contact = edge.contact;
+ b2Fixture fixtureA = contact.GetFixtureA();
+ b2Fixture fixtureB = contact.GetFixtureB();
+ if (fixtureA == this || fixtureB == this)
+ {
+ contact.FlagForFiltering();
+ }
+
+ edge = edge.next;
+ }
+
+ b2World world = m_body.World;
+
+ if (world == null)
+ {
+ return;
+ }
+
+ // Touch each proxy so that new pairs may be created
+ b2BroadPhase broadPhase = world.ContactManager.BroadPhase;
+ for (int i = 0; i < m_proxyCount; ++i)
+ {
+ broadPhase.TouchProxy(m_proxies[i].proxyId);
+ }
+ }
+ public virtual void Dump(int bodyIndex)
+ {
+ System.Diagnostics.Debug.WriteLine(" b2FixtureDef fd;");
+ System.Diagnostics.Debug.WriteLine(" fd.friction = {0:N5};", m_friction);
+ System.Diagnostics.Debug.WriteLine(" fd.restitution = {0:N5};", m_restitution);
+ System.Diagnostics.Debug.WriteLine(" fd.density = {0:N5};", m_density);
+ System.Diagnostics.Debug.WriteLine(" fd.isSensor = bool({0});", m_isSensor);
+ System.Diagnostics.Debug.WriteLine(" fd.filter.categoryBits = uint16({0});", m_filter.categoryBits);
+ System.Diagnostics.Debug.WriteLine(" fd.filter.maskBits = uint16({0});", m_filter.maskBits);
+ System.Diagnostics.Debug.WriteLine(" fd.filter.groupIndex = int16({0});", m_filter.groupIndex);
+
+ switch (m_shape.ShapeType)
+ {
+ case b2ShapeType.e_circle:
+ {
+ b2CircleShape s = (b2CircleShape)m_shape;
+ System.Diagnostics.Debug.WriteLine(" b2CircleShape shape;");
+ System.Diagnostics.Debug.WriteLine(" shape.m_radius = {0:N5};", s.Radius);
+ System.Diagnostics.Debug.WriteLine(" shape.m_p.Set({0:N5}, {0:N5});", s.Position.x, s.Position.y);
+ }
+ break;
+
+ case b2ShapeType.e_edge:
+ {
+ b2EdgeShape s = (b2EdgeShape)m_shape;
+ System.Diagnostics.Debug.WriteLine(" b2EdgeShape shape;");
+ System.Diagnostics.Debug.WriteLine(" shape.m_radius = {0:N5};", s.Radius);
+ System.Diagnostics.Debug.WriteLine(" shape.m_vertex0.Set({0:N5}, {0:N5});", s.Vertex0.x, s.Vertex0.y);
+ System.Diagnostics.Debug.WriteLine(" shape.m_vertex1.Set({0:N5}, {0:N5});", s.Vertex1.x, s.Vertex1.y);
+ System.Diagnostics.Debug.WriteLine(" shape.m_vertex2.Set({0:N5}, {0:N5});", s.Vertex2.x, s.Vertex2.y);
+ System.Diagnostics.Debug.WriteLine(" shape.m_vertex3.Set({0:N5}, {0:N5});", s.Vertex3.x, s.Vertex3.y);
+ System.Diagnostics.Debug.WriteLine(" shape.m_hasVertex0 = bool({0});", s.HasVertex0);
+ System.Diagnostics.Debug.WriteLine(" shape.m_hasVertex3 = bool({0});", s.HasVertex3);
+ }
+ break;
+
+ case b2ShapeType.e_polygon:
+ {
+ b2PolygonShape s = (b2PolygonShape)m_shape;
+ System.Diagnostics.Debug.WriteLine(" b2PolygonShape shape;");
+ System.Diagnostics.Debug.WriteLine(" b2Vec2 vs[{0}];", b2Settings.b2_maxPolygonVertices);
+ for (int i = 0; i < s.GetVertexCount(); ++i)
+ {
+ System.Diagnostics.Debug.WriteLine(" vs[{0}].Set({0:N5}, {0:N5});", i, s.Vertices[i].x, s.Vertices[i].y);
+ }
+ System.Diagnostics.Debug.WriteLine(" shape.Set(vs, {0});", s.GetVertexCount());
+ }
+ break;
+
+ case b2ShapeType.e_chain:
+ {
+ b2ChainShape s = (b2ChainShape)m_shape;
+ System.Diagnostics.Debug.WriteLine(" b2ChainShape shape;");
+ System.Diagnostics.Debug.WriteLine(" b2Vec2 vs[{0}];", s.Count);
+ for (int i = 0; i < s.Count; ++i)
+ {
+ System.Diagnostics.Debug.WriteLine(" vs[{0}].Set({0:N5}, {0:N5});", i, s.Vertices[i].x, s.Vertices[i].y);
+ }
+ System.Diagnostics.Debug.WriteLine(" shape.CreateChain(vs, {0});", s.Count);
+ System.Diagnostics.Debug.WriteLine(" shape.m_prevVertex.Set({0:N5}, {0:N5});", s.PrevVertex.x, s.PrevVertex.y);
+ System.Diagnostics.Debug.WriteLine(" shape.m_nextVertex.Set({0:N5}, {0:N5});", s.NextVertex.x, s.NextVertex.y);
+ System.Diagnostics.Debug.WriteLine(" shape.m_hasPrevVertex = bool({0});", s.HasPrevVertex);
+ System.Diagnostics.Debug.WriteLine(" shape.m_hasNextVertex = bool({0});", s.HasNextVertex);
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ System.Diagnostics.Debug.WriteLine("");
+ System.Diagnostics.Debug.WriteLine(" fd.shape = &shape;");
+ System.Diagnostics.Debug.WriteLine("");
+ System.Diagnostics.Debug.WriteLine(" bodies[{0}].CreateFixture(&fd);", bodyIndex);
+ }
+ }
+}
View
59 external/Box2D/box2d/Dynamics/b2FixtureDef.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Box2D.Collision.Shapes;
+using Box2D.Collision;
+
+namespace Box2D.Dynamics
+{
+ /// This proxy is used internally to connect fixtures to the broad-phase.
+ public class b2FixtureProxy
+ {
+ public b2AABB aabb;
+ public b2Fixture fixture;
+ public int childIndex;
+ public int proxyId;
+ }
+
+ /// <summary>
+ /// A fixture definition is used to create a fixture. This class defines an
+ /// abstract fixture definition. You can reuse fixture definitions safely.
+ /// </summary>
+ public class b2FixtureDef
+ {
+ /// The constructor sets the default fixture definition values.
+ b2FixtureDef()
+ {
+ shape = null;
+ userData = null;
+ friction = 0.2f;
+ restitution = 0.0f;
+ density = 0.0f;
+ isSensor = false;
+ }
+
+ /// The shape, this must be set. The shape will be cloned, so you
+ /// can create the shape on the stack.
+ public b2Shape shape;
+
+ /// Use this to store application specific fixture data.
+ public object userData;
+
+ /// The friction coefficient, usually in the range [0,1].
+ public float friction;
+
+ /// The restitution (elasticity) usually in the range [0,1].
+ public float restitution;
+
+ /// The density, usually in kg/m^2.
+ public float density;
+
+ /// A sensor shape collects contact information but never generates a collision
+ /// response.
+ public bool isSensor;
+
+ /// Contact filtering data.
+ public b2Filter filter;
+ }
+}
View
55 external/Box2D/box2d/Dynamics/b2TimeStep.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Box2D.Common;
+
+namespace Box2D.Dynamics
+{
+ /// Profiling data. Times are in milliseconds.
+ public struct b2Profile
+ {
+ public float step;
+ public float collide;
+ public float solve;
+ public float solveInit;
+ public float solveVelocity;
+ public float solvePosition;
+ public float broadphase;
+ public float solveTOI;
+ }
+
+ /// This is an internal structure.
+ public struct b2TimeStep
+ {
+ public float dt; // time step
+ public float inv_dt; // inverse time step (0 if dt == 0).
+ public float dtRatio; // dt * inv_dt0
+ public int velocityIterations;
+ public int positionIterations;
+ public bool warmStarting;
+ }
+
+ /// This is an internal structure.
+ public struct b2Position
+ {
+ public b2Vec2 c;
+ public float a;
+ }
+
+ /// This is an internal structure.
+ public struct b2Velocity
+ {
+ public b2Vec2 v;
+ public float w;
+ }
+
+ /// Solver Data
+ public struct b2SolverData
+ {
+ public b2TimeStep step;
+ public b2Position[] positions;
+ public b2Velocity[] velocities;
+ }
+
+}
View
991 external/Box2D/box2d/Dynamics/b2World.cs
@@ -22,14 +22,14 @@ public class b2ContactImpulse
// m_flags
[Flags]
- enum b2WorldType : short
+ enum b2WorldFlags : short
{
e_newFixture = 0x1,
e_locked = 0x2,
e_clearForces = 0x4
};
- public abstract class b2World
+ public class b2World
{
private void Solve(b2TimeStep step);
@@ -38,18 +38,57 @@ public abstract class b2World
private void DrawJoint(b2Joint joint);
private void DrawShape(b2Fixture shape, b2Transform xf, b2Color color);
- private b2WorldType m_flags;
+ private b2WorldFlags m_flags;
+ public b2WorldFlags Flags
+ {
+ get { return (m_flags); }
+ set { m_flags = value; }
+ }
private b2ContactManager m_contactManager;
+ public b2ContactManager ContactManager
+ {
+ get { return (m_contactManager); }
+ set { m_contactManager = value; }
+ }
private b2Body m_bodyList;
+ public b2Body BodyList
+ {
+ get { return (m_bodyList); }
+ set { m_bodyList = value; }
+ }
private b2Joint m_jointList;
+ public b2Joint JointList
+ {
+ get { return (m_jointList); }
+ set { m_jointList = value; }
+ }
private int m_bodyCount;
+ public int BodyCount
+ {
+ get { return (m_bodyCount); }
+ set { m_bodyCount = value; }
+ }
private int m_jointCount;
-
+ public int JointCount
+ {
+ get { return (m_jointCount); }
+ set { m_jointCount = value; }
+ }
private b2Vec2 m_gravity;
+ public b2Vec2 Gravity
+ {
+ get { return (m_gravity); }
+ set { m_gravity = value; }
+ }
private bool m_allowSleep;
+ public bool AllowSleep
+ {
+ get { return (m_allowSleep); }
+ set { m_allowSleep = value; }
+ }
private b2DestructionListener m_destructionListener;
private b2Draw m_debugDraw;
@@ -66,6 +105,11 @@ public abstract class b2World
private bool m_stepComplete;
private b2Profile m_profile;
+ public b2Profile Profile
+ {
+ get { return (m_profile); }
+ set { m_profile = value; }
+ }
public b2World(b2Vec2 gravity)
{
@@ -87,7 +131,7 @@ public b2World(b2Vec2 gravity)
m_allowSleep = true;
m_gravity = gravity;
- m_flags = b2WorldType.e_clearForces;
+ m_flags = b2WorldFlags.e_clearForces;
m_inv_dt0 = 0.0f;
}
@@ -137,11 +181,11 @@ public b2Body CreateBody(b2BodyDef def)
b2Body b = new b2Body(def, this);
// Add to world doubly linked list.
- b.m_prev = null;
- b.m_next = m_bodyList;
- if (m_bodyList)
+ b.Prev = null;
+ b.Next = m_bodyList;
+ if (m_bodyList != null)
{
- m_bodyList.m_prev = b;
+ m_bodyList.Prev = b;
}
m_bodyList = b;
++m_bodyCount;
@@ -157,7 +201,7 @@ public void DestroyBody(b2Body b)
}
// Delete the attached joints.
- b2JointEdge je = b.m_jointList;
+ b2JointEdge je = b.JointList;
while (je)
{
b2JointEdge je0 = je;
@@ -170,26 +214,26 @@ public void DestroyBody(b2Body b)
DestroyJoint(je0.joint);
- b.m_jointList = je;
+ b.JointList = je;
}
- b.m_jointList = null;
+ b.JointList = null;
// Delete the attached contacts.
- b2ContactEdge ce = b.m_contactList;
+ b2ContactEdge ce = b.ContactList;
while (ce)
{
b2ContactEdge ce0 = ce;
ce = ce.next;
m_contactManager.Destroy(ce0.contact);
}
- b.m_contactList = null;
+ b.ContactList = null;
// Delete the attached fixtures. This destroys broad-phase proxies.
- b2Fixture f = b.m_fixtureList;
- while (f)
+ b2Fixture f = b.FixtureList;
+ while (f != null)
{
b2Fixture f0 = f;
- f = f.m_next;
+ f = f.Next;
if (m_destructionListener != null)
{
@@ -198,26 +242,26 @@ public void DestroyBody(b2Body b)
f0.DestroyProxies(m_contactManager.BroadPhase);
- b.m_fixtureList = f;
- b.m_fixtureCount -= 1;
+ b.FixtureList = f;
+ b.FixtureCount -= 1;
}
- b.m_fixtureList = null;
- b.m_fixtureCount = 0;
+ b.FixtureList = null;
+ b.FixtureCount = 0;
// Remove world body list.
- if (b.m_prev)
+ if (b.Prev != null)
{
- b.m_prev.m_next = b.m_next;
+ b.Prev.Next = b.Next;
}
- if (b.m_next)
+ if (b.Next != null)
{
- b.m_next.m_prev = b.m_prev;
+ b.Next.Prev = b.Prev;
}
if (b == m_bodyList)
{
- m_bodyList = b.m_next;
+ m_bodyList = b.Next;
}
--m_bodyCount;
@@ -233,11 +277,11 @@ public b2Joint CreateJoint(b2JointDef def)
b2Joint j = b2Joint.Create(def);
// Connect to the world list.
- j.m_prev = null;
- j.m_next = m_jointList;
+ j.Prev = null;
+ j.Next = m_jointList;
if (m_jointList)
{
- m_jointList.m_prev = j;
+ m_jointList.Prev = j;
}
m_jointList = j;
++m_jointCount;
@@ -246,24 +290,24 @@ public b2Joint CreateJoint(b2JointDef def)
j.m_edgeA.joint = j;
j.m_edgeA.other = j.m_bodyB;
j.m_edgeA.prev = null;
- j.m_edgeA.next = j.m_bodyA.m_jointList;
- if (j.m_bodyA.m_jointList) j.m_bodyA.m_jointList.prev = &j.m_edgeA;
- j.m_bodyA.m_jointList = &j.m_edgeA;
+ j.m_edgeA.next = j.m_bodyA.JointList;
+ if (j.m_bodyA.JointList) j.m_bodyA.JointList.prev = &j.m_edgeA;
+ j.m_bodyA.JointList = &j.m_edgeA;
j.m_edgeB.joint = j;
j.m_edgeB.other = j.m_bodyA;
j.m_edgeB.prev = null;
- j.m_edgeB.next = j.m_bodyB.m_jointList;
- if (j.m_bodyB.m_jointList) j.m_bodyB.m_jointList.prev = &j.m_edgeB;
- j.m_bodyB.m_jointList = &j.m_edgeB;
+ j.m_edgeB.next = j.m_bodyB.JointList;
+ if (j.m_bodyB.JointList) j.m_bodyB.JointList.prev = &j.m_edgeB;
+ j.m_bodyB.JointList = &j.m_edgeB;
b2Body bodyA = def.bodyA;
b2Body bodyB = def.bodyB;
// If the joint prevents collisions, then flag any contacts for filtering.
if (def.collideConnected == false)
{
- b2ContactEdge edge = bodyB.GetContactList();
+ b2ContactEdge edge = bodyB.ContactList;
while (edge != null)
{
if (edge.other == bodyA)
@@ -292,19 +336,19 @@ public void DestroyJoint(b2Joint j)
bool collideConnected = j.m_collideConnected;
// Remove from the doubly linked list.
- if (j.m_prev)
+ if (j.Prev)
{
- j.m_prev.m_next = j.m_next;
+ j.Prev.Next = j.Next;
}
- if (j.m_next)
+ if (j.Next)
{
- j.m_next.m_prev = j.m_prev;
+ j.Next.Prev = j.Prev;
}
if (j == m_jointList)
{
- m_jointList = j.m_next;
+ m_jointList = j.Next;
}
// Disconnect from island graph.
@@ -326,9 +370,9 @@ public void DestroyJoint(b2Joint j)
j.m_edgeA.next.prev = j.m_edgeA.prev;
}
- if (&j.m_edgeA == bodyA.m_jointList)
+ if (j.m_edgeA == bodyA.JointList)
{
- bodyA.m_jointList = j.m_edgeA.next;
+ bodyA.JointList = j.m_edgeA.next;
}
j.m_edgeA.prev = null;
@@ -345,9 +389,9 @@ public void DestroyJoint(b2Joint j)
j.m_edgeB.next.prev = j.m_edgeB.prev;
}
- if (&j.m_edgeB == bodyB.m_jointList)
+ if (j.m_edgeB == bodyB.JointList)
{
- bodyB.m_jointList = j.m_edgeB.next;
+ bodyB.JointList = j.m_edgeB.next;
}
j.m_edgeB.prev = null;
@@ -360,7 +404,7 @@ public void DestroyJoint(b2Joint j)
// If the joint prevents collisions, then flag any contacts for filtering.
if (collideConnected == false)
{
- b2ContactEdge edge = bodyB.GetContactList();
+ b2ContactEdge edge = bodyB.ContactList;
while (edge != null)
{
if (edge.other == bodyA)
@@ -386,7 +430,7 @@ public void SetAllowSleeping(bool flag)
m_allowSleep = flag;
if (m_allowSleep == false)
{
- for (b2Body b = m_bodyList; b != null; b = b.m_next)
+ for (b2Body b = m_bodyList; b != null; b = b.Next)
{
b.SetAwake(true);
}
@@ -407,25 +451,25 @@ public void Solve(b2TimeStep step)
m_contactManager.ContactListener);
// Clear all the island flags.
- for (b2Body b = m_bodyList; b; b = b.m_next)
+ for (b2Body b = m_bodyList; b != null; b = b.Next)
{
- b.m_flags &= ~b2Body.e_islandFlag;
+ b.BodyFlags &= ~b2BodyFlags.e_islandFlag;
}
- for (b2Contact c = m_contactManager.m_contactList; c; c = c.m_next)
+ for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
{
- c.m_flags &= ~b2Contact.e_islandFlag;
+ c.ContactFlags &= ~b2ContactFlags.e_islandFlag;
}
- for (b2Joint j = m_jointList; j; j = j.m_next)
+ for (b2Joint j = m_jointList; j; j = j.Next)
{
j.m_islandFlag = false;
}
// Build and simulate all awake islands.
int stackSize = m_bodyCount;
b2Body[] stack = new b2Body[stackSize];
- for (b2Body seed = m_bodyList; seed; seed = seed.m_next)
+ for (b2Body seed = m_bodyList; seed != null; seed = seed.Next)
{
- if (seed.m_flags & b2BodyType.e_islandFlag)
+ if (seed.BodyFlags & b2BodyFlags.e_islandFlag)
{
continue;
}
@@ -436,7 +480,7 @@ public void Solve(b2TimeStep step)
}
// The seed can be dynamic or kinematic.
- if (seed.GetBodyType() == b2BodyType.b2_staticBody)
+ if (seed.BodyType == b2BodyType.b2_staticBody)
{
continue;
}
@@ -445,7 +489,7 @@ public void Solve(b2TimeStep step)
island.Clear();
int stackCount = 0;
stack[stackCount++] = seed;
- seed.m_flags |= b2BodyType.e_islandFlag;
+ seed.BodyFlags |= b2BodyFlags.e_islandFlag;
// Perform a depth first search (DFS) on theraint graph.
while (stackCount > 0)
@@ -459,18 +503,18 @@ public void Solve(b2TimeStep step)
// To keep islands as small as possible, we don't
// propagate islands across static bodies.
- if (b.GetBodyType() == b2BodyType.b2_staticBody)
+ if (b.BodyType == b2BodyType.b2_staticBody)
{
continue;
}
// Search all contacts connected to this body.
- for (b2ContactEdge ce = b.m_contactList; ce; ce = ce.next)
+ for (b2ContactEdge ce = b.ContactList; ce != null; ce = ce.next)
{
b2Contact contact = ce.contact;
// Has this contact already been added to an island?
- if (contact.m_flags & b2ContactType.e_islandFlag)
+ if (contact.ContactFlags & b2ContactFlags.e_islandFlag)
{
continue;
}
@@ -491,22 +535,22 @@ public void Solve(b2TimeStep step)
}
island.Add(contact);
- contact.m_flags |= b2ContactType.e_islandFlag;
+ contact.ContactFlags |= b2ContactType.e_islandFlag;
b2Body other = ce.other;
// Was the other body already added to this island?
- if (other.m_flags & b2Body.e_islandFlag)
+ if ((other.BodyFlags & b2BodyFlags.e_islandFlag) > 0)
{
continue;
}
stack[stackCount++] = other;
- other.m_flags |= b2BodyType.e_islandFlag;
+ other.BodyFlags |= b2BodyFlags.e_islandFlag;
}
// Search all joints connect to this body.
- for (b2JointEdge je = b.FirstJoint; je; je = je.next)
+ for (b2JointEdge je = b.JointList; je; je = je.next)
{
if (je.joint.IslandFlag == true)
{
@@ -524,13 +568,13 @@ public void Solve(b2TimeStep step)
island.Add(je.joint);
je.joint.m_islandFlag = true;
- if (other.m_flags & b2BodyType.e_islandFlag)
+ if ((other.BodyFlags & b2BodyFlags.e_islandFlag) > 0)
{
continue;
}
stack[stackCount++] = other;
- other.m_flags |= b2BodyType.e_islandFlag;
+ other.BodyFlags |= b2BodyFlags.e_islandFlag;
}
}
@@ -544,20 +588,20 @@ public void Solve(b2TimeStep step)
{
// Allow static bodies to participate in other islands.
b2Body b = island.m_bodies[i];
- if (b.GetType() == b2BodyType.b2_staticBody)
+ if (b.BodyType == b2BodyType.b2_staticBody)
{
- b.m_flags &= ~b2BodyType.e_islandFlag;
+ b.BodyFlags &= ~b2BodyFlags.e_islandFlag;
}
}
}
{
b2Timer timer;
// Synchronize fixtures, check for out of range bodies.
- for (b2Body b = m_bodyList; b; b = b.GetNext())
+ for (b2Body b = m_bodyList; b != null; b = b.Next)
{
// If a body was not in an island then it did not move.
- if ((b.m_flags & b2BodyType.e_islandFlag) == 0)
+ if ((b.BodyFlags & b2BodyType.e_islandFlag) == 0)
{
continue;
}
@@ -578,335 +622,335 @@ public void Solve(b2TimeStep step)
}
// Find TOI contacts and solve them.
- public void SolveTOI(b2TimeStep step)
-{
- b2Island island = new b2Island(2 * b2Settings.b2_maxTOIContacts, b2Settings.b2_maxTOIContacts, 0, m_contactManager.ContactListener);
-
- if (m_stepComplete)
- {
- for (b2Body b = m_bodyList; b; b = b.m_next)
- {
- b.m_flags &= ~b2Body.e_islandFlag;
- b.m_sweep.alpha0 = 0.0f;
- }
-
- for (b2Contact c = m_contactManager.ContactList; c; c = c.m_next)
- {
- // Invalidate TOI
- c.m_flags &= ~(b2ContactType.e_toiFlag | b2ContactType.e_islandFlag);
- c.m_toiCount = 0;
- c.m_toi = 1.0f;
- }
- }
-
- // Find TOI events and solve them.
- for (;;)
- {
- // Find the first TOI.
- b2Contact minContact = null;
- float minAlpha = 1.0f;
-
- for (b2Contact c = m_contactManager.ContactList; c != null; c = c.m_next)
- {
- // Is this contact disabled?
- if (c.IsEnabled() == false)
- {
- continue;
- }
-
- // Prevent excessive sub-stepping.
- if (c.m_toiCount > b2Settings.b2_maxSubSteps)
- {
- continue;
- }
-
- float alpha = 1.0f;
- if (c.m_flags & b2ContactType.e_toiFlag)
- {
- // This contact has a valid cached TOI.
- alpha = c.m_toi;
- }
- else
- {
- b2Fixture fA = c.GetFixtureA();
- b2Fixture fB = c.GetFixtureB();
-
- // Is there a sensor?
- if (fA.IsSensor() || fB.IsSensor())
- {
- continue;
- }
-
- b2Body bA = fA.GetBody();
- b2Body bB = fB.GetBody();
-
- b2BodyType typeA = bA.m_type;
- b2BodyType typeB = bB.m_type;
- b2Assert(typeA == b2BodyType.b2_dynamicBody || typeB == b2BodyType.b2_dynamicBody);
-
- bool activeA = bA.IsAwake() && typeA != b2BodyType.b2_staticBody;
- bool activeB = bB.IsAwake() && typeB != b2BodyType.b2_staticBody;
-
- // Is at least one body active (awake and dynamic or kinematic)?
- if (activeA == false && activeB == false)
- {
- continue;
- }
-
- bool collideA = bA.IsBullet() || typeA != b2BodyType.b2_dynamicBody;
- bool collideB = bB.IsBullet() || typeB != b2BodyType.b2_dynamicBody;
-
- // Are these two non-bullet dynamic bodies?
- if (collideA == false && collideB == false)
- {
- continue;
- }
-
- // Compute the TOI for this contact.
- // Put the sweeps onto the same time interval.
- float alpha0 = bA.m_sweep.alpha0;
-
- if (bA.m_sweep.alpha0 < bB.m_sweep.alpha0)
- {
- alpha0 = bB.m_sweep.alpha0;
- bA.m_sweep.Advance(alpha0);
- }
- else if (bB.m_sweep.alpha0 < bA.m_sweep.alpha0)
- {
- alpha0 = bA.m_sweep.alpha0;
- bB.m_sweep.Advance(alpha0);
- }
-
- int indexA = c.GetChildIndexA();
- int indexB = c.GetChildIndexB();
-
- // Compute the time of impact in interval [0, minTOI]
- b2TOIInput input = new b2TOIInput();
- input.proxyA.Set(fA.GetShape(), indexA);
- input.proxyB.Set(fB.GetShape(), indexB);
- input.sweepA = bA.m_sweep;
- input.sweepB = bB.m_sweep;
- input.tMax = 1.0f;
-
- b2TOIOutput output = b2TimeOfImpact(input);
-
- // Beta is the fraction of the remaining portion of the .
- float beta = output.t;
- if (output.state == b2TOIOutputType.e_touching)
- {
- alpha = b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
- }
- else
- {
- alpha = 1.0f;
- }
-
- c.m_toi = alpha;
- c.m_flags |= b2ContactType.e_toiFlag;
- }
-
- if (alpha < minAlpha)
- {
- // This is the minimum TOI found so far.
- minContact = c;
- minAlpha = alpha;
- }
- }
-
- if (minContact == null || 1.0f - 10.0f * b2Settings.b2_epsilon < minAlpha)
- {
- // No more TOI events. Done!
- m_stepComplete = true;
- break;
- }
-
- // Advance the bodies to the TOI.
- b2Fixture fA = minContact.GetFixtureA();
- b2Fixture fB = minContact.GetFixtureB();
- b2Body bA = fA.GetBody();
- b2Body bB = fB.GetBody();
-
- b2Sweep backup1 = bA.m_sweep;
- b2Sweep backup2 = bB.m_sweep;
-
- bA.Advance(minAlpha);
- bB.Advance(minAlpha);
-
- // The TOI contact likely has some new contact points.
- minContact.Update(m_contactManager.ContactListener);
- minContact.m_flags &= ~b2ContactType.e_toiFlag;
- ++minContact.m_toiCount;
-
- // Is the contact solid?
- if (minContact.IsEnabled() == false || minContact.IsTouching() == false)
- {
- // Restore the sweeps.
- minContact.SetEnabled(false);
- bA.m_sweep = backup1;
- bB.m_sweep = backup2;
- bA.SynchronizeTransform();
- bB.SynchronizeTransform();
- continue;
- }
-
- bA.SetAwake(true);
- bB.SetAwake(true);
-
- // Build the island
- island.Clear();
- island.Add(bA);
- island.Add(bB);
- island.Add(minContact);
-
- bA.BodyType |= b2BodyType.e_islandFlag;
- bB.BodyType |= b2BodyType.e_islandFlag;
- minContact.ContentType |= b2ContactType.e_islandFlag;
-
- // Get contacts on bodyA and bodyB.
- b2Body[] bodies = new b2Body[] {bA, bB};
- for (int i = 0; i < 2; ++i)
- {
- b2Body body = bodies[i];
- if (body.m_type == b2BodyType.b2_dynamicBody)
- {
- for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
- {
- if (island.BodyCount == island.BodyCapacity)
- {
- break;
- }
-
- if (island.ContactCount == island.ContactCapacity)
- {
- break;
- }
-
- b2Contact contact = ce.contact;
-
- // Has this contact already been added to the island?
- if (contact.ContactType & b2ContactType.e_islandFlag)
- {
- continue;
- }
-
- // Only add static, kinematic, or bullet bodies.
- b2Body other = ce.other;
- if (other.m_type == b2_dynamicBody &&
- body.IsBullet() == false && other.IsBullet() == false)
- {
- continue;
- }
-
- // Skip sensors.
- bool sensorA = contact.m_fixtureA.m_isSensor;
- bool sensorB = contact.m_fixtureB.m_isSensor;
- if (sensorA || sensorB)
- {
- continue;
- }
-
- // Tentatively advance the body to the TOI.
- b2Sweep backup = other.m_sweep;
- if ((other.m_flags & b2Body.e_islandFlag) == 0)
- {
- other.Advance(minAlpha);
- }
-
- // Update the contact points
- contact.Update(m_contactManager.m_contactListener);
-
- // Was the contact disabled by the user?
- if (contact.IsEnabled() == false)
- {
- other.m_sweep = backup;
- other.SynchronizeTransform();
- continue;
- }
-
- // Are there contact points?
- if (contact.IsTouching() == false)
- {
- other.m_sweep = backup;
- other.SynchronizeTransform();
- continue;
- }
-
- // Add the contact to the island
- contact.m_flags |= b2Contact.e_islandFlag;
- island.Add(contact);
-
- // Has the other body already been added to the island?
- if (other.m_flags & b2Body.e_islandFlag)
- {
- continue;
- }
-
- // Add the other body to the island.
- other.m_flags |= b2Body.e_islandFlag;
-
- if (other.m_type != b2_staticBody)
- {
- other.SetAwake(true);
- }
-
- island.Add(other);
- }
- }
- }
-
- b2TimeStep subStep;
- subStep.dt = (1.0f - minAlpha) * step.dt;
- subStep.inv_dt = 1.0f / subStep.dt;
- subStep.dtRatio = 1.0f;
- subStep.positionIterations = 20;
- subStep.velocityIterations = step.velocityIterations;
- subStep.warmStarting = false;
- island.SolveTOI(subStep, bA.m_islandIndex, bB.m_islandIndex);
-
- // Reset island flags and synchronize broad-phase proxies.
- for (int i = 0; i < island.m_bodyCount; ++i)
- {
- b2Body body = island.m_bodies[i];
- body.m_flags &= ~b2Body.e_islandFlag;
-
- if (body.m_type != b2_dynamicBody)
- {
- continue;
- }
-
- body.SynchronizeFixtures();
-
- // Invalidate all contact TOIs on this displaced body.
- for (b2ContactEdge* ce = body.m_contactList; ce; ce = ce.next)
- {
- ce.contact.m_flags &= ~(b2Contact.e_toiFlag | b2Contact.e_islandFlag);
- }
- }
-
- // Commit fixture proxy movements to the broad-phase so that new contacts are created.
- // Also, some contacts can be destroyed.
- m_contactManager.FindNewContacts();
-
- if (m_subStepping)
- {
- m_stepComplete = false;
- break;
- }
- }
-}
+ public void SolveTOI(b2TimeStep step)
+ {
+ b2Island island = new b2Island(2 * b2Settings.b2_maxTOIContacts, b2Settings.b2_maxTOIContacts, 0, m_contactManager.ContactListener);
+
+ if (m_stepComplete)
+ {
+ for (b2Body b = m_bodyList; b; b = b.Next)
+ {
+ b.BodyFlags &= ~b2Body.e_islandFlag;
+ b.m_sweep.alpha0 = 0.0f;
+ }
+
+ for (b2Contact c = m_contactManager.ContactList; c; c = c.Next)
+ {
+ // Invalidate TOI
+ c.ContactFlags &= ~(b2ContactType.e_toiFlag | b2ContactType.e_islandFlag);
+ c.m_toiCount = 0;
+ c.m_toi = 1.0f;
+ }
+ }
+
+ // Find TOI events and solve them.
+ for (; ; )
+ {
+ // Find the first TOI.
+ b2Contact minContact = null;
+ float minAlpha = 1.0f;
+
+ for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next)
+ {
+ // Is this contact disabled?
+ if (c.IsEnabled() == false)
+ {
+ continue;
+ }
+
+ // Prevent excessive sub-stepping.
+ if (c.m_toiCount > b2Settings.b2_maxSubSteps)
+ {
+ continue;
+ }
+
+ float alpha = 1.0f;
+ if (c.ContactFlags.HasFlag(b2ContactFlags.e_toiFlag))
+ {
+ // This contact has a valid cached TOI.
+ alpha = c.m_toi;
+ }
+ else
+ {
+ b2Fixture fA = c.GetFixtureA();
+ b2Fixture fB = c.GetFixtureB();
+
+ // Is there a sensor?
+ if (fA.IsSensor || fB.IsSensor)
+ {
+ continue;
+ }
+
+ b2Body bA = fA.Body;
+ b2Body bB = fB.Body;
+
+ b2BodyType typeA = bA.BodyType;
+ b2BodyType typeB = bB.BodyType;
+
+ bool activeA = bA.IsAwake() && typeA != b2BodyType.b2_staticBody;
+ bool activeB = bB.IsAwake() && typeB != b2BodyType.b2_staticBody;
+
+ // Is at least one body active (awake and dynamic or kinematic)?
+ if (activeA == false && activeB == false)
+ {
+ continue;
+ }
+
+ bool collideA = bA.IsBullet() || typeA != b2BodyType.b2_dynamicBody;
+ bool collideB = bB.IsBullet() || typeB != b2BodyType.b2_dynamicBody;
+
+ // Are these two non-bullet dynamic bodies?
+ if (collideA == false && collideB == false)
+ {
+ continue;
+ }
+
+ // Compute the TOI for this contact.
+ // Put the sweeps onto the same time interval.
+ float alpha0 = bA.Sweep.alpha0;
+
+ if (bA.Sweep.alpha0 < bB.Sweep.alpha0)
+ {
+ alpha0 = bB.Sweep.alpha0;
+ bA.Sweep.Advance(alpha0);
+ }
+ else if (bB.Sweep.alpha0 < bA.Sweep.alpha0)
+ {
+ alpha0 = bA.Sweep.alpha0;
+ bB.Sweep.Advance(alpha0);
+ }
+
+ int indexA = c.GetChildIndexA();
+ int indexB = c.GetChildIndexB();
+
+ // Compute the time of impact in interval [0, minTOI]
+ b2TOIInput input = new b2TOIInput();
+ input.proxyA.Set(fA.Shape, indexA);
+ input.proxyB.Set(fB.Shape, indexB);
+ input.sweepA = bA.Sweep;
+ input.sweepB = bB.Sweep;
+ input.tMax = 1.0f;
+
+ b2TOIOutput output = b2TimeOfImpact(input);
+
+ // Beta is the fraction of the remaining portion of the .
+ float beta = output.t;
+ if (output.state == b2TOIOutputType.e_touching)
+ {
+ alpha = b2Math.b2Min(alpha0 + (1.0f - alpha0) * beta, 1.0f);
+ }
+ else
+ {
+ alpha = 1.0f;
+ }
+
+ c.m_toi = alpha;
+ c.ContactFlags |= b2ContactFlags.e_toiFlag;
+ }
+
+ if (alpha < minAlpha)
+ {
+ // This is the minimum TOI found so far.
+ minContact = c;
+ minAlpha = alpha;
+ }
+ }
+
+ if (minContact == null || 1.0f - 10.0f * b2Settings.b2_epsilon < minAlpha)
+ {
+ // No more TOI events. Done!
+ m_stepComplete = true;
+ break;
+ }
+ {
+ // Advance the bodies to the TOI.
+ b2Fixture fA = minContact.GetFixtureA();
+ b2Fixture fB = minContact.GetFixtureB();
+ b2Body bA = fA.Body;
+ b2Body bB = fB.Body;
+
+ b2Sweep backup1 = bA.Sweep;
+ b2Sweep backup2 = bB.Sweep;
+
+ bA.Advance(minAlpha);
+ bB.Advance(minAlpha);
+
+ // The TOI contact likely has some new contact points.
+ minContact.Update(m_contactManager.ContactListener);
+ minContact.ContactFlags &= ~b2ContactFlags.e_toiFlag;
+ ++minContact.m_toiCount;
+
+ // Is the contact solid?
+ if (minContact.IsEnabled() == false || minContact.IsTouching() == false)
+ {
+ // Restore the sweeps.
+ minContact.SetEnabled(false);
+ bA.Sweep = backup1;
+ bB.Sweep = backup2;
+ bA.SynchronizeTransform();
+ bB.SynchronizeTransform();
+ continue;
+ }
+
+ bA.SetAwake(true);
+ bB.SetAwake(true);
+
+ // Build the island
+ island.Clear();
+ island.Add(bA);
+ island.Add(bB);
+ island.Add(minContact);
+
+ bA.BodyFlags |= b2BodyFlags.e_islandFlag;
+ bB.BodyFlags |= b2BodyFlags.e_islandFlag;
+ minContact.ContentType |= b2ContactFlags.e_islandFlag;
+
+ // Get contacts on bodyA and bodyB.
+ b2Body[] bodies = new b2Body[] { bA, bB };
+ for (int i = 0; i < 2; ++i)
+ {
+ b2Body body = bodies[i];
+ if (body.BodyType == b2BodyType.b2_dynamicBody)
+ {
+ for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
+ {
+ if (island.BodyCount == island.BodyCapacity)
+ {
+ break;
+ }
+
+ if (island.ContactCount == island.ContactCapacity)
+ {
+ break;
+ }
+
+ b2Contact contact = ce.contact;
+
+ // Has this contact already been added to the island?
+ if (contact.ContactType & b2ContactType.e_islandFlag)
+ {
+ continue;
+ }
+
+ // Only add static, kinematic, or bullet bodies.
+ b2Body other = ce.other;
+ if (other.BodyType == b2BodyType.b2_dynamicBody &&
+ body.IsBullet() == false && other.IsBullet() == false)
+ {
+ continue;
+ }
+
+ // Skip sensors.
+ bool sensorA = contact.m_fixtureA.m_isSensor;
+ bool sensorB = contact.m_fixtureB.m_isSensor;
+ if (sensorA || sensorB)
+ {
+ continue;
+ }
+
+ // Tentatively advance the body to the TOI.
+ b2Sweep backup = other.Sweep;
+ if (other.BodyFlags.HasFlag(b2BodyFlags.e_islandFlag))
+ {
+ other.Advance(minAlpha);
+ }
+
+ // Update the contact points
+ contact.Update(m_contactManager.ContactListener);
+
+ // Was the contact disabled by the user?
+ if (contact.IsEnabled() == false)
+ {
+ other.Sweep = backup;
+ other.SynchronizeTransform();
+ continue;
+ }
+
+ // Are there contact points?
+ if (contact.IsTouching() == false)
+ {
+ other.Sweep = backup;
+ other.SynchronizeTransform();
+ continue;
+ }
+
+ // Add the contact to the island
+ contact.ContactFlags |= b2ContactFlags.e_islandFlag;
+ island.Add(contact);
+
+ // Has the other body already been added to the island?
+ if (other.BodyFlags.HasFlag(b2BodyFlags.e_islandFlag))
+ {
+ continue;
+ }
+
+ // Add the other body to the island.
+ other.BodyFlags |= b2BodyFlags.e_islandFlag;
+
+ if (other.BodyType != b2BodyType.b2_staticBody)
+ {
+ other.SetAwake(true);
+ }
+
+ island.Add(other);
+ }
+ }
+ }
+
+ b2TimeStep subStep;
+ subStep.dt = (1.0f - minAlpha) * step.dt;
+ subStep.inv_dt = 1.0f / subStep.dt;
+ subStep.dtRatio = 1.0f;
+ subStep.positionIterations = 20;
+ subStep.velocityIterations = step.velocityIterations;
+ subStep.warmStarting = false;
+ island.SolveTOI(subStep, bA.m_islandIndex, bB.m_islandIndex);
+
+ // Reset island flags and synchronize broad-phase proxies.
+ for (int i = 0; i < island.m_bodyCount; ++i)
+ {
+ b2Body body = island.m_bodies[i];
+ body.BodyFlags &= ~b2BodyFlags.e_islandFlag;
+
+ if (body.BodyType != b2BodyType.b2_dynamicBody)
+ {
+ continue;
+ }
+
+ body.SynchronizeFixtures();
+
+ // Invalidate all contact TOIs on this displaced body.
+ for (b2ContactEdge ce = body.ContactList; ce != null; ce = ce.next)
+ {
+ ce.Contact.ContactFlags &= ~(b2ContactFlags.e_toiFlag | b2ContactFlags.e_islandFlag);
+ }
+ }
+
+ // Commit fixture proxy movements to the broad-phase so that new contacts are created.
+ // Also, some contacts can be destroyed.
+ m_contactManager.FindNewContacts();
+
+ if (m_subStepping)
+ {
+ m_stepComplete = false;
+ break;
+ }
+ }
+ }
+ }
public void Step(float dt, int velocityIterations, int positionIterations)
{
b2Timer stepTimer;
// If new fixtures were added, we need to find the new contacts.