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); }
public bool RayCast(int index, int nodeID) { if (NativeNodes[nodeID].IsLeaf == 1) { float bestDist = float.MaxValue; HitInfo hitInfo = new HitInfo(); for (int i = 0; i < NativeNodes[nodeID].PrimitivesCount; i++) { hitInfo.Clear(); if (NativePrims[NativeNodes[nodeID].PrimitivesOffset + i].IntersectRay(Rays[index], out hitInfo)) { if (hitInfo.HitDistance < bestDist) { bestDist = hitInfo.HitDistance; HitInfos.Add(new HitInfo(hitInfo)); } } } } else { // ReSharper disable once NotAccessedVariable float hitDist; if (BVHBBox.IntersectRay(Rays[index], NativeNodes[nodeID].BMin, NativeNodes[nodeID].BMax, out hitDist)) { float d1; float d2; int lNodeID = NativeNodes[nodeID].LChildID; int rNodeID = NativeNodes[nodeID].RChildID; bool bHitL = BVHBBox.IntersectRay(Rays[index], NativeNodes[lNodeID].BMin, NativeNodes[lNodeID].BMax, out d1); bool bHitR = BVHBBox.IntersectRay(Rays[index], NativeNodes[rNodeID].BMin, NativeNodes[rNodeID].BMax, out d2); if (bHitL && bHitR) { if (d1 > d2) { RayCast(index, lNodeID); RayCast(index, rNodeID); } else { RayCast(index, rNodeID); RayCast(index, lNodeID); } } else if (bHitL) { RayCast(index, lNodeID); } else if (bHitR) { RayCast(index, rNodeID); } } } return(false); }