public void Flip() { if (type == IntersectionType.AInsideB) { type = IntersectionType.BInsideA; } else if (type == IntersectionType.BInsideA) { type = IntersectionType.AInsideB; } { var t = brushIndexOrder0; brushIndexOrder0 = brushIndexOrder1; brushIndexOrder1 = t; } }
public void Execute() { var nodeIDValueMin = int.MaxValue; var nodeIDValueMax = 0; if (brushCount > 0) { Debug.Assert(brushCount == brushes.Length); for (int nodeOrder = 0; nodeOrder < brushCount; nodeOrder++) { var brushCompactNodeID = brushes[nodeOrder]; var brushCompactNodeIDValue = brushCompactNodeID.value; nodeIDValueMin = math.min(nodeIDValueMin, brushCompactNodeIDValue); nodeIDValueMax = math.max(nodeIDValueMax, brushCompactNodeIDValue); } } else { nodeIDValueMin = 0; } var nodeIDValueToNodeOrderOffset = nodeIDValueMin; nodeIDValueToNodeOrderOffsetRef.Value = nodeIDValueToNodeOrderOffset; var desiredLength = (nodeIDValueMax + 1) - nodeIDValueMin; nodeIDValueToNodeOrder.Clear(); nodeIDValueToNodeOrder.Resize(desiredLength, NativeArrayOptions.ClearMemory); for (int nodeOrder = 0; nodeOrder < brushCount; nodeOrder++) { var brushCompactNodeID = brushes[nodeOrder]; var brushCompactNodeIDValue = brushCompactNodeID.value; nodeIDValueToNodeOrder[brushCompactNodeIDValue - nodeIDValueToNodeOrderOffset] = nodeOrder; // We need the index into the tree to ensure deterministic ordering var brushIndexOrder = new IndexOrder { compactNodeID = brushCompactNodeID, nodeOrder = nodeOrder }; allTreeBrushIndexOrders[nodeOrder] = brushIndexOrder; } }
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 }); } }