// Copyright Epic Games, Inc. All Rights Reserved. [numthreads(64, 1, 1)] void PCGCullPointsOutsideActorBoundsCS(uint3 GroupId : SV_GroupID, uint GroupIndex : SV_GroupIndex) { // Mark the kernel as having executed. Must run before we early out via thread index, because the kernel is still 'executed' even if the number of // threads to iterate on is zero. Even if GetNumThreads() returns 0, the kernel will still have been dispatched on a single thread to set this flag. if (all(GroupId == 0) && GroupIndex == 0) { Out_SetAsExecutedInternal(); } const uint ThreadIndex = GetUnWrappedDispatchThreadId(GroupId, GroupIndex, 64); if (ThreadIndex >= GetNumThreads().x) return; uint InDataIndex, InElemIndex; if (!In_GetThreadData(ThreadIndex, InDataIndex, InElemIndex)) { return; } uint OutDataIndex, OutElemIndex; if (!Out_GetThreadData(ThreadIndex, OutDataIndex, OutElemIndex)) { return; } // Propagate the 'Removed' status to the output point. Otherwise, this point will not be culled. if (In_IsPointRemoved(InDataIndex, InElemIndex)) { Out_RemovePoint(OutDataIndex, OutElemIndex); return; } const float BoundsExpansion = CullPointsOutsideActorBounds_GetBoundsExpansion(); const float3 InPosition = In_GetPosition(InDataIndex, InElemIndex); const float3 ComponentBoundsMin = GetComponentBoundsMin() - BoundsExpansion; const float3 ComponentBoundsMax = GetComponentBoundsMax() + BoundsExpansion; const bool bInsideBounds = all(InPosition >= ComponentBoundsMin) && all(InPosition < ComponentBoundsMax); if (!bInsideBounds) { Out_RemovePoint(OutDataIndex, OutElemIndex); return; } PCG_COPY_ATTRIBUTES_TO_OUTPUT(Out, In, OutDataIndex, OutElemIndex, InDataIndex, InElemIndex, /*bMetadataOnly=*/false, /*bInitNonCopiedAttributes=*/true); }