ClosestPoints() 공개 정적인 메소드

public static ClosestPoints ( ISupportMappable support1, ISupportMappable support2, Jitter.LinearMath.JMatrix &orientation1, Jitter.LinearMath.JMatrix &orientation2, Jitter.LinearMath.JVector &position1, Jitter.LinearMath.JVector &position2, Jitter.LinearMath.JVector &p1, Jitter.LinearMath.JVector &p2, Jitter.LinearMath.JVector &normal ) : bool
support1 ISupportMappable
support2 ISupportMappable
orientation1 Jitter.LinearMath.JMatrix
orientation2 Jitter.LinearMath.JMatrix
position1 Jitter.LinearMath.JVector
position2 Jitter.LinearMath.JVector
p1 Jitter.LinearMath.JVector
p2 Jitter.LinearMath.JVector
normal Jitter.LinearMath.JVector
리턴 bool
예제 #1
0
        private void DetectRigidRigid(RigidBody body1, RigidBody body2)
        {
            bool b1IsMulti = (body1.Shape is Multishape);
            bool b2IsMulti = (body2.Shape is Multishape);

            bool speculative = speculativeContacts ||
                               (body1.EnableSpeculativeContacts || body2.EnableSpeculativeContacts);

            JVector point, normal;
            float   penetration;

            if (!b1IsMulti && !b2IsMulti)
            {
                if (XenoCollide.Detect(body1.Shape, body2.Shape, ref body1.orientation,
                                       ref body2.orientation, ref body1.position, ref body2.position,
                                       out point, out normal, out penetration))
                {
                    JVector point1, point2;
                    FindSupportPoints(body1, body2, body1.Shape, body2.Shape, ref point, ref normal, out point1, out point2);
                    RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                }
                else if (speculative)
                {
                    JVector hit1, hit2;

                    if (GJKCollide.ClosestPoints(body1.Shape, body2.Shape, ref body1.orientation, ref body2.orientation,
                                                 ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                    {
                        JVector delta = hit2 - hit1;

                        if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                        {
                            penetration = delta * normal;

                            if (penetration < 0.0f)
                            {
                                RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                            }
                        }
                    }
                }
            }
            else if (b1IsMulti && b2IsMulti)
            {
                Multishape ms1 = (body1.Shape as Multishape);
                Multishape ms2 = (body2.Shape as Multishape);

                ms1 = ms1.RequestWorkingClone();
                ms2 = ms2.RequestWorkingClone();

                JBBox transformedBoundingBox = body2.boundingBox;
                transformedBoundingBox.InverseTransform(ref body1.position, ref body1.orientation);

                int ms1Length = ms1.Prepare(ref transformedBoundingBox);

                transformedBoundingBox = body1.boundingBox;
                transformedBoundingBox.InverseTransform(ref body2.position, ref body2.orientation);

                int ms2Length = ms2.Prepare(ref transformedBoundingBox);

                if (ms1Length == 0 || ms2Length == 0)
                {
                    ms1.ReturnWorkingClone();
                    ms2.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < ms1Length; i++)
                {
                    ms1.SetCurrentShape(i);

                    for (int e = 0; e < ms2Length; e++)
                    {
                        ms2.SetCurrentShape(e);

                        if (XenoCollide.Detect(ms1, ms2, ref body1.orientation,
                                               ref body2.orientation, ref body1.position, ref body2.position,
                                               out point, out normal, out penetration))
                        {
                            JVector point1, point2;
                            FindSupportPoints(body1, body2, ms1, ms2, ref point, ref normal, out point1, out point2);
                            RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                        }
                        else if (speculative)
                        {
                            JVector hit1, hit2;

                            if (GJKCollide.ClosestPoints(ms1, ms2, ref body1.orientation, ref body2.orientation,
                                                         ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                            {
                                JVector delta = hit2 - hit1;

                                if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                                {
                                    penetration = delta * normal;

                                    if (penetration < 0.0f)
                                    {
                                        RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                                    }
                                }
                            }
                        }
                    }
                }

                ms1.ReturnWorkingClone();
                ms2.ReturnWorkingClone();
            }
            else
            {
                RigidBody b1, b2;

                if (body2.Shape is Multishape)
                {
                    b1 = body2; b2 = body1;
                }
                else
                {
                    b2 = body2; b1 = body1;
                }

                Multishape ms = (b1.Shape as Multishape);

                ms = ms.RequestWorkingClone();

                JBBox transformedBoundingBox = b2.boundingBox;
                transformedBoundingBox.InverseTransform(ref b1.position, ref b1.orientation);

                int msLength = ms.Prepare(ref transformedBoundingBox);

                if (msLength == 0)
                {
                    ms.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < msLength; i++)
                {
                    ms.SetCurrentShape(i);

                    if (XenoCollide.Detect(ms, b2.Shape, ref b1.orientation,
                                           ref b2.orientation, ref b1.position, ref b2.position,
                                           out point, out normal, out penetration))
                    {
                        JVector point1, point2;
                        FindSupportPoints(b1, b2, ms, b2.Shape, ref point, ref normal, out point1, out point2);

                        if (useTerrainNormal && ms is TerrainShape)
                        {
                            (ms as TerrainShape).CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }
                        else if (useTriangleMeshNormal && ms is TriangleMeshShape)
                        {
                            (ms as TriangleMeshShape).CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }

                        RaiseCollisionDetected(b1, b2, ref point1, ref point2, ref normal, penetration);
                    }
                    else if (speculative)
                    {
                        JVector hit1, hit2;

                        if (GJKCollide.ClosestPoints(ms, b2.Shape, ref b1.orientation, ref b2.orientation,
                                                     ref b1.position, ref b2.position, out hit1, out hit2, out normal))
                        {
                            JVector delta = hit2 - hit1;

                            if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                            {
                                penetration = delta * normal;

                                if (penetration < 0.0f)
                                {
                                    RaiseCollisionDetected(b1, b2, ref hit1, ref hit2, ref normal, penetration);
                                }
                            }
                        }
                    }
                }

                ms.ReturnWorkingClone();
            }
        }
예제 #2
0
        private void DetectRigidRigid(RigidBody body1, RigidBody body2)
        {
            // CUSTOM: Added custom detection callbacks (primarily to accommodate actor movement on surfaces).
            var callback1 = body1.ShouldGenerateContact;
            var callback2 = body2.ShouldGenerateContact;

            bool b1IsMulti = (body1.Shape is Multishape);
            bool b2IsMulti = (body2.Shape is Multishape);

            bool speculative = speculativeContacts ||
                               (body1.AreSpeculativeContactsEnabled || body2.AreSpeculativeContactsEnabled);

            JVector point, normal;
            float   penetration;

            if (!b1IsMulti && !b2IsMulti)
            {
                // CUSTOM: Added these callbacks (two rigid bodies).
                if ((callback1 != null && !callback1(body2, null)) || (callback2 != null && !callback2(body1, null)))
                {
                    return;
                }

                if (XenoCollide.Detect(body1.Shape, body2.Shape, ref body1.orientation,
                                       ref body2.orientation, ref body1.position, ref body2.position,
                                       out point, out normal, out penetration))
                {
                    JVector point1, point2;
                    FindSupportPoints(body1, body2, body1.Shape, body2.Shape, ref point, ref normal, out point1, out point2);
                    RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                }
                else if (speculative)
                {
                    JVector hit1, hit2;

                    if (GJKCollide.ClosestPoints(body1.Shape, body2.Shape, ref body1.orientation, ref body2.orientation,
                                                 ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                    {
                        JVector delta = hit2 - hit1;

                        if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                        {
                            penetration = delta * normal;

                            if (penetration < 0.0f)
                            {
                                RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                            }
                        }
                    }
                }
            }
            else if (b1IsMulti && b2IsMulti)
            {
                Multishape ms1 = (body1.Shape as Multishape);
                Multishape ms2 = (body2.Shape as Multishape);

                ms1 = ms1.RequestWorkingClone();
                ms2 = ms2.RequestWorkingClone();

                JBBox transformedBoundingBox = body2.boundingBox;
                transformedBoundingBox.InverseTransform(ref body1.position, ref body1.orientation);

                int ms1Length = ms1.Prepare(ref transformedBoundingBox);

                transformedBoundingBox = body1.boundingBox;
                transformedBoundingBox.InverseTransform(ref body2.position, ref body2.orientation);

                int ms2Length = ms2.Prepare(ref transformedBoundingBox);

                if (ms1Length == 0 || ms2Length == 0)
                {
                    ms1.ReturnWorkingClone();
                    ms2.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < ms1Length; i++)
                {
                    ms1.SetCurrentShape(i);

                    for (int e = 0; e < ms2Length; e++)
                    {
                        ms2.SetCurrentShape(e);

                        if (XenoCollide.Detect(ms1, ms2, ref body1.orientation,
                                               ref body2.orientation, ref body1.position, ref body2.position,
                                               out point, out normal, out penetration))
                        {
                            JVector point1, point2;
                            FindSupportPoints(body1, body2, ms1, ms2, ref point, ref normal, out point1, out point2);
                            RaiseCollisionDetected(body1, body2, ref point1, ref point2, ref normal, penetration);
                        }
                        else if (speculative)
                        {
                            JVector hit1, hit2;

                            if (GJKCollide.ClosestPoints(ms1, ms2, ref body1.orientation, ref body2.orientation,
                                                         ref body1.position, ref body2.position, out hit1, out hit2, out normal))
                            {
                                JVector delta = hit2 - hit1;

                                if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                                {
                                    penetration = delta * normal;

                                    if (penetration < 0.0f)
                                    {
                                        RaiseCollisionDetected(body1, body2, ref hit1, ref hit2, ref normal, penetration);
                                    }
                                }
                            }
                        }
                    }
                }

                ms1.ReturnWorkingClone();
                ms2.ReturnWorkingClone();
            }
            else
            {
                RigidBody b1, b2;

                if (body2.Shape is Multishape)
                {
                    // CUSTOM: Swapped callbacks here as well.
                    b1 = body2;
                    b2 = body1;

                    // A proper swap here (using a temporary variable) isn't necessary since, by this point, the other
                    // callback (attached to the static body) is intentionally not used.
                    callback2 = callback1;
                }
                else
                {
                    b2 = body2;
                    b1 = body1;
                }

                Multishape ms = (b1.Shape as Multishape);

                ms = ms.RequestWorkingClone();

                JBBox transformedBoundingBox = b2.boundingBox;
                transformedBoundingBox.InverseTransform(ref b1.position, ref b1.orientation);

                int msLength = ms.Prepare(ref transformedBoundingBox);

                if (msLength == 0)
                {
                    ms.ReturnWorkingClone();
                    return;
                }

                for (int i = 0; i < msLength; i++)
                {
                    ms.SetCurrentShape(i);

                    // CUSTOM: Added this callback (to allow specific triangle collisions to be ignored).
                    bool shouldCollideWith = ms is TriangleMeshShape tMesh && (callback2 == null ||
                                                                               callback2(b1, tMesh.CurrentTriangle));

                    if (shouldCollideWith && XenoCollide.Detect(ms, b2.Shape, ref b1.orientation,
                                                                ref b2.orientation, ref b1.position, ref b2.position,
                                                                out point, out normal, out penetration))
                    {
                        JVector[] triangle = null;
                        FindSupportPoints(b1, b2, ms, b2.Shape, ref point, ref normal, out var point1, out var point2);

                        if (useTerrainNormal && ms is TerrainShape)
                        {
                            (ms as TerrainShape).CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }
                        else if (useTriangleMeshNormal)
                        {
                            tMesh    = ms as TriangleMeshShape;
                            triangle = tMesh.CurrentTriangle;
                            tMesh.CollisionNormal(out normal);
                            JVector.Transform(ref normal, ref b1.orientation, out normal);
                        }

                        RaiseCollisionDetected(b1, b2, ref point1, ref point2, ref normal, triangle, penetration);
                    }
                    else if (speculative)
                    {
                        JVector hit1, hit2;

                        if (GJKCollide.ClosestPoints(ms, b2.Shape, ref b1.orientation, ref b2.orientation,
                                                     ref b1.position, ref b2.position, out hit1, out hit2, out normal))
                        {
                            JVector delta = hit2 - hit1;

                            if (delta.LengthSquared() < (body1.sweptDirection - body2.sweptDirection).LengthSquared())
                            {
                                penetration = delta * normal;

                                if (penetration < 0.0f)
                                {
                                    RaiseCollisionDetected(b1, b2, ref hit1, ref hit2, ref normal, penetration);
                                }
                            }
                        }
                    }
                }

                ms.ReturnWorkingClone();
            }
        }