/// <summary> /// Adds a contact to the arbiter (threadsafe). No more than four contacts /// are stored in the contactList. When adding a new contact /// to the arbiter the existing are checked and the best are kept. /// </summary> /// <param name="point1">Point on body1. In world space.</param> /// <param name="point2">Point on body2. In world space.</param> /// <param name="normal">The normal pointing to body2.</param> /// <param name="penetration">The estimated penetration depth.</param> public Contact AddContact(FPVector point1, FPVector point2, FPVector normal, FP penetration, ContactSettings contactSettings) { FPVector relPos1; FPVector.Subtract(ref point1, ref body1.position, out relPos1); int index; lock (contactList) { if (this.contactList.Count == 4) { index = SortCachedPoints(ref relPos1, penetration); ReplaceContact(ref point1, ref point2, ref normal, penetration, index, contactSettings); return(null); } index = GetCacheEntry(ref relPos1, contactSettings.breakThreshold); if (index >= 0) { ReplaceContact(ref point1, ref point2, ref normal, penetration, index, contactSettings); return(null); } else { Contact contact = Contact.Pool.GetNew(); contact.Initialize(body1, body2, ref point1, ref point2, ref normal, penetration, true, contactSettings); contactList.Add(contact); return(contact); } } }
private void ReplaceContact(ref FPVector point1, ref FPVector point2, ref FPVector n, FP p, int index, ContactSettings contactSettings) { Contact contact = contactList[index]; Debug.Assert(body1 == contact.body1, "Body1 and Body2 not consistent."); contact.Initialize(body1, body2, ref point1, ref point2, ref n, p, false, contactSettings); }