Files
Fishing2/Assets/Obi/Scripts/Common/Backends/Burst/Rendering/RopeAndRod/DecimateChunksJob.cs
2025-11-10 00:08:26 +08:00

79 lines
2.7 KiB
C#

#if (OBI_BURST && OBI_MATHEMATICS && OBI_COLLECTIONS)
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
namespace Obi
{
[BurstCompile]
struct DecimateChunksJob : IJobParallelFor
{
[ReadOnly] public NativeArray<int> inputFrameOffsets;
[NativeDisableParallelForRestriction] public NativeArray<BurstPathFrame> inputFrames;
[NativeDisableParallelForRestriction] public NativeArray<int> outputFrameCounts;
[ReadOnly] public NativeArray<BurstPathSmootherData> pathData;
public void Execute(int i)
{
int firstInputIndex = i > 0 ? inputFrameOffsets[i - 1] : 0;
int inputFrameCount = inputFrameOffsets[i] - firstInputIndex;
// no decimation, no work to do, just return:
if (pathData[i].decimation < 0.00001f || inputFrameCount < 3)
{
outputFrameCounts[i] = inputFrameCount;
return;
}
float scaledThreshold = pathData[i].decimation * pathData[i].decimation * 0.01f;
int start = 0;
int end = inputFrameCount - 1;
outputFrameCounts[i] = 0;
while (start < end)
{
// add starting point:
inputFrames[firstInputIndex + outputFrameCounts[i]++] = inputFrames[firstInputIndex + start];
var newEnd = end;
while (true)
{
int maxDistanceIndex = 0;
float maxDistance = 0;
// find the point that's furthest away from the current segment:
for (int k = start + 1; k < newEnd; k++)
{
var nearest = BurstMath.NearestPointOnEdge(inputFrames[firstInputIndex + start].position,
inputFrames[firstInputIndex + newEnd].position,
inputFrames[firstInputIndex + k].position, out _);
float d = math.lengthsq(nearest - inputFrames[firstInputIndex + k].position);
if (d > maxDistance)
{
maxDistanceIndex = k;
maxDistance = d;
}
}
if (maxDistance <= scaledThreshold)
break;
newEnd = maxDistanceIndex;
}
start = newEnd;
}
// add the last point:
inputFrames[firstInputIndex + outputFrameCounts[i]++] = inputFrames[firstInputIndex + end];
}
}
}
#endif