//[MethodImpl(MethodImplOptions.NoInlining)] void FindInsideVertices(ref BlobArray <float3> usedVertices0, ref BlobArray <ushort> vertexIntersectionPlanes, ref BlobArray <int2> vertexIntersectionSegments, ref BlobArray <float4> intersectingPlanes1, float4x4 nodeToTreeSpaceMatrix1, float4x4 vertexToLocal0, //ref HashedVertices hashedVertices, NativeArray <PlaneVertexIndexPair> foundIndices0, ref int foundIndices0Length) { var localVertices = stackalloc float4[usedVertices0.Length]; var usedVertexIndices = stackalloc ushort[usedVertices0.Length]; var foundVertexCount = 0; for (int j = 0; j < usedVertices0.Length; j++) { var brushVertex1 = new float4(usedVertices0[j], 1); localVertices[j] = math.mul(vertexToLocal0, brushVertex1); usedVertexIndices[j] = (ushort)j; } foundVertexCount = usedVertices0.Length; for (int j = foundVertexCount - 1; j >= 0; j--) { if (IsOutsidePlanes(ref intersectingPlanes1, localVertices[j])) { if (j < foundVertexCount - 1) { localVertices[j] = localVertices[foundVertexCount - 1]; usedVertexIndices[j] = usedVertexIndices[foundVertexCount - 1]; } foundVertexCount--; } } for (int j = 0; j < foundVertexCount; j++) { var usedVertexIndex = usedVertexIndices[j]; var segment = vertexIntersectionSegments[usedVertexIndex]; if (segment.y == 0) { continue; } var treeSpaceVertex = math.mul(nodeToTreeSpaceMatrix1, localVertices[j]).xyz; var treeSpaceVertexIndex = hashedVertices.AddNoResize(treeSpaceVertex); for (int i = segment.x; i < segment.x + segment.y; i++) { var planeIndex = vertexIntersectionPlanes[i]; foundIndices0[foundIndices0Length] = new PlaneVertexIndexPair { planeIndex = (ushort)planeIndex, vertexIndex = (ushort)treeSpaceVertexIndex }; foundIndices0Length++; } } }
void FindIntersectionVertices(ref NativeArray <float4> intersectingPlanes0, int intersectingPlanes0Length, int intersectingPlanesAndEdges0Length, ref NativeArray <float4> intersectingPlanes1, int intersectingPlanes1Length, int intersectingPlanesAndEdges1Length, ref NativeArray <PlanePair> usedPlanePairs1, int usedPlanePairs1Length, ref NativeArray <int> intersectingPlaneIndices0, int intersectingPlaneIndices0Length, float4x4 nodeToTreeSpaceMatrix0, ref HashedVertices hashedTreeSpaceVertices, ref HashedVertices snapHashedVertices, NativeArray <PlaneVertexIndexPair> foundIndices0, ref int foundIndices0Length, NativeArray <PlaneVertexIndexPair> foundIndices1, ref int foundIndices1Length) { int foundVerticesCount = usedPlanePairs1Length * intersectingPlanes0Length; NativeCollectionHelpers.EnsureMinimumSize(ref foundVertices, foundVerticesCount); NativeCollectionHelpers.EnsureMinimumSize(ref foundEdges, foundVerticesCount); NativeCollectionHelpers.EnsureMinimumSize(ref foundIntersections, foundVerticesCount); var n = 0; for (int i = 0; i < usedPlanePairs1Length; i++) { for (int j = 0; j < intersectingPlanes0Length; j++) { var plane0 = usedPlanePairs1[i].plane0; var plane1 = usedPlanePairs1[i].plane1; var plane2 = intersectingPlanes0[j]; foundIntersections[n] = new IntersectionPlanes { //plane0 = plane0, //plane1 = plane1, plane2 = plane2, planeIndex0 = usedPlanePairs1[i].planeIndex0, planeIndex1 = usedPlanePairs1[i].planeIndex1, planeIndex2 = intersectingPlaneIndices0[j] }; foundEdges[n] = new IntersectionEdge { edgeVertex0 = usedPlanePairs1[i].edgeVertex0, edgeVertex1 = usedPlanePairs1[i].edgeVertex1 }; if (math.abs(math.dot(plane2.xyz, plane0.xyz)) >= CSGConstants.kNormalDotAlignEpsilon || math.abs(math.dot(plane2.xyz, plane1.xyz)) >= CSGConstants.kNormalDotAlignEpsilon || math.abs(math.dot(plane0.xyz, plane1.xyz)) >= CSGConstants.kNormalDotAlignEpsilon) { continue; } var localVertex = PlaneExtensions.Intersection(plane2, plane0, plane1); if (double.IsNaN(localVertex.x)) { continue; } foundVertices[n] = new float4((float3)localVertex, 1); n++; } } for (int k = n - 1; k >= 0; k--) { var edgeVertex0 = foundEdges[k].edgeVertex0; var edgeVertex1 = foundEdges[k].edgeVertex1; var plane2 = foundIntersections[k].plane2; if (math.abs(math.dot(plane2, edgeVertex0)) <= kFatPlaneWidthEpsilon && math.abs(math.dot(plane2, edgeVertex1)) <= kFatPlaneWidthEpsilon) { if (k < n - 1) { foundIntersections[k] = foundIntersections[n - 1]; foundVertices[k] = foundVertices[n - 1]; } n--; } } // TODO: since we're using a pair in the outer loop, we could also determine which // 2 planes it intersects at both ends and just check those two planes .. // NOTE: for brush2, the intersection will always be only on two planes // UNLESS it's a corner vertex along that edge (we can compare to the two vertices) // in which case we could use a pre-calculated list of planes .. // OR when the intersection is outside of the edge .. for (int k = n - 1; k >= 0; k--) { if (IsOutsidePlanes(intersectingPlanes0, intersectingPlanesAndEdges0Length, foundVertices[k]) || IsOutsidePlanes(intersectingPlanes1, intersectingPlanesAndEdges1Length, foundVertices[k])) { if (k < n - 1) { foundIntersections[k] = foundIntersections[n - 1]; foundVertices[k] = foundVertices[n - 1]; } n--; } } for (int k = 0; k < n; k++) { var planeIndex0 = (ushort)foundIntersections[k].planeIndex0; var planeIndex1 = (ushort)foundIntersections[k].planeIndex1; var planeIndex2 = (ushort)foundIntersections[k].planeIndex2; var localVertex = foundVertices[k]; // TODO: should be having a Loop for each plane that intersects this vertex, and add that vertex // to ensure they are identical var treeSpaceVertex = math.mul(nodeToTreeSpaceMatrix0, localVertex).xyz; treeSpaceVertex = snapHashedVertices[snapHashedVertices.AddNoResize(treeSpaceVertex)]; var treeSpaceVertexIndex = hashedTreeSpaceVertices.AddNoResize(treeSpaceVertex); { // TODO: optimize for (int f = 0; f < foundIndices0Length; f++) { if (foundIndices0[f].vertexIndex == treeSpaceVertexIndex && foundIndices0[f].planeIndex == planeIndex2) { goto skip0; } } foundIndices0[foundIndices0Length] = new PlaneVertexIndexPair { planeIndex = planeIndex2, vertexIndex = treeSpaceVertexIndex }; foundIndices0Length++; skip0 :; } { // TODO: optimize for (int f = 0; f < foundIndices1Length; f++) { if (foundIndices1[f].vertexIndex == treeSpaceVertexIndex && foundIndices1[f].planeIndex == planeIndex0) { goto skip1; } } foundIndices1[foundIndices1Length] = new PlaneVertexIndexPair { planeIndex = planeIndex0, vertexIndex = treeSpaceVertexIndex }; foundIndices1Length++; skip1 :; } { // TODO: optimize for (int f = 0; f < foundIndices1Length; f++) { if (foundIndices1[f].vertexIndex == treeSpaceVertexIndex && foundIndices1[f].planeIndex == planeIndex1) { goto skip2; } } foundIndices1[foundIndices1Length] = new PlaneVertexIndexPair { planeIndex = planeIndex1, vertexIndex = treeSpaceVertexIndex }; foundIndices1Length++; skip2 :; } } }
//[MethodImpl(MethodImplOptions.NoInlining)] void FindInsideVertices([NoAlias] NativeArray <float3> usedVertices0, int usedVertices0Length, [NoAlias] NativeArray <ushort> vertexIntersectionPlanes, int vertexIntersectionPlanesLength, [NoAlias] NativeArray <int2> vertexIntersectionSegments, int vertexIntersectionSegmentsLength, [NoAlias] NativeArray <float4> intersectingPlanes1, int intersectingPlanes1Length, int intersectingPlanesAndEdges1Length, float4x4 nodeToTreeSpaceMatrix1, float4x4 vertexToLocal0, [NoAlias] ref HashedVertices hashedTreeSpaceVertices, [NoAlias] ref HashedVertices snapHashedVertices, [NoAlias] NativeArray <PlaneVertexIndexPair> foundIndices0, ref int foundIndices0Length) { NativeCollectionHelpers.EnsureMinimumSize(ref localVertices, usedVertices0Length); NativeCollectionHelpers.EnsureMinimumSize(ref usedVertexIndices, usedVertices0Length); for (int j = 0; j < usedVertices0Length; j++) { var brushVertex1 = new float4(usedVertices0[j], 1); localVertices[j] = math.mul(vertexToLocal0, brushVertex1); usedVertexIndices[j] = (ushort)j; } var foundVertexCount = usedVertices0Length; for (int j = foundVertexCount - 1; j >= 0; j--) { if (IsOutsidePlanes(intersectingPlanes1, intersectingPlanesAndEdges1Length, localVertices[j])) { if (j < foundVertexCount - 1) { localVertices[j] = localVertices[foundVertexCount - 1]; usedVertexIndices[j] = usedVertexIndices[foundVertexCount - 1]; } foundVertexCount--; } } for (int j = 0; j < foundVertexCount; j++) { var usedVertexIndex = usedVertexIndices[j]; var segment = vertexIntersectionSegments[usedVertexIndex]; if (segment.y == 0) { continue; } var treeSpaceVertex = math.mul(nodeToTreeSpaceMatrix1, localVertices[j]).xyz; treeSpaceVertex = snapHashedVertices[snapHashedVertices.AddNoResize(treeSpaceVertex)]; var treeSpaceVertexIndex = hashedTreeSpaceVertices.AddNoResize(treeSpaceVertex); for (int i = segment.x; i < segment.x + segment.y; i++) { var planeIndex = vertexIntersectionPlanes[i]; // TODO: optimize for (int k = 0; k < foundIndices0Length; k++) { if (foundIndices0[k].planeIndex == planeIndex && foundIndices0[k].vertexIndex == treeSpaceVertexIndex) { goto skipMe; } } foundIndices0[foundIndices0Length] = new PlaneVertexIndexPair { planeIndex = (ushort)planeIndex, vertexIndex = (ushort)treeSpaceVertexIndex }; foundIndices0Length++; skipMe: ; } } }
//[MethodImpl(MethodImplOptions.NoInlining)] void FindIntersectionVertices(ref BlobArray <float4> intersectingPlanes0, ref BlobArray <float4> intersectingPlanes1, ref BlobArray <PlanePair> usedPlanePairs1, ref BlobArray <int> intersectingPlaneIndices0, float4x4 nodeToTreeSpaceMatrix0, //ref HashedVertices hashedVertices, NativeArray <PlaneVertexIndexPair> foundIndices0, ref int foundIndices0Length, NativeArray <PlaneVertexIndexPair> foundIndices1, ref int foundIndices1Length) { var foundVertices = new NativeArray <float4>(usedPlanePairs1.Length * intersectingPlanes0.Length, Allocator.Temp); var foundEdges = new NativeArray <IntersectionEdge>(usedPlanePairs1.Length * intersectingPlanes0.Length, Allocator.Temp); var foundIntersections = new NativeArray <IntersectionPlanes>(usedPlanePairs1.Length * intersectingPlanes0.Length, Allocator.Temp); var n = 0; for (int i = 0; i < usedPlanePairs1.Length; i++) { for (int j = 0; j < intersectingPlanes0.Length; j++) { foundIntersections[n] = new IntersectionPlanes { plane0 = usedPlanePairs1[i].plane0, plane1 = usedPlanePairs1[i].plane1, plane2 = intersectingPlanes0[j], planeIndex0 = usedPlanePairs1[i].planeIndex0, planeIndex1 = usedPlanePairs1[i].planeIndex1, planeIndex2 = intersectingPlaneIndices0[j] }; foundEdges[n] = new IntersectionEdge { edgeVertex0 = usedPlanePairs1[i].edgeVertex0, edgeVertex1 = usedPlanePairs1[i].edgeVertex1 }; var plane0 = usedPlanePairs1[i].plane0; var plane1 = usedPlanePairs1[i].plane1; var plane2 = intersectingPlanes0[j]; foundVertices[n] = new float4(PlaneExtensions.Intersection(plane2, plane0, plane1), 1); n++; } } for (int k = n - 1; k >= 0; k--) { var edgeVertex0 = foundEdges[k].edgeVertex0; var edgeVertex1 = foundEdges[k].edgeVertex1; var plane2 = foundIntersections[k].plane2; if (math.abs(math.dot(plane2, edgeVertex0)) <= kDistanceEpsilon && math.abs(math.dot(plane2, edgeVertex1)) <= kDistanceEpsilon) { if (k < n - 1) { foundIntersections[k] = foundIntersections[n - 1]; foundVertices[k] = foundVertices[n - 1]; } n--; } } // TODO: since we're using a pair in the outer loop, we could also determine which // 2 planes it intersects at both ends and just check those two planes .. // NOTE: for brush2, the intersection will always be only on two planes // UNLESS it's a corner vertex along that edge (we can compare to the two vertices) // in which case we could use a pre-calculated list of planes .. // OR when the intersection is outside of the edge .. for (int k = n - 1; k >= 0; k--) { if (IsOutsidePlanes(ref intersectingPlanes0, foundVertices[k]) || IsOutsidePlanes(ref intersectingPlanes1, foundVertices[k])) { if (k < n - 1) { foundIntersections[k] = foundIntersections[n - 1]; foundVertices[k] = foundVertices[n - 1]; } n--; } } for (int k = 0; k < n; k++) { var planeIndex0 = (ushort)foundIntersections[k].planeIndex0; var planeIndex1 = (ushort)foundIntersections[k].planeIndex1; var planeIndex2 = (ushort)foundIntersections[k].planeIndex2; var localVertex = foundVertices[k]; // TODO: should be having a Loop for each plane that intersects this vertex, and add that vertex // to ensure they are identical var treeSpaceVertex = math.mul(nodeToTreeSpaceMatrix0, localVertex).xyz; var vertexIndex = hashedVertices.AddNoResize(treeSpaceVertex); foundIndices0[foundIndices0Length] = new PlaneVertexIndexPair { planeIndex = planeIndex2, vertexIndex = vertexIndex }; foundIndices0Length++; foundIndices1[foundIndices1Length] = new PlaneVertexIndexPair { planeIndex = planeIndex0, vertexIndex = vertexIndex }; foundIndices1Length++; foundIndices1[foundIndices1Length] = new PlaneVertexIndexPair { planeIndex = planeIndex1, vertexIndex = vertexIndex }; foundIndices1Length++; } }