public Vertex FindVertexUnder(Vector3 vPosition) { for (int v = mlVertices.Count - 1; v >= 0; v--) { Vertex vertex = mlVertices[v]; if (vertex.IsUnder(vPosition)) { return(vertex); } } return(null); }
private IEnumerator PunchOutStep2(XZPolygon polygon) { Profiler.BeginSample("PunchOutStep2"); float fTimeWhenStartedChunk = Time.realtimeSinceStartup; // (2) Create additional mesh lines corresponding to the polygon lines int iSegmentIndex = 0; Vertex currentVertex = FindVertexUnder(polygon.maPoints[0]); int iSecurityCounter = 0; while (iSegmentIndex < polygon.maPoints.Length - 1 && iSecurityCounter++ < 10000) { // Coroutine time management if (Time.realtimeSinceStartup - fTimeWhenStartedChunk > MAX_TIME_CHUNK) { // Enough done this frame, go on holiday yield return(null); // Back from holyday fTimeWhenStartedChunk = Time.realtimeSinceStartup; } // P---------------R // / \ triangle2 // // / \ / / // \ / \ / / // \ / triangle1 \ / / // currentVertex * -------------X-- / // |\ ' - _ \ / // | \ - _ \ / // - Q // Vector3 vPosition = currentVertex.mvPos; Vector3 vDirection = polygon.maPoints[iSegmentIndex + 1] - vPosition; // A saveguard for some nasty infinitely-go-and-fro-between-two-vertices cases while (Vector3.Dot(vDirection, polygon.maPoints[iSegmentIndex + 1] - polygon.maPoints[iSegmentIndex]) < 0) { Debug.Log("Wait, wait, we're going into the wrong direction"); iSegmentIndex++; vDirection = polygon.maPoints[iSegmentIndex + 1] - vPosition; } vDirection.y = 0.0f; if (iSecurityCounter == 9999) { Debug.DrawLine(vPosition - Vector3.up, vPosition + Vector3.up, Color.magenta, 1000.0f); Debug.Log("Endless loop?"); Debug.Break(); } if (iSecurityCounter > 9980) { Debug.DrawLine(vPosition - Vector3.up * 0.5f, vPosition + Vector3.up * 0.5f, Color.white, 1000.0f); currentVertex.DebugLogInfo("Current vertex", Vector3.zero); } if (vDirection * 1.0e6f == Vector3.zero) { Debug.LogError("vDirection is zero. "); } if (iSegmentIndex + 1 < maVerticesUnderPolygonPoints.Length && maVerticesUnderPolygonPoints[iSegmentIndex + 1].IsNeighbourOf(currentVertex)) { currentVertex = maVerticesUnderPolygonPoints[iSegmentIndex + 1]; iSegmentIndex++; } else { // Check if there is a neighbor vertex just in this direction Vertex N = currentVertex.GetNeighbourVertexInDirection(vDirection); if (N != null) { // No subdivision required, just procede to vertex N if (N.IsUnder(polygon.maPoints[iSegmentIndex + 1])) { // We reach a corner iSegmentIndex++; } currentVertex = N; } else { // Search the vertices P, Q and the triangles triangle1 and triangle2 Vertex P; Vertex Q; Triangle triangle1 = currentVertex.GetAdjacentTriangleInDirection(vDirection, out P, out Q); if (triangle1 == null) { Debug.LogError("Couldn't find triangle under polygon."); currentVertex.DebugLogInfo("Current vertex ", Vector3.zero); currentVertex.DebugDrawAdjacentTriangles(Color.red); iSegmentIndex = polygon.maPoints.Length; break; } Triangle triangle2 = triangle1.GetNeighbourTriangleBehind(P, Q); if (triangle2 == null) { Debug.LogError("Couldn't find triangle 'behind' the one under polygon"); currentVertex.DebugDrawAdjacentTriangles(Color.yellow); iSegmentIndex = polygon.maPoints.Length; break; } Vertex R = triangle2.GetThirdCorner(P, Q); //Compute X float fCutRatio; Vector3 vX = GeometryToolbox.CutSegmentByLine(P.mvPos, Q.mvPos, vPosition, vPosition + vDirection, out fCutRatio); // Sometimes the cut ratio is very close to 0 or 1, even if this should theoretically not happen. In this case we do the same thing as above in the case "N != null" if (fCutRatio < 0.001f) { // Don't need a new point, P is fine if (P.IsUnder(polygon.maPoints[iSegmentIndex + 1])) { // We reach a corner iSegmentIndex++; } currentVertex = P; } else if (fCutRatio > 0.999f) { // Same for Q if (Q.IsUnder(polygon.maPoints[iSegmentIndex + 1])) { // We reach a corner iSegmentIndex++; } currentVertex = Q; } else { // Add vertex Vertex X = AddVertex(vX); X.mvUV = Vector2.Lerp(P.mvUV, Q.mvUV, fCutRatio); #if UNITY_EDITOR X.DEBUG_INFO = "added on line in step 2, fCutRatio = " + fCutRatio; #endif // Replace triangle1 RemoveTriangle(triangle1); AddTriangle(currentVertex, X, P); AddTriangle(currentVertex, Q, X); // Replace triangle2 RemoveTriangle(triangle2); AddTriangle(X, Q, R); AddTriangle(X, R, P); // Go on if ((currentVertex.mvPos - P.mvPos).magnitude < 0.00001f) { //currentVertex vertex is very near to P - goto on. currentVertex = P; } else if ((currentVertex.mvPos - Q.mvPos).magnitude < 0.00001f) { // Idem for Q currentVertex = Q; } else if (R.IsUnder(polygon.maPoints[iSegmentIndex + 1])) { // We reach a corner currentVertex = R; iSegmentIndex++; } else { currentVertex = X; } while (iSegmentIndex + 1 < polygon.maPoints.Length && currentVertex.IsUnder(polygon.maPoints[iSegmentIndex + 1])) { iSegmentIndex++; } } } } // Debug.DrawLine( vPosition, currentVertex.mvPos, Color.red, 1000.0f); } // maVerticesUnderPolygonPoints is not needed anymore maVerticesUnderPolygonPoints = new Vertex[0]; Profiler.EndSample(); }