Ejemplo n.º 1
0
        public int flattenBVHTree(BVHBuildNode node, ref int offset)
        {
            LinearBVHNode linearNode = nodes[offset];

            linearNode.bounds = node.bounds;
            int myOffset = (offset)++;

            if (node.nPrimitives > 0)
            {
                //CHECK(!node->children[0] && !node->children[1]);
                //CHECK_LT(node->nPrimitives, 65536);
                linearNode.primitivesOffset = node.firstPrimOffset;
                linearNode.nPrimitives      = node.nPrimitives;
            }
            else
            {
                // Create interior flattened BVH node
                linearNode.axis        = Convert.ToByte(node.splitAxis);
                linearNode.nPrimitives = 0;
                flattenBVHTree(node.children[0], ref offset);
                linearNode.secondChildOffset =
                    flattenBVHTree(node.children[1], ref offset);
            }
            return(myOffset);
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        public override bool IntersectP(Ray ray)
        {
            if (nodes == null)
            {
                return(false);
            }

            //ProfilePhase p(Prof::AccelIntersectP);
            Vector3D invDir = new Vector3D(1.0 / ray.Direction.X, 1.0 / ray.Direction.Y, 1.0 / ray.Direction.Z);

            bool[] dirIsNeg = new bool[3] {
                invDir.X < 0, invDir.Y < 0, invDir.Z < 0
            };
            int[] nodesToVisit = new int[64];
            int   toVisitOffset = 0, currentNodeIndex = 0;

            while (true)
            {
                LinearBVHNode node = nodes[currentNodeIndex];
                if (node.bounds.IntersectP(ray, invDir, dirIsNeg))
                {
                    // Process BVH node _node_ for traversal
                    if (node.nPrimitives > 0)
                    {
                        for (int i = 0; i < node.nPrimitives; ++i)
                        {
                            if (primitives[node.primitivesOffset + i].IntersectP(
                                    ray))
                            {
                                return(true);
                            }
                        }
                        if (toVisitOffset == 0)
                        {
                            break;
                        }

                        currentNodeIndex = nodesToVisit[--toVisitOffset];
                    }
                    else
                    {
                        if (dirIsNeg[node.axis])
                        {
                            /// second child first
                            nodesToVisit[toVisitOffset++] = currentNodeIndex + 1;
                            currentNodeIndex = node.secondChildOffset;
                        }
                        else
                        {
                            nodesToVisit[toVisitOffset++] = node.secondChildOffset;
                            currentNodeIndex = currentNodeIndex + 1;
                        }
                    }
                }
                else
                {
                    if (toVisitOffset == 0)
                    {
                        break;
                    }

                    currentNodeIndex = nodesToVisit[--toVisitOffset];
                }
            }
            return(false);
        }
Ejemplo n.º 3
0
        /// <inheritdoc />
        public override bool Intersect(Ray ray, out SurfaceInteraction isect)
        {
            isect = null;

            if (nodes == null)
            {
                return(false);
            }

            //ProfilePhase p(Prof::AccelIntersect);
            bool     hit    = false;
            Vector3D invDir = new Vector3D(1.0 / ray.Direction.X, 1.0 / ray.Direction.Y, 1.0 / ray.Direction.Z);

            bool[] dirIsNeg = new bool[3] {
                invDir.X < 0, invDir.Y < 0, invDir.Z < 0
            };
            // Follow ray through BVH nodes to find primitive intersections
            int toVisitOffset = 0, currentNodeIndex = 0;

            int[] nodesToVisit = new int[64];
            while (true)
            {
                LinearBVHNode node = nodes[currentNodeIndex];
                // Check ray against BVH node
                if (node.bounds.IntersectP(ray, invDir, dirIsNeg))
                {
                    if (node.nPrimitives > 0)
                    {
                        // Intersect ray with primitives in leaf BVH node
                        for (int i = 0; i < node.nPrimitives; ++i)
                        {
                            if (primitives[node.primitivesOffset + i].Intersect(
                                    ray, out isect))
                            {
                                hit = true;
                            }
                        }

                        if (toVisitOffset == 0)
                        {
                            break;
                        }

                        currentNodeIndex = nodesToVisit[--toVisitOffset];
                    }
                    else
                    {
                        // Put far BVH node on _nodesToVisit_ stack, advance to near
                        // node
                        if (dirIsNeg[node.axis])
                        {
                            nodesToVisit[toVisitOffset++] = currentNodeIndex + 1;
                            currentNodeIndex = node.secondChildOffset;
                        }
                        else
                        {
                            nodesToVisit[toVisitOffset++] = node.secondChildOffset;
                            currentNodeIndex = currentNodeIndex + 1;
                        }
                    }
                }
                else
                {
                    if (toVisitOffset == 0)
                    {
                        break;
                    }

                    currentNodeIndex = nodesToVisit[--toVisitOffset];
                }
            }
            return(hit);
        }