void ProcessAxis(int rangeLength, int axis, NativeArray <sfloat> scores, NativeArray <float4> points, ref int bestAxis, ref int pivot, ref sfloat minScore) { CompareVertices comparator; comparator.SortAxis = axis; NativeSortExtension.Sort((float4 *)points.GetUnsafePtr(), rangeLength, comparator); PointAndIndex *p = (PointAndIndex *)points.GetUnsafePtr(); Aabb runningAabb = Aabb.Empty; for (int i = 0; i < rangeLength; i++) { runningAabb.Include(Aabbs[p[i].Index]); scores[i] = (sfloat)(i + 1) * runningAabb.SurfaceArea; } runningAabb = Aabb.Empty; for (int i = rangeLength - 1, j = 1; i > 0; --i, ++j) { runningAabb.Include(Aabbs[p[i].Index]); sfloat sum = scores[i - 1] + (sfloat)j * runningAabb.SurfaceArea; if (sum < minScore) { pivot = i; bestAxis = axis; minScore = sum; } } }
void Segregate(int axis, sfloat pivot, Range range, int minItems, ref Range lRange, ref Range rRange) { Assert.IsTrue(range.Length > 1 /*, "Range length must be greater than 1."*/); Aabb lDomain = Aabb.Empty; Aabb rDomain = Aabb.Empty; float4 *p = PointsAsFloat4; float4 *start = p + range.Start; float4 *end = start + range.Length - 1; do { // Consume left. while (start <= end && (*start)[axis] < pivot) { lDomain.Include((*(start++)).xyz); } // Consume right. while (end > start && (*end)[axis] >= pivot) { rDomain.Include((*(end--)).xyz); } if (start >= end) { goto FINISHED; } lDomain.Include((*end).xyz); rDomain.Include((*start).xyz); Swap(ref *(start++), ref *(end--)); } while (true); FINISHED: // Build sub-ranges. int lSize = (int)(start - p); int rSize = range.Length - lSize; if (lSize < minItems || rSize < minItems) { // Make sure sub-ranges contains at least minItems nodes, in these rare cases (i.e. all points at the same position), we just split the set in half regardless of positions. SplitRange(ref range, range.Length / 2, ref lRange, ref rRange); SetAabbFromPoints(ref lDomain, PointsAsFloat4 + lRange.Start, lRange.Length); SetAabbFromPoints(ref rDomain, PointsAsFloat4 + rRange.Start, rRange.Length); } else { SplitRange(ref range, lSize, ref lRange, ref rRange); } lRange.Domain = lDomain; rRange.Domain = rDomain; }
public static Aabb Union(Aabb a, Aabb b) { a.Include(b); return(a); }