private int XMax(InsideData a, InsideData b) { if (a.xMaxPoint.x > b.xMaxPoint.x) { return(-1); } if (b.xMaxPoint.x > a.xMaxPoint.x) { return(1); } return(0); }
private int XMax(InsideData a, InsideData b) { if (a.xMaxPoint.x > b.xMaxPoint.x) return -1; if (b.xMaxPoint.x > a.xMaxPoint.x) return 1; return 0; }
public bool SetMeshData(int resolution) { var pointsList2 = new List<Vector2[]>(_contourList.Count); // Sort any inside lines by largest X value var xMaxVertices = new int[_contourList.Count]; var xMaxPoints = new Vector2[_contourList.Count]; for (int i = 0; i < _contourList.Count; i++) { if (_contourList[i].side == Side.Out) { pointsList2.Add (RenderContourPoints (_contourList[i], resolution, false)); continue; } var insideList = new List<InsideData>(); int arrayIdx = i; for (; i < _contourList.Count; i++) { var inside = new InsideData(); inside.points = RenderContourPoints (_contourList[i], resolution, false); var points = inside.points; int xMaxVertex = 0; float xMax = points[0].x; float yVal = points[0].y; int end = points.Length; for (int j = 1; j < end; j++) { if (points[j].x > xMax) { xMax = points[j].x; yVal = points[j].y; xMaxVertex = j; } } inside.xMaxPoint = new Vector2(xMax, yVal); inside.xMaxVertex = xMaxVertex; insideList.Add (inside); if (i+1 == _contourList.Count || _contourList[i+1].side == Side.Out) { insideList.Sort (XMax); for (int j = 0; j < insideList.Count; j++) { pointsList2.Add (insideList[j].points); xMaxVertices[arrayIdx] = insideList[j].xMaxVertex; xMaxPoints[arrayIdx++] = insideList[j].xMaxPoint; } break; } } } // Find out how many triangles/vertices there will be, and make a list that holds an array of vertex references for each line var vertexCounts = new int[pointsList2.Count]; var vertexList = new List<int[]>(pointsList2.Count); int vertexIndex = 0; int totalVertices = 0; int pointCount = 0; int totalTriangles = 0; for (int i = 0; i < pointsList2.Count; i++) { if (_contourList[i].side == Side.Out && i > 0) { totalTriangles += (pointCount-2) * 3; pointCount = 0; } var points = pointsList2[i]; int vertexCount = points.Length; if (points.Length > 2 && points[0] == points[vertexCount-1]) vertexCount--; if (vertexCount < 3) { vertexList.Add (null); continue; } vertexCounts[i] = vertexCount; totalVertices += vertexCount; if (_contourList[i].side == Side.Out) vertexIndex = 0; var vertexArray = new int[vertexCount]; for (var j = 0; j < vertexCount; j++) { vertexArray[j] = j + vertexIndex; } vertexIndex += vertexCount; vertexList.Add (vertexArray); pointCount += vertexCount; if (_contourList[i].side == Side.In) pointCount += 2; // Because each interior line requires a "cut" with 2 additional points } // Debug outlines --- // for (int i = 0; i < pointsList2.Count; i++) { // if (vertexCounts[i] < 3) continue; // var lineColor = _contourList[i].side == Side.Out? Color.green : Color.red; // var outline = new VectorLine("contour "+i, pointsList2[i], lineColor, null, 2.0f, LineType.Continuous); // outline.depth = 1; // outline.Draw(); // } totalTriangles += (pointCount-2) * 3; int totalFrontVertices = totalVertices; int totalFrontTriangles = totalTriangles; // Allow for backface totalVertices *= 2; totalTriangles *= 2; // Allow for extrusion for (int i = 0; i < vertexCounts.Length; i++) { totalVertices += vertexCounts[i] * 4; totalTriangles += vertexCounts[i] * 6; } if (totalVertices > 65534) { Debug.LogError ("Too many points...resolution is too high or character is too complex"); return false; } var meshVertices = new Vector3[totalVertices]; var meshTriangles = new int[totalTriangles]; // Copy all Vector2 points to the mesh vertices array int idx = 0; for (int i = 0; i < pointsList2.Count; i++) { var points = pointsList2[i]; int vertexCount = vertexCounts[i]; for (int j = 0; j < vertexCount; j++) { meshVertices[idx ].x = points[j].x; meshVertices[idx++].y = points[j].y; } } int triIdx = 0; int triAdd = 0; if (!Triangulate.Compute (_contourList, vertexList, vertexCounts, xMaxVertices, xMaxPoints, pointsList2, meshTriangles, ref triIdx, ref triAdd)) { return false; } // Do verts and triangles for back face Array.Copy (meshVertices, 0, meshVertices, totalFrontVertices, totalFrontVertices); for (int i = 0; i < totalFrontTriangles; i += 3) { meshTriangles[i + totalFrontTriangles ] = meshTriangles[i + 2] + totalFrontVertices; meshTriangles[i + totalFrontTriangles + 1] = meshTriangles[i + 1] + totalFrontVertices; meshTriangles[i + totalFrontTriangles + 2] = meshTriangles[i ] + totalFrontVertices; } // Do edges for extrusion int frontIdx = 0; int backIdx = totalFrontVertices; int edgeIdx = totalFrontVertices * 2; Vector2 l1, l2; float p2x, p2y; float smoothAngle = Mathf.Clamp (FlyingText.smoothingAngle, 0.0f, 180.0f); triIdx = totalFrontTriangles * 2; triAdd *= 2; int edgeVertCount = 0, edgeTriCount = 0; for (int i = 0; i < pointsList2.Count; i++) { if (vertexCounts[i] < 3) continue; int vEnd = vertexCounts[i], j1 = 0, j2 = 0; int originalTriAdd = triAdd; int vCount = 0; for (int j = 0; j < vEnd; j++) { j1 = j+1; if (j1 == vEnd) j1 = 0; j2 = j1+1; if (j2 == vEnd) j2 = 0; // Get this segment and the next one, so the angle can be computed p2x = meshVertices[frontIdx + j1].x; p2y = meshVertices[frontIdx + j1].y; l1.x = meshVertices[frontIdx + j].x - p2x; l1.y = meshVertices[frontIdx + j].y - p2y; l2.x = meshVertices[frontIdx + j2].x - p2x; l2.y = meshVertices[frontIdx + j2].y - p2y; meshVertices[edgeIdx ] = meshVertices[frontIdx + j]; meshVertices[edgeIdx + 1] = meshVertices[backIdx + j]; if (vCount != 0) { AddTriangle (meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount); } if (180.0f - Vector2.Angle(l1, l2) >= smoothAngle) { meshVertices[edgeIdx + 2] = meshVertices[frontIdx + j1]; meshVertices[edgeIdx + 3] = meshVertices[backIdx + j1]; edgeIdx += 4; vCount = 4; edgeVertCount += 4; } else { edgeIdx += 2; vCount = 2; edgeVertCount += 2; } } if (vCount == 4) { AddTriangle (meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount); } else { meshTriangles[triIdx ] = triAdd; meshTriangles[triIdx + 1] = triAdd + 1; meshTriangles[triIdx + 2] = originalTriAdd; meshTriangles[triIdx + 3] = triAdd + 1; meshTriangles[triIdx + 4] = originalTriAdd + 1; meshTriangles[triIdx + 5] = originalTriAdd; triIdx += 6; triAdd += vCount; edgeTriCount += 6; } idx += vEnd; frontIdx += vEnd; backIdx += vEnd; } if (meshVertices.Length != totalFrontVertices * 2 + edgeVertCount) { Array.Resize (ref meshVertices, totalFrontVertices * 2 + edgeVertCount); } if (meshTriangles.Length != totalFrontTriangles * 2 + edgeTriCount) { Array.Resize (ref meshTriangles, totalFrontTriangles * 2 + edgeTriCount); } _baseVertices = meshVertices; _baseTriangles = meshTriangles; _frontVertIndex = totalFrontVertices; _frontTriIndex = totalFrontTriangles; _scaleFactor = -1.0f; return true; }
public bool SetMeshData(int resolution) { var pointsList2 = new List <Vector2[]>(_contourList.Count); // Sort any inside lines by largest X value var xMaxVertices = new int[_contourList.Count]; var xMaxPoints = new Vector2[_contourList.Count]; for (int i = 0; i < _contourList.Count; i++) { if (_contourList[i].side == Side.Out) { pointsList2.Add(RenderContourPoints(_contourList[i], resolution, false)); continue; } var insideList = new List <InsideData>(); int arrayIdx = i; for (; i < _contourList.Count; i++) { var inside = new InsideData(); inside.points = RenderContourPoints(_contourList[i], resolution, false); var points = inside.points; int xMaxVertex = 0; float xMax = points[0].x; float yVal = points[0].y; int end = points.Length; for (int j = 1; j < end; j++) { if (points[j].x > xMax) { xMax = points[j].x; yVal = points[j].y; xMaxVertex = j; } } inside.xMaxPoint = new Vector2(xMax, yVal); inside.xMaxVertex = xMaxVertex; insideList.Add(inside); if (i + 1 == _contourList.Count || _contourList[i + 1].side == Side.Out) { insideList.Sort(XMax); for (int j = 0; j < insideList.Count; j++) { pointsList2.Add(insideList[j].points); xMaxVertices[arrayIdx] = insideList[j].xMaxVertex; xMaxPoints[arrayIdx++] = insideList[j].xMaxPoint; } break; } } } // Find out how many triangles/vertices there will be, and make a list that holds an array of vertex references for each line var vertexCounts = new int[pointsList2.Count]; var vertexList = new List <int[]>(pointsList2.Count); int vertexIndex = 0; int totalVertices = 0; int pointCount = 0; int totalTriangles = 0; for (int i = 0; i < pointsList2.Count; i++) { if (_contourList[i].side == Side.Out && i > 0) { totalTriangles += (pointCount - 2) * 3; pointCount = 0; } var points = pointsList2[i]; int vertexCount = points.Length; if (points.Length > 2 && points[0] == points[vertexCount - 1]) { vertexCount--; } if (vertexCount < 3) { vertexList.Add(null); continue; } vertexCounts[i] = vertexCount; totalVertices += vertexCount; if (_contourList[i].side == Side.Out) { vertexIndex = 0; } var vertexArray = new int[vertexCount]; for (var j = 0; j < vertexCount; j++) { vertexArray[j] = j + vertexIndex; } vertexIndex += vertexCount; vertexList.Add(vertexArray); pointCount += vertexCount; if (_contourList[i].side == Side.In) { pointCount += 2; // Because each interior line requires a "cut" with 2 additional points } } // Debug outlines --- // for (int i = 0; i < pointsList2.Count; i++) { // if (vertexCounts[i] < 3) continue; // var lineColor = _contourList[i].side == Side.Out? Color.green : Color.red; // var outline = new VectorLine("contour "+i, pointsList2[i], lineColor, null, 2.0f, LineType.Continuous); // outline.depth = 1; // outline.Draw(); // } totalTriangles += (pointCount - 2) * 3; int totalFrontVertices = totalVertices; int totalFrontTriangles = totalTriangles; // Allow for backface totalVertices *= 2; totalTriangles *= 2; // Allow for extrusion for (int i = 0; i < vertexCounts.Length; i++) { totalVertices += vertexCounts[i] * 4; totalTriangles += vertexCounts[i] * 6; } if (totalVertices > 65534) { Debug.LogError("Too many points...resolution is too high or character is too complex"); return(false); } var meshVertices = new Vector3[totalVertices]; var meshTriangles = new int[totalTriangles]; // Copy all Vector2 points to the mesh vertices array int idx = 0; for (int i = 0; i < pointsList2.Count; i++) { var points = pointsList2[i]; int vertexCount = vertexCounts[i]; for (int j = 0; j < vertexCount; j++) { meshVertices[idx].x = points[j].x; meshVertices[idx++].y = points[j].y; } } int triIdx = 0; int triAdd = 0; if (!Triangulate.Compute(_contourList, vertexList, vertexCounts, xMaxVertices, xMaxPoints, pointsList2, meshTriangles, ref triIdx, ref triAdd)) { return(false); } // Do verts and triangles for back face Array.Copy(meshVertices, 0, meshVertices, totalFrontVertices, totalFrontVertices); for (int i = 0; i < totalFrontTriangles; i += 3) { meshTriangles[i + totalFrontTriangles] = meshTriangles[i + 2] + totalFrontVertices; meshTriangles[i + totalFrontTriangles + 1] = meshTriangles[i + 1] + totalFrontVertices; meshTriangles[i + totalFrontTriangles + 2] = meshTriangles[i] + totalFrontVertices; } // Do edges for extrusion int frontIdx = 0; int backIdx = totalFrontVertices; int edgeIdx = totalFrontVertices * 2; Vector2 l1, l2; float p2x, p2y; float smoothAngle = Mathf.Clamp(FlyingText.smoothingAngle, 0.0f, 180.0f); triIdx = totalFrontTriangles * 2; triAdd *= 2; int edgeVertCount = 0, edgeTriCount = 0; for (int i = 0; i < pointsList2.Count; i++) { if (vertexCounts[i] < 3) { continue; } int vEnd = vertexCounts[i], j1 = 0, j2 = 0; int originalTriAdd = triAdd; int vCount = 0; for (int j = 0; j < vEnd; j++) { j1 = j + 1; if (j1 == vEnd) { j1 = 0; } j2 = j1 + 1; if (j2 == vEnd) { j2 = 0; } // Get this segment and the next one, so the angle can be computed p2x = meshVertices[frontIdx + j1].x; p2y = meshVertices[frontIdx + j1].y; l1.x = meshVertices[frontIdx + j].x - p2x; l1.y = meshVertices[frontIdx + j].y - p2y; l2.x = meshVertices[frontIdx + j2].x - p2x; l2.y = meshVertices[frontIdx + j2].y - p2y; meshVertices[edgeIdx] = meshVertices[frontIdx + j]; meshVertices[edgeIdx + 1] = meshVertices[backIdx + j]; if (vCount != 0) { AddTriangle(meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount); } if (180.0f - Vector2.Angle(l1, l2) >= smoothAngle) { meshVertices[edgeIdx + 2] = meshVertices[frontIdx + j1]; meshVertices[edgeIdx + 3] = meshVertices[backIdx + j1]; edgeIdx += 4; vCount = 4; edgeVertCount += 4; } else { edgeIdx += 2; vCount = 2; edgeVertCount += 2; } } if (vCount == 4) { AddTriangle(meshTriangles, ref triAdd, ref triIdx, ref edgeTriCount, ref vCount); } else { meshTriangles[triIdx] = triAdd; meshTriangles[triIdx + 1] = triAdd + 1; meshTriangles[triIdx + 2] = originalTriAdd; meshTriangles[triIdx + 3] = triAdd + 1; meshTriangles[triIdx + 4] = originalTriAdd + 1; meshTriangles[triIdx + 5] = originalTriAdd; triIdx += 6; triAdd += vCount; edgeTriCount += 6; } idx += vEnd; frontIdx += vEnd; backIdx += vEnd; } if (meshVertices.Length != totalFrontVertices * 2 + edgeVertCount) { Array.Resize(ref meshVertices, totalFrontVertices * 2 + edgeVertCount); } if (meshTriangles.Length != totalFrontTriangles * 2 + edgeTriCount) { Array.Resize(ref meshTriangles, totalFrontTriangles * 2 + edgeTriCount); } _baseVertices = meshVertices; _baseTriangles = meshTriangles; _frontVertIndex = totalFrontVertices; _frontTriIndex = totalFrontTriangles; _scaleFactor = -1.0f; return(true); }