Exemple #1
0
 public BVHNode(Vector3 minBound, Vector3 maxBound, BVHNode leftChild, BVHNode rightChild, int start, int end)
 {
     bound             = new BoundingBox(minBound, maxBound);
     lChild            = leftChild;
     rChild            = rightChild;
     surfaceIndexStart = start;
     surfaceIndexEnd   = end;
 }
Exemple #2
0
 public BVHNode()
 {
     bound             = new BoundingBox();
     lChild            = null;
     rChild            = null;
     surfaceIndexStart = -1;
     surfaceIndexEnd   = -1;
 }
Exemple #3
0
 public void Build(VertexPositionTexture[] verts, int[] inds)
 {
     tris = new List <Triangle>(inds.Length / 3);
     for (int i = 0; i < inds.Length;)
     {
         int i1 = inds[i++];
         int i2 = inds[i++];
         int i3 = inds[i++];
         tris.Add(new Triangle(
                      verts[i1].Position,
                      verts[i2].Position,
                      verts[i3].Position
                      ));
     }
     root = CreateTree(0, tris.Count);
 }
Exemple #4
0
        private BVHNode CreateTree(int start, int end)
        {
            Vector3 minB = new Vector3(float.MaxValue);
            Vector3 maxB = new Vector3(-float.MaxValue);

            for (int i = start; i < end; i++)
            {
                minB = Vector3.Min(tris[i].MinBound, minB);
                maxB = Vector3.Max(tris[i].MaxBound, maxB);
            }

            // Check For Leaf Node Condition
            if (end - start <= 1)
            {
                return(new BVHNode(minB, maxB, null, null, start, end));
            }

            // Sort On Widest Dimension
            Vector3 dim = maxB - minB;

            if (dim.X >= dim.Y && dim.X >= dim.Z)
            {
                tris.Sort(start, end - start, F_SORT_X);
            }
            else if (dim.Y >= dim.Z)
            {
                tris.Sort(start, end - start, F_SORT_Y);
            }
            else
            {
                tris.Sort(start, end - start, F_SORT_Z);
            }

            // Create Children
            int     e          = (start + end) / 2;
            BVHNode leftChild  = CreateTree(start, e);
            BVHNode rightChild = CreateTree(e, end);

            return(new BVHNode(minB, maxB, leftChild, rightChild, start, end));
        }
Exemple #5
0
        private bool IntersectHelper(BVHNode node, ref IntersectionRecord outRecord, Ray rayIn)
        {
            if (node.IsLeaf)
            {
                outRecord.T = float.PositiveInfinity;
                IntersectionRecord tempRec = new IntersectionRecord();
                for (int i = node.surfaceIndexStart; i < node.surfaceIndexEnd; i++)
                {
                    if (tris[i].Intersect(ref tempRec, rayIn))
                    {
                        // check if current t value is smaller
                        if (tempRec.T < outRecord.T)
                        {
                            outRecord = tempRec;
                        }
                    }
                }
                return(!float.IsPositiveInfinity(outRecord.T));
            }
            else
            {
                float t1 = node.lChild.IntersectTime(rayIn);
                float t2 = node.rChild.IntersectTime(rayIn);
                if (float.IsNaN(t1))
                {
                    if (float.IsNaN(t2))
                    {
                        return(false);
                    }
                    return(IntersectHelper(node.rChild, ref outRecord, rayIn));
                }
                if (float.IsNaN(t2))
                {
                    return(IntersectHelper(node.lChild, ref outRecord, rayIn));
                }

                // Need To Check Both
                IntersectionRecord lRec = new IntersectionRecord();
                IntersectionRecord rRec = new IntersectionRecord();
                bool lHit, rHit;
                lHit = IntersectHelper(node.lChild, ref lRec, rayIn);
                rHit = IntersectHelper(node.rChild, ref rRec, rayIn);
                if (lHit && rHit)
                {
                    outRecord = lRec.T <= rRec.T ? lRec : rRec;
                }
                else if (lHit)
                {
                    outRecord = lRec;
                }
                else if (rHit)
                {
                    outRecord = rRec;
                }
                else
                {
                    return(false);
                }
                return(true);
            }
        }