/// <summary> /// danger! This works for ContactDemo, but there is one hang up. The call to Math.Abs() should not /// be needed. It isn't in the orange book text. However, we only get negative numbers from that Dot. /// </summary> /// <param name="box"></param> /// <param name="plane"></param> /// <param name="data"></param> /// <returns></returns> public static int boxAndPlane(Box box, Plane plane, CollisionData data) { if (data.contactsLeft <= 0) return 0; int contacts_found = 0; // p dot L < l Vector3[] verts = box.WorldVerts(); foreach (Vector3 vert in verts) { //float vertexDist = (float)Math.Abs( (double)Vector3.Dot(plane.Normal, vert)); float vertexDist = Vector3.Dot(-plane.Normal, vert); if (vertexDist >= plane.Offset + data.tolerance) { // the contact point is halfway between the vertex and the plane // we multiply the direction by half the spearation distance // and add the vertex location Contact contact = new Contact(); contact.DiscoveryHint = ContactDiscoveryHint.BoxOnPlane_Corner; contact.Bodies[0] = box.Body; contact.Bodies[1] = null; contact.Point = plane.ClosestPoint(vert); contact.Normal = plane.Normal; contact.Penetration = vertexDist - plane.Offset;//TrickyMathHelper.Abs(plane.Offset - vertexDist); contact.Restitution = data.restitution; contact.Friction = data.friction; data.contacts.Add(contact); contacts_found++; } } return contacts_found; }
public static int boxAndBoxBetter(Box left, Box right, CollisionData data) { Vector3[] leftWorldVerts = left.WorldVerts(); Vector3[] rightWorldVerts = right.WorldVerts(); foreach (Vector3 leftWorldVert in leftWorldVerts) { Contact contact = IntersectionTests.checkBoxAndPoint(right, leftWorldVert, data.restitution, data.friction); if (contact != null) { contact.Bodies[1] = left.Body; data.contacts.Add(contact); } } if (data.contacts.Count > 0) { return data.contacts.Count; } foreach (Vector3 rightWorldVert in rightWorldVerts) { Contact contact = IntersectionTests.checkBoxAndPoint(left, rightWorldVert, data.restitution, data.friction); if (contact != null) { contact.Bodies[1] = right.Body; data.contacts.Add(contact); } } // If any point/face contacts get precedent over edge/edge if (data.contacts.Count > 0) { return data.contacts.Count; } List<Vector3[]> leftEdges = left.WorldEdges(); List<Vector3[]> rightEdges = right.WorldEdges(); foreach (Vector3[] leftEdge in leftEdges) { foreach (Vector3[] rightEdge in rightEdges) { Contact contact = checkEdgeAndEdge(left, leftEdge[0], leftEdge[1], right, rightEdge[0], rightEdge[1], data.restitution, data.friction); if (contact != null) { data.contacts.Add(contact); } } } return data.contacts.Count; }