// Update the contact manifold and touching status. // Note: do not assume the fixture AABBs are overlapping or are valid. internal void Update(b2ContactListener listener) { b2Manifold oldManifold = m_manifold; // Re-enable this contact. m_flags |= ContactFlags.e_enabledFlag; bool touching = false; bool wasTouching = (m_flags & ContactFlags.e_touchingFlag) == ContactFlags.e_touchingFlag; bool sensorA = m_fixtureA.IsSensor(); bool sensorB = m_fixtureB.IsSensor(); bool sensor = sensorA || sensorB; b2Body bodyA = m_fixtureA.GetBody(); b2Body bodyB = m_fixtureB.GetBody(); b2Transform xfA = bodyA.GetTransform(); b2Transform xfB = bodyB.GetTransform(); // Is this contact a sensor? if (sensor) { b2Shape shapeA = m_fixtureA.GetShape(); b2Shape shapeB = m_fixtureB.GetShape(); touching = Utils.b2TestOverlap(shapeA, m_indexA, shapeB, m_indexB, xfA, xfB); // Sensors don't generate manifolds. m_manifold.pointCount = 0; } else { Evaluate(m_manifold, xfA, xfB); touching = m_manifold.pointCount > 0; // Match old contact ids to new contact ids and copy the // stored impulses to warm start the solver. for (int i = 0; i < m_manifold.pointCount; ++i) { b2ManifoldPoint mp2 = m_manifold.points[i]; mp2.normalImpulse = 0.0f; mp2.tangentImpulse = 0.0f; b2ContactID id2 = mp2.id; for (int j = 0; j < oldManifold.pointCount; ++j) { b2ManifoldPoint mp1 = oldManifold.points[j]; if (mp1.id.key == id2.key) { mp2.normalImpulse = mp1.normalImpulse; mp2.tangentImpulse = mp1.tangentImpulse; break; } } } if (touching != wasTouching) { bodyA.SetAwake(true); bodyB.SetAwake(true); } } if (touching) { m_flags |= ContactFlags.e_touchingFlag; } else { m_flags &= ~ContactFlags.e_touchingFlag; } if (wasTouching == false && touching == true && listener != null) { listener.BeginContact(this); } if (wasTouching == true && touching == false && listener != null) { listener.EndContact(this); } if (sensor == false && touching && listener != null) { listener.PreSolve(this, oldManifold); } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2ContactID obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
public void Update(b2ContactListener listener) { // Swap old & new manifold b2Manifold tManifold = m_oldManifold; m_oldManifold = m_manifold; m_manifold = tManifold; // Re-enable this contact m_flags |= e_enabledFlag; bool touching = false; bool wasTouching = (m_flags & e_touchingFlag) == e_touchingFlag; b2Body bodyA = m_fixtureA.m_body; b2Body bodyB = m_fixtureB.m_body; bool aabbOverlap = m_fixtureA.m_aabb.TestOverlap(m_fixtureB.m_aabb); // Is this contat a sensor? if ((m_flags & e_sensorFlag) > 0) { if (aabbOverlap) { b2Shape shapeA = m_fixtureA.GetShape(); b2Shape shapeB = m_fixtureB.GetShape(); b2Transform xfA = bodyA.GetTransform(); b2Transform xfB = bodyB.GetTransform(); touching = b2Shape.TestOverlap(shapeA, xfA, shapeB, xfB); } // Sensors don't generate manifolds m_manifold.m_pointCount = 0; } else { // Slow contacts don't generate TOI events. if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { m_flags |= e_continuousFlag; } else { m_flags &= ~e_continuousFlag; } if (aabbOverlap) { Evaluate(); touching = m_manifold.m_pointCount > 0; // Match old contact ids to new contact ids and copy the // stored impulses to warm start the solver. for (int i = 0; i < m_manifold.m_pointCount; ++i) { b2ManifoldPoint mp2 = m_manifold.m_points[i]; mp2.m_normalImpulse = 0.0f; mp2.m_tangentImpulse = 0.0f; b2ContactID id2 = mp2.m_id; for (int j = 0; j < m_oldManifold.m_pointCount; ++j) { b2ManifoldPoint mp1 = m_oldManifold.m_points[j]; if (mp1.m_id.key == id2.key) { mp2.m_normalImpulse = mp1.m_normalImpulse; mp2.m_tangentImpulse = mp1.m_tangentImpulse; break; } } } } else { m_manifold.m_pointCount = 0; } if (touching != wasTouching) { bodyA.SetAwake(true); bodyB.SetAwake(true); } } if (touching) { m_flags |= e_touchingFlag; } else { m_flags &= ~e_touchingFlag; } if (wasTouching == false && touching == true) { listener.BeginContact(this); } if (wasTouching == true && touching == false) { listener.EndContact(this); } if ((m_flags & e_sensorFlag) == 0) { listener.PreSolve(this, m_oldManifold); } }