private void Collide(Geom geometry1, Geom geometry2, ContactList contactList) { int vertexIndex = -1; for (int i = 0; i < geometry2.worldVertices.Count; i++) { if (contactList.Count == _physicsSimulator.maxContactsToDetect) { break; } if (geometry1.grid == null) { break; } //grid can be null for "one-way" collision (points) vertexIndex += 1; _vertRef = geometry2.WorldVertices[i]; geometry1.TransformToLocalCoordinates(ref _vertRef, out _localVertex); if (!geometry1.Intersect(ref _localVertex, out _feature)) { continue; } if (_feature.Distance < 0f) { geometry1.TransformNormalToWorld(ref _feature.Normal, out _feature.Normal); Contact contact = new Contact(geometry2.WorldVertices[i], _feature.Normal, _feature.Distance, new ContactId(2, vertexIndex, 1)); contactList.Add(contact); } } for (int i = 0; i < geometry1.WorldVertices.Count; i++) { if (contactList.Count == _physicsSimulator.maxContactsToDetect) { break; } if (geometry2.grid == null) { break; } //grid can be null for "one-way" collision (points) vertexIndex += 1; _vertRef = geometry1.WorldVertices[i]; geometry2.TransformToLocalCoordinates(ref _vertRef, out _localVertex); if (!geometry2.Intersect(ref _localVertex, out _feature)) { continue; } if (_feature.Distance < 0f) { geometry2.TransformNormalToWorld(ref _feature.Normal, out _feature.Normal); _feature.Normal = -_feature.Normal; Contact contact = new Contact(geometry1.WorldVertices[i], _feature.Normal, _feature.Distance, new ContactId(2, vertexIndex, 1)); contactList.Add(contact); } } //sort _contact list by seperation (amount of penetration) contactList.Sort(_contactComparer); //resolve deepest contacts first int contactCount = contactList.Count; if (contactList.Count > _physicsSimulator.maxContactsToResolve) { contactList.RemoveRange(_physicsSimulator.maxContactsToResolve, contactCount - _physicsSimulator.maxContactsToResolve); } //allow user to cancel collision if desired if (geometry1.Collision != null) { if (contactList.Count > 0) { if (!geometry1.Collision(geometry1, geometry2, contactList)) { contactList.Clear(); } } } //allow user to cancel collision if desired if (geometry2.Collision != null) { if (contactList.Count > 0) { if (!geometry2.Collision(geometry2, geometry1, contactList)) { contactList.Clear(); } } } }