Esempio n. 1
0
        /// <summary>
        /// Traverses the specified graph path</summary>
        /// <param name="graphPath">The graph path</param>
        /// <param name="action">The render action</param>
        /// <param name="camera">The camera</param>
        /// <param name="list">The list</param>
        /// <returns></returns>
        public override TraverseState Traverse(Stack <SceneNode> graphPath, IRenderAction action, Camera camera, ICollection <TraverseNode> list)
        {
            // Get the "top matrix" before we push a new matrix on to it, just in case we need
            //  it for the bounding box test.
            Matrix4F parentToWorld = action.TopMatrix;

            // Push matrix onto the matrix stack even if we're not visible because this class
            //  implements the marker interface ISetsLocalTransform.
            action.PushMatrix(m_node.Transform, true);

            // If node is invisible then cull
            if (!m_node.Visible)
            {
                return(TraverseState.Cull);
            }

            TraverseState dResult = action.TraverseState;

            if (dResult == TraverseState.None)
            {
                // Test if bounding sphere is contained in frustum
                if (s_enableVFCull)
                {
                    // Construct bounding box
                    Box box = new Box();
                    box.Extend(m_node.BoundingBox);

                    // Transform the bounding box into view space
                    Matrix4F localToView = Matrix4F.Multiply(parentToWorld, camera.ViewMatrix);
                    box.Transform(localToView);

                    if (!camera.Frustum.Contains(box))
                    {
                        dResult = TraverseState.Cull;
                    }
                }
            }
            return(dResult);
        }
        public bool RayCastStackless(int index)
        {
            LBVHNODE current      = NativeNodes[0];
            float3   rayDirection = Rays[index].Direction;

            // ----------------------------------------------------------------------------------------------------
            float sA = rayDirection[current.SplitAxis];

            current.NearNodeID = math.@select(current.LChildID, current.RChildID, sA < 0f);
            current.FarNodeID  = math.@select(current.RChildID, current.LChildID, sA < 0f);
            // ----------------------------------------------------------------------------------------------------

            int rootNearID = current.NearNodeID;
            int rootNodeID = current.NodeID;

            current = NativeNodes[rootNearID];

            TraverseState state     = TraverseState.FromParent;
            bool          intersect = false;

            while (current.NodeID != rootNodeID)
            {
                switch (state)
                {
                case TraverseState.FromChild:

                    int cID = current.NodeID;

                    current = NativeNodes[current.ParentID];

                    // ----------------------------------------------------------------------------------------------------
                    sA = rayDirection[current.SplitAxis];
                    current.NearNodeID = math.@select(current.LChildID, current.RChildID, sA < 0f);
                    current.FarNodeID  = math.@select(current.RChildID, current.LChildID, sA < 0f);

                    // ----------------------------------------------------------------------------------------------------


                    if (cID == current.NearNodeID)
                    {
                        current = NativeNodes[current.FarNodeID];
                        state   = TraverseState.FromSibling;
                    }
                    else
                    {
                        state = TraverseState.FromChild;
                    }

                    break;

                case TraverseState.FromSibling:

                    // ReSharper disable once NotAccessedVariable
                    float dist;
                    if (!BVHBBox.IntersectRay(Rays[index], current.BMin, current.BMax, out dist))
                    {
                        current = NativeNodes[current.ParentID];
                        state   = TraverseState.FromChild;
                    }
                    else if (current.IsLeaf == 1)
                    {
                        if (NativePrims[current.PrimitivesOffset].IntersectRay(Rays[index], ref TempHi, index))
                        {
                            HitInfos.Add(TempHi[index]);
                            intersect = true;
                        }

                        current = NativeNodes[current.ParentID];
                        state   = TraverseState.FromChild;
                    }
                    else
                    {
                        // ----------------------------------------------------------------------------------------------------
                        sA = rayDirection[current.SplitAxis];
                        current.NearNodeID = math.@select(current.LChildID, current.RChildID, sA < 0f);
                        current.FarNodeID  = math.@select(current.RChildID, current.LChildID, sA < 0f);
                        // ----------------------------------------------------------------------------------------------------

                        current = NativeNodes[current.NearNodeID];
                        state   = TraverseState.FromParent;
                    }

                    break;

                case TraverseState.FromParent:
                    if (!BVHBBox.IntersectRay(Rays[index], current.BMin, current.BMax, out dist))
                    {
                        cID     = current.NodeID;
                        current = NativeNodes[current.ParentID];

                        // ----------------------------------------------------------------------------------------------------
                        sA = rayDirection[current.SplitAxis];
                        current.NearNodeID = math.@select(current.LChildID, current.RChildID, sA < 0f);
                        current.FarNodeID  = math.@select(current.RChildID, current.LChildID, sA < 0f);
                        // ----------------------------------------------------------------------------------------------------

                        if (cID == current.NearNodeID)
                        {
                            current = NativeNodes[current.FarNodeID];
                            state   = TraverseState.FromSibling;
                        }
                        else
                        {
                            current = NativeNodes[current.NearNodeID];
                            state   = TraverseState.FromSibling;
                        }
                    }
                    else if (current.IsLeaf == 1)
                    {
                        // Test triangle for intersection

                        if (NativePrims[current.PrimitivesOffset].IntersectRay(Rays[index], ref TempHi, index))
                        {
                            HitInfos.Add(TempHi[index]);
                            intersect = true;
                        }

                        // ----------------------------------------------------------------------------------------------------

                        int lChild, rChild, splitAxis;
                        NativeNodes[current.ParentID]
                        .GetChildrenIDsAndSplitAxis(out lChild, out rChild, out splitAxis);
                        sA = rayDirection[splitAxis];

                        //int nearNodeID = math.@select(lChild, rChild, sA < 0f);
                        int farNodeID = math.@select(rChild, lChild, sA < 0f);

                        // ----------------------------------------------------------------------------------------------------

                        current = NativeNodes[farNodeID];
                        state   = TraverseState.FromSibling;
                    }
                    else
                    {
                        // ----------------------------------------------------------------------------------------------------
                        sA = rayDirection[current.SplitAxis];
                        current.NearNodeID = math.@select(current.LChildID, current.RChildID, sA < 0f);
                        current.FarNodeID  = math.@select(current.RChildID, current.LChildID, sA < 0f);
                        // ----------------------------------------------------------------------------------------------------

                        current = NativeNodes[current.NearNodeID];
                        state   = TraverseState.FromParent;
                    }

                    break;
                }
            }

            return(intersect);
        }
Esempio n. 3
0
 protected TreeIteratorAbstract(Tensor tensor, TraverseState state)
 {
     Iterator = new TreeTraverseIterator(tensor);
     State    = state;
 }