#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 inputFrameOffsets; [NativeDisableParallelForRestriction] public NativeArray inputFrames; [NativeDisableParallelForRestriction] public NativeArray outputFrameCounts; [ReadOnly] public NativeArray 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