79 lines
2.7 KiB
C#
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 |