public override float AddSingleResult(BulletSharp.ManifoldPoint contact, BulletSharp.CollisionObjectWrapper obj0, int partId0, int index0, BulletSharp.CollisionObjectWrapper obj1, int partId1, int index1) { var component0 = obj0.CollisionObject.UserObject as PhysicsComponent; var component1 = obj1.CollisionObject.UserObject as PhysicsComponent; Contacts.Add(new OverlapContactPoint { ContactComponent = component0 ?? component1, Distance = contact.m_distance1, Normal = contact.m_normalWorldOnB, Position = contact.m_positionWorldOnB, }); return(0f); }
private void PersistentManifoldContactProcessed(BulletSharp.ManifoldPoint cp, BulletSharp.CollisionObject body0, BulletSharp.CollisionObject body1) { var colA = (Collider)body0.UserObject; var colB = (Collider)body1.UserObject; if (!colA.NeedsCollisionCheck && !colB.NeedsCollisionCheck) { return; //don't process at all if both the objects don't need any collision event } if (cp.UserPersistentData == null) //New contact! { var contact = new Contact { ColliderA = colA, ColliderB = colB, Distance = cp.Distance, PositionOnA = new Vector3(cp.PositionWorldOnA.X, cp.PositionWorldOnA.Y, cp.PositionWorldOnA.Z), PositionOnB = new Vector3(cp.PositionWorldOnB.X, cp.PositionWorldOnB.Y, cp.PositionWorldOnB.Z), Normal = new Vector3(cp.NormalWorldOnB.X, cp.NormalWorldOnB.Y, cp.NormalWorldOnB.Z) }; //must figure if we are a really brand new collision for correct event propagation var colABegan = false; var previousColAState = colA.Contacts.Where(x => (x.ColliderA == colA && x.ColliderB == colB) || (x.ColliderA == colB && x.ColliderB == colA)); if (!previousColAState.Any()) { colABegan = true; } var colBBegan = false; var previousColBState = colB.Contacts.Where(x => (x.ColliderB == colB && x.ColliderA == colA) || (x.ColliderB == colA && x.ColliderA == colB)); if (!previousColBState.Any()) { colBBegan = true; } colA.Contacts.Add(contact); colB.Contacts.Add(contact); var args = new CollisionArgs { Contact = contact }; cp.UserPersistentData = contact; if (CacheContacts) { contactsCache.Add(new ContactEventData { Type = colABegan ? ContactEventType.FirstContactStart : ContactEventType.ContactStart, Caller = colA, Args = args }); contactsCache.Add(new ContactEventData { Type = colBBegan ? ContactEventType.FirstContactStart : ContactEventType.ContactStart, Caller = colB, Args = args }); } else { if (colABegan) { colA.OnFirstContactStart(args); } colA.OnContactStart(args); if (colBBegan) { colB.OnFirstContactStart(args); } colB.OnContactStart(args); } } else { var contact = (Contact)cp.UserPersistentData; contact.Distance = cp.Distance; contact.PositionOnA = new Vector3(cp.PositionWorldOnA.X, cp.PositionWorldOnA.Y, cp.PositionWorldOnA.Z); contact.PositionOnB = new Vector3(cp.PositionWorldOnB.X, cp.PositionWorldOnB.Y, cp.PositionWorldOnB.Z); contact.Normal = new Vector3(cp.NormalWorldOnB.X, cp.NormalWorldOnB.Y, cp.NormalWorldOnB.Z); var args = new CollisionArgs { Contact = contact }; if (CacheContacts) { contactsCache.Add(new ContactEventData { Type = ContactEventType.ContactChange, Caller = colA, Args = args }); contactsCache.Add(new ContactEventData { Type = ContactEventType.ContactChange, Caller = colB, Args = args }); } else { colA.OnContactChange(args); colB.OnContactChange(args); } } }
private void PersistentManifoldContactProcessed(BulletSharp.ManifoldPoint cp, BulletSharp.CollisionObject body0, BulletSharp.CollisionObject body1) { if (body0 == null || body1 == null) { return; } //this can fail and will fail in the case of multiple scenes and bodies not of the current simulation ( working as intended ) Collider colA, colB; if (!aliveColliders.TryGetValue(body0, out colA)) { return; } if (!aliveColliders.TryGetValue(body1, out colB)) { return; } if (colA == null || colB == null || !colA.ContactsAlwaysValid && !colB.ContactsAlwaysValid) { return; } //Pairs management Collision pair = null; var newPair = true; foreach (var pair1 in colA.Collisions) { if ((pair1.ColliderA != colA || pair1.ColliderB != colB) && (pair1.ColliderA != colB || pair1.ColliderB != colA)) { continue; } pair = pair1; newPair = false; break; } if (pair == null) { pair = new Collision { ColliderA = colA, ColliderB = colB, Contacts = new List <ContactPoint>() }; colA.Collisions.Add(pair); colB.Collisions.Add(pair); } //Contacts management ContactPoint contact = null; var newContact = true; foreach (var contact1 in pair.Contacts) { if (contact1.Handle.IsAllocated && cp.UserPersistentPtr != IntPtr.Zero && contact1.Handle.Target != GCHandle.FromIntPtr(cp.UserPersistentPtr).Target) { continue; } contact = contact1; newContact = false; break; } if (contact == null) { contact = new ContactPoint { Distance = cp.Distance, PositionOnA = new Vector3(cp.PositionWorldOnA.X, cp.PositionWorldOnA.Y, cp.PositionWorldOnA.Z), PositionOnB = new Vector3(cp.PositionWorldOnB.X, cp.PositionWorldOnB.Y, cp.PositionWorldOnB.Z), Normal = new Vector3(cp.NormalWorldOnB.X, cp.NormalWorldOnB.Y, cp.NormalWorldOnB.Z), Pair = pair }; pair.Contacts.Add(contact); contact.Handle = GCHandle.Alloc(contact); cp.UserPersistentPtr = GCHandle.ToIntPtr(contact.Handle); contact.Manifold = cp; } if (newPair) { //are we the first pair we detect? if (colA.Collisions.Count == 1) { firstPairsCache.Add(new KeyValuePair <Collider, Collision>(colA, pair)); } //are we the first pair we detect? if (colB.Collisions.Count == 1) { firstPairsCache.Add(new KeyValuePair <Collider, Collision>(colB, pair)); } newPairsCache.Add(new KeyValuePair <Collider, Collision>(colA, pair)); newPairsCache.Add(new KeyValuePair <Collider, Collision>(colB, pair)); } if (newContact) { newContactsCache.Add(new KeyValuePair <Collision, ContactPoint>(pair, contact)); } else { updatedContactsCache.Add(new KeyValuePair <Collision, ContactPoint>(pair, contact)); } }
private void PersistentManifoldContactProcessed(BulletSharp.ManifoldPoint cp, BulletSharp.CollisionObject body0, BulletSharp.CollisionObject body1) { var colA = aliveColliders[body0]; var colB = aliveColliders[body1]; if (colA == null || colB == null || !colA.ContactsAlwaysValid && !colB.ContactsAlwaysValid) { return; } //Pairs management Collision pair = null; var newPair = true; foreach (var pair1 in colA.Pairs) { if ((pair1.ColliderA != colA || pair1.ColliderB != colB) && (pair1.ColliderA != colB || pair1.ColliderB != colA)) { continue; } pair = pair1; newPair = false; break; } if (pair == null) { pair = new Collision { ColliderA = colA, ColliderB = colB, Contacts = new List <ContactPoint>() }; colA.Pairs.Add(pair); colB.Pairs.Add(pair); } //Contacts management ContactPoint contact = null; var newContact = true; foreach (var contact1 in pair.Contacts) { if (contact1 != cp.UserPersistentData) { continue; } contact = contact1; newContact = false; break; } if (contact == null) { contact = new ContactPoint { Distance = cp.Distance, PositionOnA = new Vector3(cp.PositionWorldOnA.X, cp.PositionWorldOnA.Y, cp.PositionWorldOnA.Z), PositionOnB = new Vector3(cp.PositionWorldOnB.X, cp.PositionWorldOnB.Y, cp.PositionWorldOnB.Z), Normal = new Vector3(cp.NormalWorldOnB.X, cp.NormalWorldOnB.Y, cp.NormalWorldOnB.Z), Pair = pair }; pair.Contacts.Add(contact); cp.UserPersistentData = contact; } if (newPair) { //are we the first pair we detect? if (colA.Pairs.Count == 1) { firstPairsCache.Add(new KeyValuePair <Collider, Collision>(colA, pair)); } //are we the first pair we detect? if (colB.Pairs.Count == 1) { firstPairsCache.Add(new KeyValuePair <Collider, Collision>(colB, pair)); } newPairsCache.Add(new KeyValuePair <Collider, Collision>(colA, pair)); newPairsCache.Add(new KeyValuePair <Collider, Collision>(colB, pair)); } if (newContact) { newContactsCache.Add(new KeyValuePair <Collision, ContactPoint>(pair, contact)); } else { updatedContactsCache.Add(new KeyValuePair <Collision, ContactPoint>(pair, contact)); } }