/** * Bisect a given volume once, return true if the volume was actually intersected **/ public bool BisectOnce() { Plane bisectPlane = CreateRandomBisectPlane(); //DrawDebugPlane(bisectPlane); List <IntersectionPair> intersectionPairs = new List <IntersectionPair>(); for (int i = 0; i != m_pendingTriangles.Length; i++) { Triangle triangle = m_pendingTriangles[i]; if (triangle == null || !triangle.m_valid) { continue; } Triangle.IntersectionPoint[] intersections; if (triangle.IntersectsPlane(bisectPlane, out intersections)) { intersectionPairs.Add(new IntersectionPair(intersections[0], intersections[1])); Triangle[] splitTriangles; triangle.Split(intersections, out splitTriangles); triangle.m_valid = false; for (int m = 0; m != splitTriangles.Length; m++) { //remove split triangles that are on the wrong side of the plane if (bisectPlane.GetSide(splitTriangles[m].m_center)) { splitTriangles[m].m_valid = false; continue; } splitTriangles[m].m_color = Color.red; } InsertTriangles(splitTriangles); } else { if (bisectPlane.GetSide(triangle.m_center)) { triangle.m_valid = false; } } } if (intersectionPairs.Count > 2) { //strip pairs that have an almost zero length int validPairsCount = intersectionPairs.Count; float sqrZeroLength = 1E-10F; for (int p = 0; p != intersectionPairs.Count; p++) { if (intersectionPairs[p].GetSquareDistance() < sqrZeroLength) { intersectionPairs[p].m_valid = false; validPairsCount--; } } if (validPairsCount > 2) { //build the new plane face of the stone Triangle.IntersectionPoint[] planeFaceVertices = new Triangle.IntersectionPoint[validPairsCount]; planeFaceVertices[0] = intersectionPairs[0].m_pointA; planeFaceVertices[1] = intersectionPairs[0].m_pointB; intersectionPairs[0].m_valid = false; Triangle.IntersectionPoint lastVertex = planeFaceVertices[1]; int vertexIndex = 2; while (vertexIndex < planeFaceVertices.Length) { bool bBreakLoop = true; for (int p = 0; p != intersectionPairs.Count; p++) { if (intersectionPairs[p].m_valid) { bool bShareSamePositionAsPointA = intersectionPairs[p].m_pointA.ShareSamePosition(lastVertex, sqrZeroLength); bool bShareSamePositionAsPointB = false; if (!bShareSamePositionAsPointA) { bShareSamePositionAsPointB = intersectionPairs[p].m_pointB.ShareSamePosition(lastVertex, sqrZeroLength); } if (bShareSamePositionAsPointA || bShareSamePositionAsPointB) { lastVertex = bShareSamePositionAsPointA ? intersectionPairs[p].m_pointB : intersectionPairs[p].m_pointA; planeFaceVertices[vertexIndex] = lastVertex; vertexIndex++; intersectionPairs[p].m_valid = false; bBreakLoop = false; break; } } } if (bBreakLoop) { break; } } //DEBUG Check if planeFaceVertices has the same number of elements than intersectionPairs //int missingVerticesCount = 0; //for (int m = 0; m != planeFaceVertices.Length; m++) //{ // if (planeFaceVertices[m].m_point == Vector3.zero) // missingVerticesCount++; //} //Debug.Log("missingVerticesCount:" + missingVerticesCount); Triangle[] triangles = ProcessShapeContour(planeFaceVertices, bisectPlane); for (int p = 0; p != triangles.Length; p++) { triangles[p].m_color = Color.yellow; } InsertTriangles(triangles); InvalidateMesh(); return(true); } } return(false); }
public IntersectionPair(Triangle.IntersectionPoint pointA, Triangle.IntersectionPoint pointB) { m_pointA = pointA; m_pointB = pointB; m_valid = true; }