예제 #1
0
        /// <summary>
        /// CollDetectBoxStaticMeshOverlap
        /// </summary>
        /// <param name="oldBox"></param>
        /// <param name="newBox"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        /// <returns>bool</returns>
        private static bool CollDetectBoxStaticMeshOverlap(Box oldBox,
                                                           Box newBox,
                                                           TriangleMesh mesh,
                                                           ref CollDetectInfo info,
                                                           float collTolerance,
                                                           CollisionFunctor collisionFunctor)
        {
            float boxRadius = newBox.GetBoundingRadiusAroundCentre();

            #region REFERENCE: Vector3 boxCentre = newBox.GetCentre();
            Vector3 boxCentre;
            newBox.GetCentre(out boxCentre);
            // Deano need to trasnform the box center into mesh space
            Matrix invTransformMatrix = mesh.InverseTransformMatrix;
            Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre);
            #endregion

            BoundingBox bb = BoundingBoxHelper.InitialBox;
            BoundingBoxHelper.AddBox(newBox, ref bb);

            bool collision = false;

            int[] potTriArray = IntStackAlloc();

            // aabox is done in mesh space and handles the mesh transform correctly
            int numTriangles = mesh.GetTrianglesIntersectingtAABox(potTriArray, MaxLocalStackTris, ref bb);

            for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
            {
                IndexedTriangle meshTriangle = mesh.GetTriangle(potTriArray[iTriangle]);

                // quick early test is done in mesh space
                float dist = meshTriangle.Plane.DotCoordinate(boxCentre);

                // BEN-BUG-FIX: Fixed by chaning 0.0F to -boxRadius.
                if (dist > boxRadius || dist < -boxRadius)
                {
                    continue;
                }

                if (DoOverlapBoxTriangleTest(
                        oldBox, newBox,
                        ref meshTriangle,
                        mesh,
                        ref info,
                        collTolerance,
                        collisionFunctor))
                {
                    collision = true;
                }
            }

            FreeStackAlloc(potTriArray);

            return(collision);
        }
예제 #2
0
        private static void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            var mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh;

            var oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box;
            var newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box;

            oldBox.GetCentre(out var oldCentre);
            newBox.GetCentre(out var newCentre);

            Vector3.Subtract(ref newCentre, ref oldCentre, out var delta);

            var boxMinLen  = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z));
            var nPositions = 1 + (int)(delta.Length() / boxMinLen);

            if (nPositions > 50)
            {
                System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test");
                nPositions = 50;
            }

            if (nPositions == 1)
            {
                CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor);
            }
            else
            {
                var bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddBox(oldBox, ref bb);
                BoundingBoxHelper.AddBox(newBox, ref bb);
                unsafe
                {
                    var potentialTriangles = stackalloc int[MaxLocalStackTris];
                    {
                        var numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
                        if (numTriangles <= 0)
                        {
                            return;
                        }
                        for (var i = 0; i <= nPositions; ++i)
                        {
                            var frac = (float)i / nPositions;
                            Vector3.Multiply(ref delta, frac, out var centre);
                            Vector3.Add(ref centre, ref oldCentre, out centre);

                            var orient = Matrix.Add(Matrix.Multiply(oldBox.Orientation, 1.0f - frac), Matrix.Multiply(newBox.Orientation, frac));
                            var box    = new Box(centre - 0.5f * Vector3.TransformNormal(newBox.SideLengths, orient), orient, newBox.SideLengths);

                            CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor);
                        }
                    }
                }
            }
        }
예제 #3
0
        private static bool CollDetectBoxStaticMeshOverlap(Box oldBox, Box newBox, TriangleMesh mesh, ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            var boxRadius = newBox.GetBoundingRadiusAroundCentre();

            newBox.GetCentre(out var boxCentre);

            var invTransformMatrix = mesh.InverseTransformMatrix;

            Vector3.Transform(ref boxCentre, ref invTransformMatrix, out boxCentre);

            var bb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddBox(newBox, ref bb);

            unsafe
            {
                var collision          = false;
                var potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
                    var numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                    for (var iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                    {
                        var meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);


                        var dist = meshTriangle.Plane.DotCoordinate(boxCentre);


                        if (dist > boxRadius || dist < -boxRadius)
                        {
                            continue;
                        }

                        if (DoOverlapBoxTriangleTest(oldBox, newBox, ref meshTriangle, mesh, ref info, collTolerance, collisionFunctor))
                        {
                            collision = true;
                        }
                    }
                }
                return(collision);
            }
        }
예제 #4
0
        private void CollDetectSweep(ref CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            // todo - proper swept test
            // note - mesh is static and its triangles are in world space
            TriangleMesh mesh = info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1) as TriangleMesh;

            Box oldBox = info.Skin0.GetPrimitiveOldWorld(info.IndexPrim0) as Box;
            Box newBox = info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0) as Box;

            Vector3 oldCentre;

            oldBox.GetCentre(out oldCentre);
            Vector3 newCentre;

            newBox.GetCentre(out newCentre);

            Vector3 delta;

            Vector3.Subtract(ref newCentre, ref oldCentre, out delta);

            float boxMinLen  = 0.5f * System.Math.Min(newBox.SideLengths.X, System.Math.Min(newBox.SideLengths.Y, newBox.SideLengths.Z));
            int   nPositions = 1 + (int)(delta.Length() / boxMinLen);

            // limit the max positions...
            if (nPositions > 50)
            {
                System.Diagnostics.Debug.WriteLine("Warning - clamping max positions in swept box test");
                nPositions = 50;
            }
            if (nPositions == 1)
            {
                CollDetectBoxStaticMeshOverlap(oldBox, newBox, mesh, ref info, collTolerance, collisionFunctor);
            }
            else
            {
                BoundingBox bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddBox(oldBox, ref bb);
                BoundingBoxHelper.AddBox(newBox, ref bb);
                unsafe
                {
#if USE_STACKALLOC
                    int *potentialTriangles = stackalloc int[MaxLocalStackTris];
                    {
#else
                    int[] potTriArray = IntStackAlloc();
                    fixed(int *potentialTriangles = potTriArray)
                    {
#endif
                        int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);
                        if (numTriangles > 0)
                        {
                            for (int i = 0; i <= nPositions; ++i)
                            {
                                float   frac = ((float)i) / nPositions;
                                Vector3 centre;
                                Vector3.Multiply(ref delta, frac, out centre);
                                Vector3.Add(ref centre, ref oldCentre, out centre);

                                Matrix orient = Matrix.Add(Matrix.Multiply(oldBox.Orientation, 1.0f - frac), Matrix.Multiply(newBox.Orientation, frac));

                                Box box = new Box(centre - 0.5f * Vector3.Transform(newBox.SideLengths, orient), orient, newBox.SideLengths);
                                // ideally we'd break if we get one collision... but that stops us getting multiple collisions
                                // when we enter a corner (two walls meeting) - can let us pass through
                                CollDetectBoxStaticMeshOverlap(oldBox, box, mesh, ref info, collTolerance, collisionFunctor);
                            }
                        }
#if USE_STACKALLOC
                    }
#else
                    }
                    FreeStackAlloc(potTriArray);
#endif
                }
            }
        }