// BEN-PATCH: Someone else's patch... needs testing but the idea seems correct.
        /// <summary>
        /// GetTrianglesIntersectingtAABox
        /// </summary>
        /// <param name="triangles"></param>
        /// <param name="maxTriangles"></param>
        /// <param name="bb"></param>
        /// <returns>int</returns>
        public unsafe int GetTrianglesIntersectingtAABox(int *triangles, int maxTriangles, ref BoundingBox bb)
        {
            // rotated aabb
            BoundingBox rotBB = bb;

            Vector3 bbCorner = new Vector3();
            Vector3 bbCornerT;

            for (int a = 0; a < 2; a++)
            {
                for (int b = 0; b < 2; b++)
                {
                    for (int c = 0; c < 2; c++)
                    {
                        bbCorner.X = ((a == 0) ? bb.Min.X : bb.Max.X);
                        bbCorner.Y = ((b == 0) ? bb.Min.Y : bb.Max.Y);
                        bbCorner.Z = ((c == 0) ? bb.Min.Z : bb.Max.Z);
                        bbCornerT  = Vector3.Transform(bbCorner, invTransform);

                        BoundingBoxHelper.AddPoint(ref bbCornerT, ref rotBB);
                    }
                }
            }
            return(octree.GetTrianglesIntersectingtAABox(triangles, maxTriangles, ref rotBB));
        }
Exemple #2
0
        /// <summary>
        /// SegmentIntersect
        /// </summary>
        /// <param name="frac"></param>
        /// <param name="pos"></param>
        /// <param name="normal"></param>
        /// <param name="seg"></param>
        /// <returns>bool</returns>
        public override bool SegmentIntersect(out float frac, out Vector3 pos, out Vector3 normal, Segment seg)
        {
            // move segment into octree space
            seg.Origin = Vector3.Transform(seg.Origin, invTransform);
            seg.Delta  = Vector3.TransformNormal(seg.Delta, invTransform);


            BoundingBox segBox = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSegment(seg, ref segBox);

            int[] potTriArray = DetectFunctor.IntStackAlloc();

            int numTriangles = GetTrianglesIntersectingtAABox(potTriArray, DetectFunctor.MaxLocalStackTris, ref segBox);

            float tv1, tv2;

            pos    = Vector3.Zero;
            normal = Vector3.Zero;

            float bestFrac = float.MaxValue;

            for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
            {
                IndexedTriangle meshTriangle = GetTriangle(potTriArray[iTriangle]);
                float           thisFrac;
                Triangle        tri = new Triangle(GetVertex(meshTriangle.GetVertexIndex(0)),
                                                   GetVertex(meshTriangle.GetVertexIndex(1)),
                                                   GetVertex(meshTriangle.GetVertexIndex(2)));

                if (Intersection.SegmentTriangleIntersection(out thisFrac, out tv1, out tv2, seg, tri))
                {
                    if (thisFrac < bestFrac)
                    {
                        bestFrac = thisFrac;
                        // re-project
                        pos    = Vector3.Transform(seg.GetPoint(thisFrac), transformMatrix);
                        normal = Vector3.TransformNormal(meshTriangle.Plane.Normal, transformMatrix);
                    }
                }
            }

            frac = bestFrac;
            if (bestFrac < float.MaxValue)
            {
                DetectFunctor.FreeStackAlloc(potTriArray);
                return(true);
            }
            else
            {
                DetectFunctor.FreeStackAlloc(potTriArray);
                return(false);
            }
        }
        public unsafe int GetTrianglesIntersectingtAABox(int *triangles, int maxTriangles, ref BoundingBox bb)
        {
            // move segment into octree space
            Vector3 aabbMin = Vector3.Transform(bb.Min, invTransform);
            Vector3 aabbMax = Vector3.Transform(bb.Max, invTransform);

            // rotated aabb
            BoundingBox rotBB = bb;

            BoundingBoxHelper.AddPoint(ref aabbMin, ref rotBB);
            BoundingBoxHelper.AddPoint(ref aabbMax, ref rotBB);
            return(octree.GetTrianglesIntersectingtAABox(triangles, maxTriangles, ref rotBB));
        }
        public override bool SegmentIntersect(out float frac, out Vector3 pos, out Vector3 normal, Segment seg)
        {
            BoundingBox segBox = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSegment(seg, ref segBox);

            unsafe
            {
#if USE_STACKALLOC
                int *potentialTriangles = stackalloc int[MaxLocalStackTris];
                {
#else
                int[] potTriArray = DetectFunctor.IntStackAlloc();
                fixed(int *potentialTriangles = potTriArray)
                {
#endif
                    int numTriangles = GetTrianglesIntersectingtAABox(potentialTriangles, DetectFunctor.MaxLocalStackSCPI, ref segBox);

                    float tv1, tv2;

                    pos    = Vector3.Zero;
                    normal = Vector3.Zero;

                    // move segment into octree space
                    seg.Origin = Vector3.Transform(seg.Origin, invTransform);
                    seg.Delta  = Vector3.TransformNormal(seg.Delta, invTransform);

                    float bestFrac = float.MaxValue;
                    for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                    {
                        IndexedTriangle meshTriangle = GetTriangle(potentialTriangles[iTriangle]);
                        float           thisFrac;
                        Triangle        tri = new Triangle(GetVertex(meshTriangle.GetVertexIndex(0)),
                                                           GetVertex(meshTriangle.GetVertexIndex(1)),
                                                           GetVertex(meshTriangle.GetVertexIndex(2)));

                        if (Intersection.SegmentTriangleIntersection(out thisFrac, out tv1, out tv2, seg, tri))
                        {
                            if (thisFrac < bestFrac)
                            {
                                bestFrac = thisFrac;
                                pos      = seg.GetPoint(thisFrac);
                                normal   = meshTriangle.Plane.Normal;
                            }
                        }
                    }

                    frac = bestFrac;
                    if (bestFrac < float.MaxValue)
                    {
                        DetectFunctor.FreeStackAlloc(potTriArray);
                        return(true);
                    }
                    else
                    {
                        DetectFunctor.FreeStackAlloc(potTriArray);
                        return(false);
                    }
#if USE_STACKALLOC
                }
#else
                }
#endif
            }
        }