public World(AABB worldAABB, Vec2 gravity, bool doSleep) { this._destructionListener = null; this._boundaryListener = null; this._contactFilter = WorldCallback.DefaultFilter; this._contactListener = null; this._debugDraw = null; this._bodyList = null; this._contactList = null; this._jointList = null; this._bodyCount = 0; this._contactCount = 0; this._jointCount = 0; this._warmStarting = true; this._continuousPhysics = true; this._allowSleep = doSleep; this._gravity = gravity; this._lock = false; this._inv_dt0 = 0f; this._contactManager = new ContactManager(); this._contactManager._world = this; this._broadPhase = new BroadPhase(worldAABB, this._contactManager); BodyDef def = new BodyDef(); this._groundBody = this.CreateBody(def); }
public void BeginContact(Contact contact) { if (contact.FixtureA.UserData is IEntity && contact.FixtureB.UserData is IEntity) { IEntity A = (IEntity)contact.FixtureA.UserData; IEntity B = (IEntity)contact.FixtureB.UserData; A.OnCollides(B); B.OnCollides(A); } }
public ContactManager() { _broadPhase = new BroadPhase(); _defaultFilter = new ContactFilter(); _defaultListener = new ContactListener(); _contactList = null; _contactCount = 0; _contactFilter = _defaultFilter; _contactListener = _defaultListener; }
void OnEndContact(Box2DX.Dynamics.Contact contact) { if ((contact.GetShape1().UserData is Actor) && (contact.GetShape2().UserData is Actor)) { (contact.GetShape1().UserData as Actor).OnEndContact((contact.GetShape2().UserData as Actor), contact.GetShape1(), contact.GetShape2()); (contact.GetShape2().UserData as Actor).OnEndContact((contact.GetShape1().UserData as Actor), contact.GetShape2(), contact.GetShape1()); } else { throw new Exceptions.PhysicsBodyDataIsBroken("This contact listener requires for user data to be owner of the component to properly operate"); } }
public ContactSolver(TimeStep step, Contact[] contacts, int contactCount) { _step = step; _constraintCount = contactCount; _constraints = new ContactConstraint[_constraintCount]; for (int i = 0; i < _constraintCount; i++) { _constraints[i] = new ContactConstraint(); } for (int i = 0; i < _constraintCount; ++i) { Contact contact = contacts[i]; Fixture fixtureA = contact._fixtureA; Fixture fixtureB = contact._fixtureB; Shape shapeA = fixtureA.Shape; Shape shapeB = fixtureB.Shape; float radiusA = shapeA._radius; float radiusB = shapeB._radius; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; Manifold manifold = contact.Manifold; float friction = Settings.MixFriction(fixtureA.Friction, fixtureB.Friction); float restitution = Settings.MixRestitution(fixtureA.Restitution, fixtureB.Restitution); Box2DXDebug.Assert(manifold.PointCount > 0); WorldManifold worldManifold = new WorldManifold(); worldManifold.Initialize(manifold, bodyA._xf, radiusA, bodyB._xf, radiusB); ContactConstraint cc = _constraints[i]; cc.BodyA = bodyA; cc.BodyB = bodyB; cc.Manifold = manifold; cc.Normal = worldManifold.Normal; cc.PointCount = manifold.PointCount; cc.Friction = friction; cc.Restitution = restitution; cc.LocalPlaneNormal = manifold.LocalPlaneNormal; cc.LocalPoint = manifold.LocalPoint; cc.Radius = radiusA + radiusB; cc.Type = manifold.Type; ContactSolverSetup(manifold, worldManifold, cc); } }
public override void PostSolve(Contact contact, ContactImpulse impulse) { if (_broke) { // The body already broke. return; } // Should the body break? int count = contact.GetManifold().PointCount; float maxImpulse = 0.0f; for (int i = 0; i < count; ++i) { maxImpulse = Math.Max(maxImpulse, impulse.normalImpulses[i]); } if (maxImpulse > 50.0f) { // Flag the body for breaking. _break = true; } }
public Contact(Shape s1, Shape s2) { this._flags = (Contact.CollisionFlags)0; if (s1.IsSensor || s2.IsSensor) { this._flags |= Contact.CollisionFlags.NonSolid; } this._shape1 = s1; this._shape2 = s2; this._manifoldCount = 0; this._prev = null; this._next = null; this._node1 = new ContactEdge(); this._node1.Contact = null; this._node1.Prev = null; this._node1.Next = null; this._node1.Other = null; this._node2 = new ContactEdge(); this._node2.Contact = null; this._node2.Prev = null; this._node2.Next = null; this._node2.Other = null; }
public void Destroy(Contact c) { Shape shape1 = c.GetShape1(); Shape shape2 = c.GetShape2(); Body body1 = shape1.GetBody(); Body body2 = shape2.GetBody(); ContactPoint cp = new ContactPoint(); cp.Shape1 = shape1; cp.Shape2 = shape2; cp.Friction = Settings.MixFriction(shape1.Friction, shape2.Friction); cp.Restitution = Settings.MixRestitution(shape1.Restitution, shape2.Restitution); // Inform the user that this contact is ending. int manifoldCount = c.GetManifoldCount(); if (manifoldCount > 0 && _world._contactListener!=null) { Manifold[] manifolds = c.GetManifolds(); for (int i = 0; i < manifoldCount; ++i) { Manifold manifold = manifolds[i]; cp.Normal = manifold.Normal; for (int j = 0; j < manifold.PointCount; ++j) { ManifoldPoint mp = manifold.Points[j]; cp.Position = body1.GetWorldPoint(mp.LocalPoint1); Vec2 v1 = body1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); Vec2 v2 = body2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); cp.Velocity = v2 - v1; cp.Separation = mp.Separation; cp.ID = mp.ID; _world._contactListener.Remove(cp); } } } // Remove from the world. if (c._prev != null) { c._prev._next = c._next; } if (c._next != null) { c._next._prev = c._prev; } if (c == _world._contactList) { _world._contactList = c._next; } // Remove from body 1 if (c._node1.Prev != null) { c._node1.Prev.Next = c._node1.Next; } if (c._node1.Next != null) { c._node1.Next.Prev = c._node1.Prev; } if (c._node1 == body1._contactList) { body1._contactList = c._node1.Next; } // Remove from body 2 if (c._node2.Prev != null) { c._node2.Prev.Next = c._node2.Next; } if (c._node2.Next != null) { c._node2.Next.Prev = c._node2.Prev; } if (c._node2 == body2._contactList) { body2._contactList = c._node2.Next; } // Call the factory. Contact.Destroy(c); --_world._contactCount; }
public void AddPair(object proxyUserDataA, object proxyUserDataB) { Fixture fixtureA = (Fixture)proxyUserDataA; Fixture fixtureB = (Fixture)proxyUserDataB; Body bodyA = fixtureA.GetBody(); Body bodyB = fixtureB.GetBody(); // Are the fixtures on the same body? if (bodyA == bodyB) { return; } // Are both bodies static? if (bodyA.IsStatic() && bodyB.IsStatic()) { return; } // Does a contact already exist? ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { Fixture fA = edge.Contact.GetFixtureA(); Fixture fB = edge.Contact.GetFixtureB(); if (fA == fixtureA && fB == fixtureB) { // A contact already exists. return; } if (fA == fixtureB && fB == fixtureA) { // A contact already exists. return; } } edge = edge.Next; } // Does a joint override collision? if (bodyB.IsConnected(bodyA)) { return; } // Check user filtering. if (_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return; } // Call the factory. Contact c = Contact.Create(fixtureA, fixtureB); // Contact creation may swap fixtures. fixtureA = c.GetFixtureA(); fixtureB = c.GetFixtureB(); bodyA = fixtureA.GetBody(); bodyB = fixtureB.GetBody(); // Insert into the world. c.Prev = null; c.Next = _contactList; if (_contactList != null) { _contactList.Prev = c; } _contactList = c; // Connect to island graph. // Connect to body A c.NodeA.Contact = c; c.NodeA.Other = bodyB; c.NodeA.Prev = null; c.NodeA.Next = bodyA._contactList; if (bodyA._contactList != null) { bodyA._contactList.Prev = c.NodeA; } bodyA._contactList = c.NodeA; // Connect to body B c.NodeB.Contact = c; c.NodeB.Other = bodyA; c.NodeB.Prev = null; c.NodeB.Next = bodyB._contactList; if (bodyB._contactList != null) { bodyB._contactList.Prev = c.NodeB; } bodyB._contactList = c.NodeB; ++_contactCount; }
public static new void Destroy(Contact contact) { }
public static void Destroy(Contact contact, ShapeType typeA, ShapeType typeB) { Box2DXDebug.Assert(Initialized == true); if (contact.Manifold.PointCount > 0) { contact.GetFixtureA().GetBody().WakeUp(); contact.GetFixtureB().GetBody().WakeUp(); } Box2DXDebug.Assert(ShapeType.UnknownShape < typeA && typeB < ShapeType.ShapeTypeCount); Box2DXDebug.Assert(ShapeType.UnknownShape < typeA && typeB < ShapeType.ShapeTypeCount); ContactDestroyFcn destroyFcn = Registers[(int)typeA][(int)typeB].DestroyFcn; destroyFcn(contact); }
public Contact(Shape s1, Shape s2) { _flags = 0; if (s1.IsSensor || s2.IsSensor) { _flags |= CollisionFlags.NonSolid; } _shape1 = s1; _shape2 = s2; _manifoldCount = 0; _prev = null; _next = null; _node1 = new ContactEdge(); _node1.Contact = null; _node1.Prev = null; _node1.Next = null; _node1.Other = null; _node2 = new ContactEdge(); _node2.Contact = null; _node2.Prev = null; _node2.Next = null; _node2.Other = null; }
public void PostSolve(Contact contact, ContactImpulse impulse) { //eh }
public Contact(Fixture fA, Fixture fB) { _flags = 0; if (fA.IsSensor || fB.IsSensor) { _flags |= CollisionFlags.NonSolid; } _fixtureA = fA; _fixtureB = fB; _manifold.PointCount = 0; _prev = null; _next = null; _nodeA = new ContactEdge(); _nodeB = new ContactEdge(); }
new public static void Destroy(ref Contact contact) { contact = null; }
public ContactSolver(TimeStep step, Contact[] contacts, int contactCount) { _step = step; _constraintCount = 0; for (int i = 0; i < contactCount; ++i) { Box2DXDebug.Assert(contacts[i].IsSolid()); _constraintCount += contacts[i].GetManifoldCount(); } _constraints = new ContactConstraint[_constraintCount]; for (int i = 0; i < _constraintCount; i++) _constraints[i] = new ContactConstraint(); int count = 0; for (int i = 0; i < contactCount; ++i) { Contact contact = contacts[i]; Shape shape1 = contact._shape1; Shape shape2 = contact._shape2; Body b1 = shape1.GetBody(); Body b2 = shape2.GetBody(); int manifoldCount = contact.GetManifoldCount(); Manifold[] manifolds = contact.GetManifolds(); float friction = Settings.MixFriction(shape1.Friction, shape2.Friction); float restitution = Settings.MixRestitution(shape1.Restitution, shape2.Restitution); Vec2 v1 = b1._linearVelocity; Vec2 v2 = b2._linearVelocity; float w1 = b1._angularVelocity; float w2 = b2._angularVelocity; for (int j = 0; j < manifoldCount; ++j) { Manifold manifold = manifolds[j]; Box2DXDebug.Assert(manifold.PointCount > 0); Vec2 normal = manifold.Normal; Box2DXDebug.Assert(count < _constraintCount); ContactConstraint cc = _constraints[count]; cc.Body1 = b1; cc.Body2 = b2; cc.Manifold = manifold; cc.Normal = normal; cc.PointCount = manifold.PointCount; cc.Friction = friction; cc.Restitution = restitution; for (int k = 0; k < cc.PointCount; ++k) { ManifoldPoint cp = manifold.Points[k]; ContactConstraintPoint ccp = cc.Points[k]; ccp.NormalImpulse = cp.NormalImpulse; ccp.TangentImpulse = cp.TangentImpulse; ccp.Separation = cp.Separation; ccp.LocalAnchor1 = cp.LocalPoint1; ccp.LocalAnchor2 = cp.LocalPoint2; ccp.R1 = Common.Math.Mul(b1.GetXForm().R, cp.LocalPoint1 - b1.GetLocalCenter()); ccp.R2 = Common.Math.Mul(b2.GetXForm().R, cp.LocalPoint2 - b2.GetLocalCenter()); float rn1 = Vec2.Cross(ccp.R1, normal); float rn2 = Vec2.Cross(ccp.R2, normal); rn1 *= rn1; rn2 *= rn2; float kNormal = b1._invMass + b2._invMass + b1._invI * rn1 + b2._invI * rn2; Box2DXDebug.Assert(kNormal > Common.Settings.FLT_EPSILON); ccp.NormalMass = 1.0f / kNormal; float kEqualized = b1._mass * b1._invMass + b2._mass * b2._invMass; kEqualized += b1._mass * b1._invI * rn1 + b2._mass * b2._invI * rn2; Box2DXDebug.Assert(kEqualized > Common.Settings.FLT_EPSILON); ccp.EqualizedMass = 1.0f / kEqualized; Vec2 tangent = Vec2.Cross(normal, 1.0f); float rt1 = Vec2.Cross(ccp.R1, tangent); float rt2 = Vec2.Cross(ccp.R2, tangent); rt1 *= rt1; rt2 *= rt2; float kTangent = b1._invMass + b2._invMass + b1._invI * rt1 + b2._invI * rt2; Box2DXDebug.Assert(kTangent > Common.Settings.FLT_EPSILON); ccp.TangentMass = 1.0f / kTangent; // Setup a velocity bias for restitution. ccp.VelocityBias = 0.0f; if (ccp.Separation > 0.0f) { ccp.VelocityBias = -step.Inv_Dt * ccp.Separation; // TODO_ERIN b2TimeStep } else { float vRel = Vec2.Dot(cc.Normal, v2 + Vec2.Cross(w2, ccp.R2) - v1 - Vec2.Cross(w1, ccp.R1)); if (vRel < -Settings.VelocityThreshold) { ccp.VelocityBias = -cc.Restitution * vRel; } } } // If we have two points, then prepare the block solver. if (cc.PointCount == 2) { ContactConstraintPoint ccp1 = cc.Points[0]; ContactConstraintPoint ccp2 = cc.Points[1]; float invMass1 = b1._invMass; float invI1 = b1._invI; float invMass2 = b2._invMass; float invI2 = b2._invI; float rn11 = Vec2.Cross(ccp1.R1, normal); float rn12 = Vec2.Cross(ccp1.R2, normal); float rn21 = Vec2.Cross(ccp2.R1, normal); float rn22 = Vec2.Cross(ccp2.R2, normal); float k11 = invMass1 + invMass2 + invI1 * rn11 * rn11 + invI2 * rn12 * rn12; float k22 = invMass1 + invMass2 + invI1 * rn21 * rn21 + invI2 * rn22 * rn22; float k12 = invMass1 + invMass2 + invI1 * rn11 * rn21 + invI2 * rn12 * rn22; // Ensure a reasonable condition number. const float k_maxConditionNumber = 100.0f; if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { // K is safe to invert. cc.K.Col1.Set(k11, k12); cc.K.Col2.Set(k12, k22); cc.NormalMass = cc.K.Invert(); } else { // The constraints are redundant, just use one. // TODO_ERIN use deepest? cc.PointCount = 1; } } ++count; } } Box2DXDebug.Assert(count == _constraintCount); }
/// This lets you inspect a contact after the solver is finished. This is useful /// for inspecting impulses. /// Note: the contact manifold does not include time of impact impulses, which can be /// arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly /// in a separate data structure. /// Note: this is only called for contacts that are touching, solid, and awake. public virtual void PostSolve(Contact contact, ContactImpulse impulse) { //B2_NOT_USED(contact); //B2_NOT_USED(impulse); }
/// This is called after a contact is updated. This allows you to inspect a /// contact before it goes to the solver. If you are careful, you can modify the /// contact manifold (e.g. disable contact). /// A copy of the old manifold is provided so that you can detect changes. /// Note: this is called only for awake bodies. /// Note: this is called even when the number of contact points is zero. /// Note: this is not called for sensors. /// Note: if you set the number of contact points to zero, you will not /// get an EndContact callback. However, you may get a BeginContact callback /// the next step. public virtual void PreSolve(Contact contact, Manifold oldManifold) { //B2_NOT_USED(contact); //B2_NOT_USED(oldManifold); }
/// Called when two fixtures cease to touch. public virtual void EndContact(Contact contact) { //B2_NOT_USED(contact); }
/// Called when two fixtures begin to touch. public virtual void BeginContact(Contact contact) { //B2_NOT_USED(contact); }
public Contact(Fixture fixtureA, Fixture fixtureB) { Flags = 0; if (fixtureA.IsSensor || fixtureB.IsSensor) { Flags |= ContactFlag.SensorFlag; } Body bodyA = fixtureA.GetBody(); Body bodyB = fixtureB.GetBody(); if (bodyA.IsStatic() || bodyA.IsBullet() || bodyB.IsStatic() || bodyB.IsBullet()) { Flags |= ContactFlag.ContinuousFlag; } else { Flags &= ~ContactFlag.ContinuousFlag; } _fixtureA = fixtureA; _fixtureB = fixtureB; Manifold = new Manifold(); Manifold.PointCount = 0; Prev = null; Next = null; NodeA = new ContactEdge(); NodeA.Contact = null; NodeA.Prev = null; NodeA.Next = null; NodeA.Other = null; NodeB = new ContactEdge(); NodeB.Contact = null; NodeB.Prev = null; NodeB.Next = null; NodeB.Other = null; }
public ContactSolver(TimeStep step, Contact[] contacts, int contactCount) { Step = step; ConstraintCount = contactCount; Constraints = new ContactConstraint[ConstraintCount]; for (int i = 0; i < ConstraintCount; ++i) { Contact contact = contacts[i]; Fixture fixtureA = contact.GetFixtureA(); Fixture fixtureB = contact.GetFixtureB(); Shape shapeA = fixtureA.GetShape(); Shape shapeB = fixtureB.GetShape(); float radiusA = shapeA._radius; float radiusB = shapeB._radius; Body bodyA = fixtureA.GetBody(); Body bodyB = fixtureB.GetBody(); Manifold manifold = contact.GetManifold(); float friction = Settings.MixFriction(fixtureA.GetFriction(), fixtureB.GetFriction()); float restitution = Settings.MixRestitution(fixtureA.GetRestitution(), fixtureB.GetRestitution()); Vec2 vA = bodyA._linearVelocity; Vec2 vB = bodyB._linearVelocity; float wA = bodyA._angularVelocity; float wB = bodyB._angularVelocity; Box2DXDebug.Assert(manifold.PointCount > 0); WorldManifold worldManifold = new WorldManifold(); worldManifold.Initialize(manifold, bodyA.GetTransform(), radiusA, bodyB.GetTransform(), radiusB); ContactConstraint cc = new ContactConstraint(); Constraints[i] = cc; cc.BodyA = bodyA; cc.BodyB = bodyB; cc.Manifold = manifold; cc.Normal = worldManifold.Normal; cc.PointCount = manifold.PointCount; cc.Friction = friction; cc.Restitution = restitution; cc.LocalPlaneNormal = manifold.LocalPlaneNormal; cc.LocalPoint = manifold.LocalPoint; cc.Radius = radiusA + radiusB; cc.Type = manifold.Type; for (int j = 0; j < cc.PointCount; ++j) { ManifoldPoint cp = manifold.Points[j]; ContactConstraintPoint ccp = cc.Points[j]; ccp.NormalImpulse = cp.NormalImpulse; ccp.TangentImpulse = cp.TangentImpulse; ccp.LocalPoint = cp.LocalPoint; ccp.RA = worldManifold.Points[j] - bodyA._sweep.C; ccp.RB = worldManifold.Points[j] - bodyB._sweep.C; float rnA = Vec2.Cross(ccp.RA, cc.Normal); float rnB = Vec2.Cross(ccp.RB, cc.Normal); rnA *= rnA; rnB *= rnB; float kNormal = bodyA._invMass + bodyB._invMass + bodyA._invI * rnA + bodyB._invI * rnB; Box2DXDebug.Assert(kNormal > Settings.FLT_EPSILON); ccp.NormalMass = 1.0f / kNormal; float kEqualized = bodyA._mass * bodyA._invMass + bodyB._mass * bodyB._invMass; kEqualized += bodyA._mass * bodyA._invI * rnA + bodyB._mass * bodyB._invI * rnB; Box2DXDebug.Assert(kEqualized > Settings.FLT_EPSILON); ccp.EqualizedMass = 1.0f / kEqualized; Vec2 tangent = Vec2.Cross(cc.Normal, 1.0f); float rtA = Vec2.Cross(ccp.RA, tangent); float rtB = Vec2.Cross(ccp.RB, tangent); rtA *= rtA; rtB *= rtB; float kTangent = bodyA._invMass + bodyB._invMass + bodyA._invI * rtA + bodyB._invI * rtB; Box2DXDebug.Assert(kTangent > Settings.FLT_EPSILON); ccp.TangentMass = 1.0f / kTangent; // Setup a velocity bias for restitution. ccp.VelocityBias = 0.0f; float vRel = Vec2.Dot(cc.Normal, vB + Vec2.Cross(wB, ccp.RB) - vA - Vec2.Cross(wA, ccp.RA)); if (vRel < -Settings.VelocityThreshold) { ccp.VelocityBias = -cc.Restitution * vRel; } } // If we have two points, then prepare the block solver. if (cc.PointCount == 2) { ContactConstraintPoint ccp1 = cc.Points[0]; ContactConstraintPoint ccp2 = cc.Points[1]; float invMassA = bodyA._invMass; float invIA = bodyA._invI; float invMassB = bodyB._invMass; float invIB = bodyB._invI; float rn1A = Vec2.Cross(ccp1.RA, cc.Normal); float rn1B = Vec2.Cross(ccp1.RB, cc.Normal); float rn2A = Vec2.Cross(ccp2.RA, cc.Normal); float rn2B = Vec2.Cross(ccp2.RB, cc.Normal); float k11 = invMassA + invMassB + invIA * rn1A * rn1A + invIB * rn1B * rn1B; float k22 = invMassA + invMassB + invIA * rn2A * rn2A + invIB * rn2B * rn2B; float k12 = invMassA + invMassB + invIA * rn1A * rn2A + invIB * rn1B * rn2B; // Ensure a reasonable condition number. const float k_maxConditionNumber = 100.0f; if (k11 * k11 < k_maxConditionNumber * (k11 * k22 - k12 * k12)) { // K is safe to invert. cc.K.Col1.Set(k11, k12); cc.K.Col2.Set(k12, k22); cc.NormalMass = cc.K.Invert(); } else { // The constraints are redundant, just use one. // TODO_ERIN use deepest? cc.PointCount = 1; } } } }
public static void Destroy(Contact contact) { //Box2DXDebug.Assert(s_initialized == true); // COMMENT IS HACK HACK HACK if (contact.GetManifoldCount() > 0) { contact.GetShape1().GetBody().WakeUp(); contact.GetShape2().GetBody().WakeUp(); } ShapeType type1 = contact.GetShape1().GetType(); ShapeType type2 = contact.GetShape2().GetType(); Box2DXDebug.Assert(ShapeType.UnknownShape < type1 && type1 < ShapeType.ShapeTypeCount); Box2DXDebug.Assert(ShapeType.UnknownShape < type2 && type2 < ShapeType.ShapeTypeCount); try { ContactDestroyFcn destroyFcn = s_registers[(int)type1][(int)type2].DestroyFcn; destroyFcn(contact); } catch (NullReferenceException e) { Console.WriteLine("NullReferenceException caught in Box2DX.Dynamics.Contact#Destroy"); } }
public void EndContact(Contact contact) { if (contact.FixtureA.UserData is IEntity && contact.FixtureB.UserData is IEntity) { IEntity A = (IEntity)contact.FixtureA.UserData; IEntity B = (IEntity)contact.FixtureB.UserData; A.OnSeperate(B); B.OnSeperate(A); } }
public void Add(Contact contact) { Box2DXDebug.Assert(_contactCount < _contactCapacity); _contacts[_contactCount++] = contact; }
public void PreSolve(Contact contact, Manifold oldManifold) { //eh }
public void Destroy(Contact c) { Fixture fixtureA = c.GetFixtureA(); Fixture fixtureB = c.GetFixtureB(); Body body1 = fixtureA.GetBody(); Body body2 = fixtureB.GetBody(); if (c.Manifold.PointCount > 0) { _contactListener.EndContact(c); } // Remove from the world. if (c.Prev != null) { c.Prev.Next = c.Next; } if (c.Next != null) { c.Next.Prev = c.Prev; } if (c == _contactList) { _contactList = c.Next; } // Remove from body 1 if (c.NodeA.Prev != null) { c.NodeA.Prev.Next = c.NodeA.Next; } if (c.NodeA.Next != null) { c.NodeA.Next.Prev = c.NodeA.Prev; } if (c.NodeA == body1._contactList) { body1._contactList = c.NodeA.Next; } // Remove from body 2 if (c.NodeB.Prev != null) { c.NodeB.Prev.Next = c.NodeB.Next; } if (c.NodeB.Next != null) { c.NodeB.Next.Prev = c.NodeB.Prev; } if (c.NodeB == body2._contactList) { body2._contactList = c.NodeB.Next; } // Call the factory. Contact.Destroy(c); --_contactCount; }
public void Add(ref Contact contact) { Box2DXDebug.Assert(ContactCount < ContactCapacity); Contacts[ContactCount++] = contact; }
public static void Destroy(Contact contact) { Destroy(contact, contact.GetFixtureA().GetType(), contact.GetFixtureB().GetType()); }
public static new void Destroy(Contact contact) { contact = null; }
/// <summary> /// Construct a world object. /// </summary> /// <param name="worldAABB">A bounding box that completely encompasses all your shapes.</param> /// <param name="gravity">The world gravity vector.</param> /// <param name="doSleep">Improve performance by not simulating inactive bodies.</param> public World(AABB worldAABB, Vec2 gravity, bool doSleep) { _destructionListener = null; _boundaryListener = null; _contactFilter = WorldCallback.DefaultFilter; _contactListener = null; _debugDraw = null; _bodyList = null; _contactList = null; _jointList = null; _bodyCount = 0; _contactCount = 0; _jointCount = 0; _warmStarting = true; _continuousPhysics = true; _allowSleep = doSleep; _gravity = gravity; _lock = false; _inv_dt0 = 0.0f; _contactManager = new ContactManager(); _contactManager._world = this; _broadPhase = new BroadPhase(worldAABB, _contactManager); BodyDef bd = new BodyDef(); _groundBody = CreateBody(bd); }