public override void Evaluate(ContactListener listener) { Body b1 = _shape1.GetBody(); Body b2 = _shape2.GetBody(); #warning "needfix" //memcpy(&m0, &m_manifold, sizeof(b2Manifold)); Manifold m0 = _manifold.Clone(); Collision.Collision.CollidePolygons(ref _manifold, (PolygonShape)_shape1, b1.GetXForm(), (PolygonShape)_shape2, b2.GetXForm()); bool[] persisted = new bool[] { false, false }; 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); // Match contact ids to facilitate warm starting. if (_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 < _manifold.PointCount; ++i) { ManifoldPoint mp = _manifold.Points[i]; mp.NormalImpulse = 0.0f; mp.TangentImpulse = 0.0f; bool found = false; ContactID id = mp.ID; for (int j = 0; j < m0.PointCount; ++j) { if (persisted[j] == true) { continue; } ManifoldPoint mp0 = m0.Points[j]; if (mp0.ID.Key == id.Key) { persisted[j] = true; mp.NormalImpulse = mp0.NormalImpulse; mp.TangentImpulse = mp0.TangentImpulse; // A persistent point. found = true; // Report persistent point. if (listener != null) { cp.Position = b1.GetWorldPoint(mp.LocalPoint1); Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); cp.Velocity = v2 - v1; cp.Normal = _manifold.Normal; cp.Separation = mp.Separation; cp.ID = id; listener.Persist(cp); } break; } } // Report added point. if (found == false && listener != null) { cp.Position = b1.GetWorldPoint(mp.LocalPoint1); Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); cp.Velocity = v2 - v1; cp.Normal = _manifold.Normal; cp.Separation = mp.Separation; cp.ID = id; listener.Add(cp); } } _manifoldCount = 1; } else { _manifoldCount = 0; } if (listener == null) { return; } // Report removed points. for (int i = 0; i < m0.PointCount; ++i) { if (persisted[i]) { continue; } ManifoldPoint mp0 = m0.Points[i]; cp.Position = b1.GetWorldPoint(mp0.LocalPoint1); Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp0.LocalPoint1); Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp0.LocalPoint2); cp.Velocity = v2 - v1; cp.Normal = m0.Normal; cp.Separation = mp0.Separation; cp.ID = mp0.ID; listener.Remove(cp); } }
public void Update(ContactListener listener) { Manifold oldManifold = _manifold.Clone(); Evaluate(); Body bodyA = _fixtureA.Body; Body bodyB = _fixtureB.Body; int oldCount = oldManifold.PointCount; int newCount = _manifold.PointCount; if (newCount == 0 && oldCount > 0) { bodyA.WakeUp(); bodyB.WakeUp(); } // Slow contacts don't generate TOI events. if (bodyA.IsStatic() || bodyA.IsBullet() || bodyB.IsStatic() || bodyB.IsBullet()) { _flags &= ~CollisionFlags.Slow; } else { _flags |= CollisionFlags.Slow; } // Match old contact ids to new contact ids and copy the // stored impulses to warm start the solver. for (int i = 0; i < _manifold.PointCount; ++i) { ManifoldPoint mp2 = _manifold.Points[i]; mp2.NormalImpulse = 0.0f; mp2.TangentImpulse = 0.0f; ContactID id2 = mp2.ID; for (int j = 0; j < oldManifold.PointCount; ++j) { ManifoldPoint mp1 = oldManifold.Points[j]; if (mp1.ID.Key == id2.Key) { mp2.NormalImpulse = mp1.NormalImpulse; mp2.TangentImpulse = mp1.TangentImpulse; break; } } } if (oldCount == 0 && newCount > 0) { _flags |= CollisionFlags.Touch; if (listener != null) { listener.BeginContact(this); } } if (oldCount > 0 && newCount == 0) { _flags &= ~CollisionFlags.Touch; if (listener != null) { listener.EndContact(this); } } if ((_flags & CollisionFlags.NonSolid) == 0) { if (listener != null) { listener.PreSolve(this, oldManifold); } // The user may have disabled contact. if (_manifold.PointCount == 0) { _flags &= ~CollisionFlags.Touch; } } }
public override void Evaluate(ContactListener listener) { Body b1 = _shape1.GetBody(); Body b2 = _shape2.GetBody(); //memcpy(&m0, &m_manifold, sizeof(b2Manifold)); Manifold m0 = _manifold.Clone(); Collision.Collision.CollideCircles(ref _manifold, (CircleShape)_shape1, b1.GetXForm(), (CircleShape)_shape2, b2.GetXForm()); 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); if (_manifold.PointCount > 0) { _manifoldCount = 1; ManifoldPoint mp = _manifold.Points[0]; if (m0.PointCount == 0) { mp.NormalImpulse = 0.0f; mp.TangentImpulse = 0.0f; if (listener != null) { cp.Position = b1.GetWorldPoint(mp.LocalPoint1); Vector2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); Vector2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); cp.Velocity = v2 - v1; cp.Normal = _manifold.Normal; cp.Separation = mp.Separation; cp.ID = mp.ID; listener.Add(cp); } } else { ManifoldPoint mp0 = m0.Points[0]; mp.NormalImpulse = mp0.NormalImpulse; mp.TangentImpulse = mp0.TangentImpulse; if (listener != null) { cp.Position = b1.GetWorldPoint(mp.LocalPoint1); Vector2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); Vector2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); cp.Velocity = v2 - v1; cp.Normal = _manifold.Normal; cp.Separation = mp.Separation; cp.ID = mp.ID; listener.Persist(cp); } } } else { _manifoldCount = 0; if (m0.PointCount > 0 && listener != null) { ManifoldPoint mp0 = m0.Points[0]; cp.Position = b1.GetWorldPoint(mp0.LocalPoint1); Vector2 v1 = b1.GetLinearVelocityFromLocalPoint(mp0.LocalPoint1); Vector2 v2 = b2.GetLinearVelocityFromLocalPoint(mp0.LocalPoint2); cp.Velocity = v2 - v1; cp.Normal = m0.Normal; cp.Separation = mp0.Separation; cp.ID = mp0.ID; listener.Remove(cp); } } }