示例#1
0
        void GenerateLoop(IndexOrder brushIndexOrder0,
                          IndexOrder brushIndexOrder1,
                          bool invertedTransform,
                          [NoAlias] NativeArray <SurfaceInfo> surfaceInfos,
                          [NoAlias] int surfaceInfosLength,
                          [NoAlias] ref BrushTreeSpacePlanes brushTreeSpacePlanes0,
                          [NoAlias] NativeArray <PlaneVertexIndexPair> foundIndices0,
                          [NoAlias] ref int foundIndices0Length,
                          [NoAlias] ref HashedVertices hashedTreeSpaceVertices,
                          [NoAlias] NativeList <BrushIntersectionLoop> .ParallelWriter outputSurfaces)
        {
            // Why is the unity NativeSort slower than bubble sort?
            for (int i = 0; i < foundIndices0Length - 1; i++)
            {
                for (int j = i + 1; j < foundIndices0Length; j++)
                {
                    var x = foundIndices0[i];
                    var y = foundIndices0[j];
                    if (x.planeIndex > y.planeIndex)
                    {
                        continue;
                    }
                    if (x.planeIndex == y.planeIndex)
                    {
                        if (x.vertexIndex <= y.vertexIndex)
                        {
                            continue;
                        }
                    }

                    var t = x;
                    foundIndices0[i] = foundIndices0[j];
                    foundIndices0[j] = t;
                }
            }


            NativeCollectionHelpers.EnsureMinimumSize(ref planeIndexOffsets, foundIndices0Length);
            NativeCollectionHelpers.EnsureMinimumSize(ref uniqueIndices, foundIndices0Length);

            var planeIndexOffsetsLength = 0;
            //var planeIndexOffsets       = stackalloc PlaneIndexOffsetLength[foundIndices0Length];
            var uniqueIndicesLength = 0;
            //var uniqueIndices           = stackalloc ushort[foundIndices0Length];

            // Now that our indices are sorted by planeIndex, we can segment them by start/end offset
            var previousPlaneIndex  = foundIndices0[0].planeIndex;
            var previousVertexIndex = foundIndices0[0].vertexIndex;

            uniqueIndices[uniqueIndicesLength] = previousVertexIndex;
            uniqueIndicesLength++;
            var loopStart = 0;

            for (int i = 1; i < foundIndices0Length; i++)
            {
                var indices = foundIndices0[i];

                var planeIndex  = indices.planeIndex;
                var vertexIndex = indices.vertexIndex;

                // TODO: why do we have soooo many duplicates sometimes?
                if (planeIndex == previousPlaneIndex &&
                    vertexIndex == previousVertexIndex)
                {
                    continue;
                }

                if (planeIndex != previousPlaneIndex)
                {
                    var currLength = (uniqueIndicesLength - loopStart);
                    if (currLength > 2)
                    {
                        planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                        {
                            length     = (ushort)currLength,
                            offset     = (ushort)loopStart,
                            planeIndex = previousPlaneIndex
                        };
                        planeIndexOffsetsLength++;
                    }
                    loopStart = uniqueIndicesLength;
                }

                uniqueIndices[uniqueIndicesLength] = vertexIndex;
                uniqueIndicesLength++;
                previousVertexIndex = vertexIndex;
                previousPlaneIndex  = planeIndex;
            }
            {
                var currLength = (uniqueIndicesLength - loopStart);
                if (currLength > 2)
                {
                    planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                    {
                        length     = (ushort)currLength,
                        offset     = (ushort)loopStart,
                        planeIndex = previousPlaneIndex
                    };
                    planeIndexOffsetsLength++;
                }
            }

            var maxLength = 0;

            for (int i = 0; i < planeIndexOffsetsLength; i++)
            {
                maxLength = math.max(maxLength, planeIndexOffsets[i].length);
            }

            NativeCollectionHelpers.EnsureMinimumSize(ref sortedStack, maxLength * 2);

            // For each segment, we now sort our vertices within each segment,
            // making the assumption that they are convex
            //var sortedStack = stackalloc int2[maxLength * 2];
            var vertices = hashedTreeSpaceVertices;//.GetUnsafeReadOnlyPtr();

            for (int n = planeIndexOffsetsLength - 1; n >= 0; n--)
            {
                var planeIndexOffset = planeIndexOffsets[n];
                var length           = planeIndexOffset.length;
                var offset           = planeIndexOffset.offset;
                var planeIndex       = planeIndexOffset.planeIndex;

                float3 normal = brushTreeSpacePlanes0.treeSpacePlanes[planeIndex].xyz * (invertedTransform ? 1 : -1);

                // TODO: use plane information instead
                SortIndices(vertices, sortedStack, uniqueIndices, offset, length, normal);
            }


            var totalLoopsSize = 16 + (planeIndexOffsetsLength * UnsafeUtility.SizeOf <BrushIntersectionLoop>());
            var totalSize      = totalLoopsSize;

            for (int j = 0; j < planeIndexOffsetsLength; j++)
            {
                var planeIndexLength = planeIndexOffsets[j];
                var loopLength       = planeIndexLength.length;
                totalSize += (loopLength * UnsafeUtility.SizeOf <float3>());
            }

            var srcVertices = hashedTreeSpaceVertices;

            for (int j = 0; j < planeIndexOffsetsLength; j++)
            {
                var planeIndexLength = planeIndexOffsets[j];
                var offset           = planeIndexLength.offset;
                var loopLength       = planeIndexLength.length;
                var basePlaneIndex   = planeIndexLength.planeIndex;
                var surfaceInfo      = surfaceInfos[basePlaneIndex];

                NativeCollectionHelpers.EnsureMinimumSize(ref temporaryVertices, loopLength);
                for (int d = 0; d < loopLength; d++)
                {
                    temporaryVertices[d] = srcVertices[uniqueIndices[offset + d]];
                }

                outputSurfaces.AddNoResize(new BrushIntersectionLoop
                {
                    indexOrder0     = brushIndexOrder0,
                    indexOrder1     = brushIndexOrder1,
                    surfaceInfo     = surfaceInfo,
                    loopVertexIndex = outputSurfaceVertices.AddRangeNoResize(temporaryVertices.GetUnsafePtr(), loopLength),
                    loopVertexCount = loopLength
                });
            }
        }
        void GenerateLoop(IndexOrder brushIndexOrder0,
                          IndexOrder brushIndexOrder1,
                          bool invertedTransform,
                          [NoAlias] NativeArray <SurfaceInfo> surfaceInfos,
                          [NoAlias] int surfaceInfosLength,
                          [NoAlias] ref BrushTreeSpacePlanes brushTreeSpacePlanes0,
                          [NoAlias] NativeArray <PlaneVertexIndexPair> foundIndices0,
                          [NoAlias] ref int foundIndices0Length,
                          [NoAlias] ref HashedVertices hashedTreeSpaceVertices,
                          [NoAlias] NativeList <BrushIntersectionLoop> .ParallelWriter outputSurfaces)
        {
            // Why is the unity NativeSort slower than bubble sort?
            // TODO: revisit this assumption
            //*
            for (int i = 0; i < foundIndices0Length - 1; i++)
            {
                for (int j = i + 1; j < foundIndices0Length; j++)
                {
                    var x = foundIndices0[i];
                    var y = foundIndices0[j];
                    if (x.planeIndex > y.planeIndex)
                    {
                        continue;
                    }
                    if (x.planeIndex == y.planeIndex)
                    {
                        if (x.vertexIndex <= y.vertexIndex)
                        {
                            continue;
                        }
                    }

                    var t = x;
                    foundIndices0[i] = foundIndices0[j];
                    foundIndices0[j] = t;
                }
            }

            /*/
             * foundIndices0.Sort(comparer);
             * //*/

            NativeCollectionHelpers.EnsureMinimumSize(ref planeIndexOffsets, foundIndices0Length);
            NativeCollectionHelpers.EnsureCapacityAndClear(ref uniqueIndices, foundIndices0Length);

            var planeIndexOffsetsLength = 0;
            //var planeIndexOffsets       = stackalloc PlaneIndexOffsetLength[foundIndices0Length];
            //var uniqueIndices           = stackalloc ushort[foundIndices0Length];

            // Now that our indices are sorted by planeIndex, we can segment them by start/end offset
            var previousPlaneIndex  = foundIndices0[0].planeIndex;
            var previousVertexIndex = foundIndices0[0].vertexIndex;

            uniqueIndices.Add(previousVertexIndex);
            var loopStart = 0;

            for (int i = 1; i < foundIndices0Length; i++)
            {
                var indices = foundIndices0[i];

                var planeIndex  = indices.planeIndex;
                var vertexIndex = indices.vertexIndex;

                // TODO: why do we have soooo many duplicates sometimes?
                if (planeIndex == previousPlaneIndex &&
                    vertexIndex == previousVertexIndex)
                {
                    continue;
                }

                if (planeIndex != previousPlaneIndex)
                {
                    var currLength = RemoveDuplicateEdges(ref uniqueIndices, loopStart, uniqueIndices.Length);
                    //var currLength = (uniqueIndices.Length - loopStart);
                    if (currLength > 2)
                    {
                        planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                        {
                            length     = (ushort)currLength,
                            offset     = (ushort)loopStart,
                            planeIndex = previousPlaneIndex
                        };
                        planeIndexOffsetsLength++;
                    }
                    loopStart = uniqueIndices.Length;
                }

                uniqueIndices.Add(vertexIndex);
                previousVertexIndex = vertexIndex;
                previousPlaneIndex  = planeIndex;
            }
            {
                var currLength = RemoveDuplicateEdges(ref uniqueIndices, loopStart, uniqueIndices.Length);
                //var currLength = (uniqueIndices.Length - loopStart);
                if (currLength > 2)
                {
                    planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                    {
                        length     = (ushort)currLength,
                        offset     = (ushort)loopStart,
                        planeIndex = previousPlaneIndex
                    };
                    planeIndexOffsetsLength++;
                }
            }

            var maxLength = 0;

            for (int i = 0; i < planeIndexOffsetsLength; i++)
            {
                maxLength = math.max(maxLength, planeIndexOffsets[i].length);
            }

            NativeCollectionHelpers.EnsureMinimumSize(ref sortedStack, maxLength * 2);


            var uniqueIndicesArray = uniqueIndices.AsArray();

            // For each segment, we now sort our vertices within each segment,
            // making the assumption that they are convex
            //var sortedStack = stackalloc int2[maxLength * 2];
            ref var vertices = ref hashedTreeSpaceVertices;//.GetUnsafeReadOnlyPtr();
        //[MethodImpl(MethodImplOptions.NoInlining)]
        void GenerateLoop(int brushNodeIndex0,
                          int brushNodeIndex1,
                          ref BlobArray <SurfaceInfo> surfaceInfos,
                          ref BrushTreeSpacePlanes brushTreeSpacePlanes,
                          NativeArray <PlaneVertexIndexPair> foundIndices0,
                          ref int foundIndices0Length,
                          //ref HashedVertices              hashedVertices,
                          NativeList <BlobAssetReference <BrushIntersectionLoops> > .ParallelWriter outputSurfaces)
        {
            // Why is the unity NativeSort slower than bubble sort?
            for (int i = 0; i < foundIndices0Length - 1; i++)
            {
                for (int j = i + 1; j < foundIndices0Length; j++)
                {
                    var x = foundIndices0[i];
                    var y = foundIndices0[j];
                    if (x.planeIndex > y.planeIndex)
                    {
                        continue;
                    }
                    if (x.planeIndex == y.planeIndex)
                    {
                        if (x.vertexIndex <= y.vertexIndex)
                        {
                            continue;
                        }
                    }

                    var t = x;
                    foundIndices0[i] = foundIndices0[j];
                    foundIndices0[j] = t;
                }
            }


            var planeIndexOffsetsLength = 0;
            var planeIndexOffsets       = stackalloc PlaneIndexOffsetLength[foundIndices0Length];
            var uniqueIndicesLength     = 0;
            var uniqueIndices           = stackalloc ushort[foundIndices0Length];

            // Now that our indices are sorted by planeIndex, we can segment them by start/end offset
            var previousPlaneIndex  = foundIndices0[0].planeIndex;
            var previousVertexIndex = foundIndices0[0].vertexIndex;

            uniqueIndices[uniqueIndicesLength] = previousVertexIndex;
            uniqueIndicesLength++;
            var loopStart = 0;

            for (int i = 1; i < foundIndices0Length; i++)
            {
                var indices = foundIndices0[i];

                var planeIndex  = indices.planeIndex;
                var vertexIndex = indices.vertexIndex;

                // TODO: why do we have soooo many duplicates sometimes?
                if (planeIndex == previousPlaneIndex &&
                    vertexIndex == previousVertexIndex)
                {
                    continue;
                }

                if (planeIndex != previousPlaneIndex)
                {
                    var currLength = (uniqueIndicesLength - loopStart);
                    if (currLength > 2)
                    {
                        planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                        {
                            length     = (ushort)currLength,
                            offset     = (ushort)loopStart,
                            planeIndex = previousPlaneIndex
                        };
                        planeIndexOffsetsLength++;
                    }
                    loopStart = uniqueIndicesLength;
                }

                uniqueIndices[uniqueIndicesLength] = vertexIndex;
                uniqueIndicesLength++;
                previousVertexIndex = vertexIndex;
                previousPlaneIndex  = planeIndex;
            }
            {
                var currLength = (uniqueIndicesLength - loopStart);
                if (currLength > 2)
                {
                    planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength
                    {
                        length     = (ushort)currLength,
                        offset     = (ushort)loopStart,
                        planeIndex = previousPlaneIndex
                    };
                    planeIndexOffsetsLength++;
                }
            }

            var maxLength = 0;

            for (int i = 0; i < planeIndexOffsetsLength; i++)
            {
                maxLength = math.max(maxLength, planeIndexOffsets[i].length);
            }

            // For each segment, we now sort our vertices within each segment,
            // making the assumption that they are convex
            var sortedStack = stackalloc int2[maxLength * 2];
            var vertices    = hashedVertices.GetUnsafeReadOnlyPtr();

            for (int n = planeIndexOffsetsLength - 1; n >= 0; n--)
            {
                var planeIndexOffset = planeIndexOffsets[n];
                var length           = planeIndexOffset.length;
                var offset           = planeIndexOffset.offset;
                var planeIndex       = planeIndexOffset.planeIndex;

                // TODO: use plane information instead
                SortIndices(vertices, sortedStack, uniqueIndices, offset, length, brushTreeSpacePlanes.treeSpacePlanes[planeIndex].xyz);
            }


            var totalLoopsSize = 16 + (planeIndexOffsetsLength * UnsafeUtility.SizeOf <BrushIntersectionLoop>());
            var totalSize      = totalLoopsSize;

            for (int j = 0; j < planeIndexOffsetsLength; j++)
            {
                var planeIndexLength = planeIndexOffsets[j];
                var loopLength       = planeIndexLength.length;
                totalSize += (loopLength * UnsafeUtility.SizeOf <float3>());
            }

            var     builder     = new BlobBuilder(Allocator.Temp, totalSize);
            ref var root        = ref builder.ConstructRoot <BrushIntersectionLoops>();