예제 #1
0
        int flattenBVHTree(BVHBuildNode node, ref int offset)
        {
            LinearBVHNode linearNode = nodes[offset];

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

            if (node.nShapes > 0)
            {
                Debug.Assert(node.childLeft != null && node.childRight != null);
                linearNode.ShapesOffset = node.firstPrimOffset;
                linearNode.nShapes      = (byte)node.nShapes;
            }
            else
            {
                // Creater interior flattened BVH node
                linearNode.axis    = (byte)node.splitAxis;
                linearNode.nShapes = 0;
                flattenBVHTree(node.childLeft, ref offset);
                linearNode.secondChildOffset = flattenBVHTree(node.childRight, ref offset);
            }

            return(myOffset);
        }
예제 #2
0
        bool Intersect(Ray ray, ref LFloat isect)
        {
            if (nodes == null || nodes.Count == 0)
            {
                return(false);
            }
            bool     hit    = false;
            LVector3 invDir = new LVector3(1 / ray.d.x, 1 / ray.d.y, 1 / ray.d.z);

            int[] dirIsNeg = new int[3] {
                invDir.x < 0 ? 1 : 0,
                invDir.y < 0 ? 1 : 0,
                invDir.z < 0 ? 1 : 0
            };
            // Follow ray through BVH nodes to find Shape intersections
            int todoOffset = 0, nodeNum = 0;

            int[]  todo = new int[64];
            LFloat tmin = LFloat.zero;
            LFloat tmax = LFloat.zero;

            while (true)
            {
                LinearBVHNode node = nodes[nodeNum];
                // Check ray against BVH node
                if (IntersectP(node.bounds, ray, invDir, dirIsNeg, tmin, tmax))
                {
                    if (node.nShapes > 0)
                    {
                        // Intersect ray with Shapes in leaf BVH node
                        for (int i = 0; i < node.nShapes; ++i)
                        {
                            if (Shapes[node.ShapesOffset + i].TestWith(ray, ref isect))
                            {
                                hit = true;
                            }
                        }

                        if (todoOffset == 0)
                        {
                            break;
                        }
                        nodeNum = todo[--todoOffset];
                    }
                    else
                    {
                        // Put far BVH node on _todo_ stack, advance to near node
                        if (dirIsNeg[node.axis] != 0)
                        {
                            todo[todoOffset++] = nodeNum + 1;
                            nodeNum            = node.secondChildOffset;
                        }
                        else
                        {
                            todo[todoOffset++] = node.secondChildOffset;
                            nodeNum            = nodeNum + 1;
                        }
                    }
                }
                else
                {
                    if (todoOffset == 0)
                    {
                        break;
                    }
                    nodeNum = todo[--todoOffset];
                }
            }

            return(hit);
        }
예제 #3
0
        bool IntersectP(Ray ray, LFloat tmin, LFloat tmax)
        {
            if (nodes == null || nodes.Count == 0)
            {
                return(false);
            }
            LVector3 invDir = new LVector3(1 / ray.d.x, 1 / ray.d.y, 1 / ray.d.z);

            int[] dirIsNeg = new int[3] {
                invDir.x < 0 ? 1 : 0,
                invDir.y < 0 ? 1 : 0,
                invDir.z < 0 ? 1 : 0
            };
            int[] todo = new int[64]; //最大堆栈数
            int   todoOffset = 0, nodeNum = 0;

            while (true)
            {
                LinearBVHNode node = nodes[nodeNum];
                if (IntersectP(node.bounds, ray, invDir, dirIsNeg, tmin, tmax))
                {
                    // Process BVH node _node_ for traversal
                    if (node.nShapes > 0)
                    {
                        for (int i = 0; i < node.nShapes; ++i)
                        {
                            if (Shapes[node.ShapesOffset + i].TestWith(ray))
                            {
                                return(true);
                            }
                        }

                        if (todoOffset == 0)
                        {
                            break;
                        }
                        nodeNum = todo[--todoOffset];
                    }
                    else
                    {
                        if (dirIsNeg[node.axis] != 0)
                        {
                            /// second child first
                            todo[todoOffset++] = nodeNum + 1;
                            nodeNum            = node.secondChildOffset;
                        }
                        else
                        {
                            todo[todoOffset++] = node.secondChildOffset;
                            nodeNum            = nodeNum + 1;
                        }
                    }
                }
                else
                {
                    if (todoOffset == 0)
                    {
                        break;
                    }
                    nodeNum = todo[--todoOffset];
                }
            }

            return(false);
        }