コード例 #1
0
            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;
                    }
                }
            }
コード例 #2
0
            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;
            }
コード例 #3
0
 public static Aabb Union(Aabb a, Aabb b)
 {
     a.Include(b);
     return(a);
 }