public void Execute(int index) { var brushNodeIndex = treeBrushIndices[index]; var worldPlanes = BrushTreeSpacePlanes.Build(brushMeshLookup[brushNodeIndex], transformations[brushNodeIndex].Value.nodeToTree); brushTreeSpacePlanes.TryAdd(brushNodeIndex, worldPlanes); }
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();
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 }); } }
//[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>();