/// <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); }
protected TreeIteratorAbstract(Tensor tensor, TraverseState state) { Iterator = new TreeTraverseIterator(tensor); State = state; }