/// <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;
        }