Пример #1
0
        public static bool boxAndBox(
            BoxRigid one,
            BoxRigid two,
            ref CollisionData data
            )
        {
            if (!IntersectionTestsboxAndBox(one, two))
            {
                return(false);
            }

            // Find the vector between the two centres
            Vector3 toCentre = two.PositionCenterEngine - one.PositionCenterEngine;

            // We start assuming there is no contact
            float pen  = float.MaxValue;
            int   best = 0xffffff;

            // Now we check each axes, returning if it gives us
            // a separating axis, and keeping track of the axis with
            // the smallest penetration otherwise.

            if (!tryAxis(one, two, (one).XAxis, toCentre, 0, ref pen, ref best))
            {
                return(false);
            }
            if (!tryAxis(one, two, (one).YAxis, toCentre, 1, ref pen, ref best))
            {
                return(false);
            }

            if (!tryAxis(one, two, (two).XAxis, toCentre, 2, ref pen, ref best))
            {
                return(false);
            }
            if (!tryAxis(one, two, (two).YAxis, toCentre, 3, ref pen, ref best))
            {
                return(false);
            }


            // Store the best axis-major, in case we run into almost
            // parallel edge collisions later
            int bestSingleAxis = best;

            // Make sure we've got a result.

            if (best != 0xffffff)
            {
                // We now know there's a collision, and we know which
                // of the axes gave the smallest penetration. We now
                // can deal with it in different ways depending on
                // the case.
                if (best < 2)
                {
                    // We've got a vertex of box two on a face of box one.
                    fillPointFaceBoxBox(one, two, toCentre, ref data, best, pen);
                    one.SetCanSleep(true);
                    two.SetCanSleep(true);
                    data.addContacts(1);
                }
                else if (best < 4)
                {
                    fillPointFaceBoxBox(two, one, toCentre * -1.0f, ref data, best - 2, pen);
                    one.SetCanSleep(true);
                    two.SetCanSleep(true);
                    data.addContacts(1);
                }
                return(true);
            }
            return(false);
        }
Пример #2
0
        public static bool boxAndHalfSpace(
            BoxRigid box,
            CollisionPlane plane,
            ref CollisionData data
            )
        {
            // Make sure we have contacts
            if (data.contactsLeft <= 0)
            {
                return(false);
            }

            // Check for intersection
            if (!IntersectionTestboxAndHalfSpace(box, plane))
            {
                return(false);
            }

            bool b            = false;
            int  contactsUsed = 0;

            for (int i = 0; i < 4; i++)
            {
                Vector3 vertexPos = ((BoxRigid)box).vertices[i].Position;

                // Calculate the distance from the plane
                float vertexDistance = Vector3.Dot(vertexPos, plane.Direction);

                // Compare this to the plane's distance
                if (vertexDistance <= plane.Offset)
                {
                    b = true;
                    // Create the contact data.

                    // The contact point is halfway between the vertex and the
                    // plane - we multiply the direction by half the separation
                    // distance and add the vertex location.

                    Contact c = new Contact();
                    c.ContactPoint  = plane.Direction;
                    c.ContactPoint *= (0.5f * (plane.Offset - vertexDistance));
                    c.ContactPoint  = vertexPos;
                    c.ContactNormal = plane.Direction;
                    c.Penetration   = plane.Offset - vertexDistance;

                    c.Particle[0] = box;
                    c.Particle[1] = null;
                    c.Friction    = data.friction;
                    c.Restitution = data.restitution;

                    c.Friction    = StaticData.FrictionTable[(int)plane.Material][(int)box.GetMaterial()];
                    c.Restitution = StaticData.RestitutionTable[(int)plane.Material][(int)box.GetMaterial()];


                    c.ContactToWorld.M11 = plane.Direction.X;
                    c.ContactToWorld.M12 = -plane.Direction.Y;
                    c.ContactToWorld.M21 = plane.Direction.Y;
                    c.ContactToWorld.M22 = plane.Direction.X;

                    data.contacts.Add(c);

                    box.SetCanSleep(true);

                    data.index++;
                    data.contactsLeft--;
                    data.contactCount++;


                    contactsUsed++;
                }
            }
            return(b);
        }