protected override void HandleOnUpdate() { for(int i = 0; i<OuterPolygon.Count; i++) { List<Vector2> union = PolygonAlgorithm.Combine(OuterPolygon[i], new List<List<Vector2>>() { InnerHole[i] }); if ((FaceType & Facing.FACE_BACK) == Facing.FACE_BACK) CalcFaceMeshData(union, ForceEarCut.ComputeTriangles(union), Facing.FACE_FORWARD, tinkness, ref vertices, ref normals, ref uv, ref triangles); if ((FaceType & Facing.FACE_BACK) == Facing.FACE_BACK) CalcFaceMeshData(union, ForceEarCut.ComputeTriangles(union), Facing.FACE_BACK, tinkness, ref vertices, ref normals, ref uv, ref triangles); } if(IsTinkness) { foreach (var outer in OuterPolygon) { //outer.Reverse(); CalcSideMeshData(outer, tinkness, ref vertices, ref normals, ref uv, ref triangles); } foreach (var inner in InnerHole) { CalcSideMeshData(inner, tinkness, ref vertices, ref normals, ref uv, ref triangles); } } }
public static List <Vector2> Combine(PolygonTree tree) { List <Vector2> exVertices = new List <Vector2>(tree.exterior.vertices); if (!ForceEarCut.AreVerticesClockwise(exVertices, 0, exVertices.Count)) { exVertices.Reverse(); } if (tree.interiors == null || tree.interiors.Count == 0) { return(exVertices); } List <List <Vector2> > inPolygons = new List <List <Vector2> >(tree.interiors.Count); foreach (Polygon inPoly in tree.interiors) { List <Vector2> verts = new List <Vector2>(inPoly.vertices); if (!ForceEarCut.AreVerticesClockwise(verts, 0, verts.Count)) { verts.Reverse(); } inPolygons.Add(verts); } return(Combine(exVertices, inPolygons)); }
public void OnUpdateMesh() { List <Vector3> verts = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> tris = new List <int>(); List <Vector2> points = PolygonAlgorithm.Combine(_shape2D); List <int> triangles = ForceEarCut.ComputeTriangles(points); if ((facing & Facing.FACE_BACK) == Facing.FACE_BACK) { CalculateMeshData(points, triangles, Facing.FACE_BACK, _thickness, ref verts, ref uvs, ref tris); } if ((facing & Facing.FACE_FORWARD) == Facing.FACE_FORWARD) { CalculateMeshData(points, triangles, Facing.FACE_FORWARD, _thickness, ref verts, ref uvs, ref tris); } Mesh _mesh = GetComponent <MeshFilter>().sharedMesh; if (_mesh == null) { _mesh = new Mesh(); _mesh.name = "Face_Mesh"; GetComponent <MeshFilter>().mesh = _mesh; } _mesh.Clear(); _mesh.vertices = verts.ToArray(); _mesh.uv = uvs.ToArray(); _mesh.triangles = tris.ToArray(); _mesh.RecalculateNormals(); ; }
public void OnUpdateMesh() { List <Vector3> verts = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> tris = new List <int>(); if (join == Join.JOIN_BEVEL) { if (!ForceEarCut.AreVerticesClockwise(_shape2D.exterior.vertices, 0, _shape2D.exterior.vertices.Count)) { _shape2D.exterior.vertices.Reverse(); } CalculateBevelOutline(_shape2D.exterior.vertices, _strokeWidth, ref verts, ref uvs, ref tris); foreach (Polygon inter in _shape2D.interiors) { if (ForceEarCut.AreVerticesClockwise(inter.vertices, 0, inter.vertices.Count)) { inter.vertices.Reverse(); } CalculateBevelOutline(inter.vertices, _strokeWidth, ref verts, ref uvs, ref tris); } } else if (join == Join.JOIN_MITER) { if (!ForceEarCut.AreVerticesClockwise(_shape2D.exterior.vertices, 0, _shape2D.exterior.vertices.Count)) { _shape2D.exterior.vertices.Reverse(); } CalculateMeshData(_shape2D.exterior.vertices, _strokeWidth, ref verts, ref uvs, ref tris); foreach (Polygon inter in _shape2D.interiors) { if (ForceEarCut.AreVerticesClockwise(inter.vertices, 0, inter.vertices.Count)) { inter.vertices.Reverse(); } CalculateMeshData(inter.vertices, _strokeWidth, ref verts, ref uvs, ref tris); } } Mesh _mesh = GetComponent <MeshFilter>().sharedMesh; if (_mesh == null) { _mesh = new Mesh(); _mesh.name = "Outline_Mesh"; GetComponent <MeshFilter>().mesh = _mesh; } _mesh.Clear(); _mesh.vertices = verts.ToArray(); _mesh.uv = uvs.ToArray(); _mesh.triangles = tris.ToArray(); _mesh.RecalculateNormals(); ; OnCalculateRect(); }
public void SetVertices(Vector2[] array) { vertices = new List <Vector2>(array); if (!ForceEarCut.AreVerticesClockwise(vertices, 0, vertices.Count)) { vertices.Reverse(); } }
public static List <Vector2> Combine(List <Vector2> exVertices, List <List <Vector2> > inPolygons) { // inP.Clear(); // exP.Clear(); List <Vector2> inP = new List <Vector2>(); List <Vector2> exP = new List <Vector2>(); //List<Vector2> exVertices = new List<Vector2>(tree.exterior.vertices);//new List<Vector2>(poly.exteriorRing.vertices); // List<Polygon> inPolygons = new List<Polygon>(tree.interiors); // List<Vector2> inVertices = new List<Vector2>(); // foreach(Polygon poly in inPolygons){ // inVertices.AddRange(poly.vertices); // } while (inPolygons.Count > 0) { Vector2 inVertex = inPolygons[0][0]; int index = 0; for (int i = 0; i < inPolygons.Count; i++) { if (GetRightMostVertex(inPolygons[i], ref inVertex)) { index = i; } } Intersection inter = Intersection.none; if (CGAlgorithm.SegmentSkewPoly(inVertex, inVertex + RIGHT_DISTANCE, exVertices, ref inter)) { if (inter.Type == PointType.ON_EDGE) { exVertices.Insert(inter.EdgeEndIndex, inter.Point0); } Combine(ref exVertices, ref inP, ref exP, inPolygons[index], inter.Point0, inVertex); } else { //Debug.LogError("The " + index +" interior polygon cannot combine to exterior polygon !"); } inPolygons.RemoveAt(index); } if (!ForceEarCut.AreVerticesClockwise(exVertices, 0, exVertices.Count)) { exVertices.Reverse(); } return(exVertices); }
protected override void HandleOnUpdateVertices() { float length = Vector3.Distance(startPosition, endPosition) - blankCap * 2; float halfLength = length * 0.5f; float halfWidth = width * 0.5f; Vector3 position = (endPosition + startPosition) * 0.5f; float angle = Mathf.Atan2(endPosition.x - startPosition.x, endPosition.y - startPosition.y) * Mathf.Rad2Deg; Quaternion rotation = Quaternion.AngleAxis(angle, Vector3.back); //Quaternion rotation = Quaternion.FromToRotation(Vector3.up, endPos - startPos); transform.localPosition = position; transform.localRotation = rotation; /*Vertices[0] = halfLength*Vector3.left + Vector3.down * size; * Vertices[1] = halfLength*Vector3.left + Vector3.up * size; * Vertices[2] = halfLength*Vector3.right + Vector3.up * size; * Vertices[3] = halfLength*Vector3.right + Vector3.down * size;*/ /*Vertices[0] = halfWidth * Vector3.left + Vector3.down * halfLength; * Vertices[1] = halfWidth * Vector3.left + Vector3.up * halfLength; * Vertices[2] = halfWidth * Vector3.right + Vector3.up * halfLength; * Vertices[3] = halfWidth * Vector3.right + Vector3.down * halfLength;*/ List <Vector3> vertices = new List <Vector3>() { (halfWidth * Vector3.left + Vector3.down * halfLength), (halfWidth * Vector3.left + Vector3.up * halfLength), (halfWidth * Vector3.right + Vector3.up * halfLength), (halfWidth * Vector3.right + Vector3.down * halfLength) }; /*vertices.Add(halfWidth * Vector3.left + Vector3.down * halfLength); * vertices.Add(halfWidth * Vector3.left + Vector3.up * halfLength); * vertices.Add(halfWidth * Vector3.right + Vector3.up * halfLength); * vertices.Add(halfWidth * Vector3.right + Vector3.down * halfLength);*/ if (!ForceEarCut.AreVerticesClockwise(vertices.Select(v => new Vector2(v.x, v.y)).ToList(), 0, 4)) { vertices.Reverse(); } Vertices = vertices.ToArray(); float f = length / width; Vector2[] uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, f), new Vector2(1, f), new Vector2(1, 0) }; UV = uv; }
public static List <Vector2> ScalePoly(List <Vector2> Poly, float Spacing) { int n = Poly.Count; if (ForceEarCut.AreVerticesClockwise(Poly, 0, n)) { Poly.Reverse(); } List <Vector2> scaledPoly = new List <Vector2>(); Vector2 P0, P1, P2, P3; Vector2 I0, I1; n = Poly.Count; for (int i = 0; i < n; i++) { P0 = Poly[PreIndex(i, n)]; P1 = Poly[i]; P2 = Poly[i]; P3 = Poly[NextIndex(i, n)]; TranslateSegment(ref P0, ref P1, Spacing); TranslateSegment(ref P2, ref P3, Spacing); if (Intersect2D_2Segments(P0, P1, P2, P3, out I0, out I1) > 0) { scaledPoly.Add(I0); } else { scaledPoly.Add(P1); scaledPoly.Add(P2); } } return(scaledPoly); }
public void OnUpdateMesh() { List <Vector3> verts = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <int> tris = new List <int>(); // // float halfThickness = _thickness * 0.5F; CalculateMeshData(_shape2D.exterior.vertices, _thickness, ref verts, ref uvs, ref tris); foreach (Polygon inPolygon in _shape2D.interiors) { if (ForceEarCut.AreVerticesClockwise(inPolygon.vertices, 0, inPolygon.vertices.Count)) { inPolygon.vertices.Reverse(); } CalculateMeshData(inPolygon.vertices, _thickness, ref verts, ref uvs, ref tris); } Mesh _mesh = GetComponent <MeshFilter>().sharedMesh; if (_mesh == null) { _mesh = new Mesh(); _mesh.name = "Side_Mesh"; GetComponent <MeshFilter>().mesh = _mesh; } _mesh.Clear(); _mesh.vertices = verts.ToArray(); _mesh.uv = uvs.ToArray(); _mesh.triangles = tris.ToArray(); _mesh.RecalculateNormals(); ; }
protected override void HandleOnUpdate() { Clear(); List <Vector3> points = TriangleMesh.Vertices.Select(p => new Vector3((float)p.X, (float)p.Y, 0)).ToList(); foreach (var segment in TriangleMesh.Segments) { Vector3 p0 = points[segment.P0]; Vector3 p1 = points[segment.P1]; Vector3 a = p0 + offsetPos; Vector3 b = p1 + offsetPos; Vector3 c = p1 - offsetPos; Vector3 d = p0 - offsetPos; Vector3 normal = p1 - p0; Vector3 tangent = Vector3.back; Vector3 binormal = Vector3.zero; Vector3.OrthoNormalize(ref normal, ref tangent, ref binormal); Matrix4x4 toNewSpace = new Matrix4x4(); toNewSpace.SetRow(0, normal); toNewSpace.SetRow(1, tangent); toNewSpace.SetRow(2, binormal); toNewSpace[3, 3] = 1.0F; Vector3 ma = toNewSpace.MultiplyPoint3x4(a); Vector3 mb = toNewSpace.MultiplyPoint3x4(b); Vector3 mc = toNewSpace.MultiplyPoint3x4(c); Vector3 md = toNewSpace.MultiplyPoint3x4(d); //Debug.Log(string.Format("{0}:{1},{2}:{3},{4}:{5},{6}:{7}", a, ma, b, mb, c, mc, d, md)); /* * basisA = stretchAxis; * Vector3.OrthoNormalize(ref basisA, ref basisB, ref basisC); * Matrix4x4 toNewSpace = new Matrix4x4(); * toNewSpace.SetRow(0, basisA); * toNewSpace.SetRow(1, basisB); * toNewSpace.SetRow(2, basisC); * toNewSpace[3, 3] = 1.0F; * * Matrix4x4 scale = new Matrix4x4(); * scale[0, 0] = stretchFactor; * scale[1, 1] = 1.0F / stretchFactor; * scale[2, 2] = 1.0F / stretchFactor; * scale[3, 3] = 1.0F; * Matrix4x4 fromNewSpace = toNewSpace.transpose; * Matrix4x4 trans = toNewSpace * scale * fromNewSpace; * int i = 0; * while (i < origVerts.Length) { * newVerts[i] = trans.MultiplyPoint3x4(origVerts[i]); * i++; * } * mf.mesh.vertices = newVerts; * */ List <Vector2> quad2 = new List <Vector2>() { (Vector2)ma, (Vector2)mb, (Vector2)mc, (Vector2)md }; List <Vector3> quad3 = new List <Vector3>() { a, b, c, d }; if (ForceEarCut.AreVerticesClockwise(quad2, 0, 4)) { quad3.Reverse(); } normals.Add(binormal); normals.Add(binormal); normals.Add(binormal); normals.Add(binormal); /*vertices.Add(p0 + offsetPos); * vertices.Add(p1 + offsetPos); * vertices.Add(p1 - offsetPos); * vertices.Add(p0 - offsetPos);*/ vertices.AddRange(quad3); float dis = Vector3.Distance(p0, p1); float f = dis / shapeDepth; uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(0, f)); uv.Add(new Vector2(1, f)); uv.Add(new Vector2(1, 0)); } for (int a = 0, n = points.Count * 4; a < n; a += 4) { var b = (a + 1) % n; var c = (a + 2) % n; var d = (a + 3) % n; triangles.Add(a); // (offsetIndex + a); triangles.Add(b); // (offsetIndex + b); triangles.Add(c); // (offsetIndex + c); triangles.Add(a); // (offsetIndex + a); triangles.Add(c); // (offsetIndex + c); triangles.Add(d); // (offsetIndex + d); } //CalculateSideData(TriangleMesh.Vertices.Select(p => new Vector2((float)p.X, (float)p.Y)).ToList()); }
public static bool Operate(List <Vector2> subjPoly, List <Vector2> operPoly, out List <Vector2> result, OPERATION operation = OPERATION.OR) { result = new List <Vector2>(); int sn = subjPoly.Count; int on = operPoly.Count; if (!ForceEarCut.AreVerticesClockwise(subjPoly, 0, sn)) { subjPoly.Reverse(); } //当union == UNION.NOT时,operPoly 应该是逆时针方向。 if (operation == OPERATION.NOT) { if (ForceEarCut.AreVerticesClockwise(operPoly, 0, on)) { operPoly.Reverse(); } } else { if (!ForceEarCut.AreVerticesClockwise(operPoly, 0, on)) { operPoly.Reverse(); } } List <VertexNode> entering = new List <VertexNode>(); List <VertexNode> subjList = new List <VertexNode>(); List <VertexNode> operList = new List <VertexNode>(); VertexNode.FillNodeList(subjList, subjPoly); VertexNode.FillNodeList(operList, operPoly); int oi, oj, si, sj; InterFactor factor; // = InterFactor.none; for (si = 0, sj = sn - 1; si < sn; sj = si++) { for (oi = 0, oj = on - 1; oi < on; oj = oi++) { int nInter = CGAlgorithm.IntersectFactor(subjPoly[sj], subjPoly[si], operPoly[oj], operPoly[oi], out factor); if (nInter == 1) { VertexNode subjNode = new VertexNode(subjList, sj, subjPoly, factor.t, factor.inbound); VertexNode operNode = new VertexNode(operList, oj, operPoly, factor.u, factor.inbound); subjNode.Other = operNode; subjList.Add(subjNode); operList.Add(operNode); if (operation == OPERATION.NOT) { if (!factor.inbound) { entering.Add(operNode); } } else if (operation == OPERATION.OR) { if (factor.inbound) { entering.Add(operNode); } } else if (operation == OPERATION.AND) { if (factor.inbound) { entering.Add(subjNode); } } } } } if (entering.Count == 0) { return(false); } subjList.Sort(); operList.Sort(); while (entering.Count > 0) { VertexNode nextNode = entering[0]; entering.RemoveAt(0); VertexNode startNode = nextNode; result.Add(nextNode.Vlaue); nextNode = nextNode.Next; while (nextNode != startNode && nextNode.Other != startNode) { result.Add(nextNode.Vlaue); if (nextNode.Kind == VerType.Intersection) { if (nextNode.inbound) { if (entering.Contains(nextNode)) { entering.Remove(nextNode); } else if (entering.Contains(nextNode.Other)) { entering.Remove(nextNode.Other); } } nextNode = nextNode.Other.Next; } else { nextNode = nextNode.Next; } } } return(true); }
public void CalculateBevelOutline(List <Vector2> vertices, float strokeWidth, ref List <Vector3> verts, ref List <Vector2> uvs, ref List <int> tris) { int n = vertices.Count; int initIndex = verts.Count; int i = 0; int vertNum = initIndex; float pFactor = 0, nFactor = 0; Vector2 pVer = vertices[n - 1]; Vector2 cVer = vertices[0]; Vector2 nVer = vertices[1]; float pDis = Vector2.Distance(pVer, cVer); float nDis; // = Vector2.Distance(cVer, nVer); // int sign = ForceEarCut.ComputeSpannedAreaSign(pVer, cVer, nVer); Vector2 firstSkewPoint = pVer; Debug.LogError(gameObject.name + " is going on to enter while ... ! "); while (i < n + 1) { nDis = Vector2.Distance(cVer, nVer); if (nDis < strokeWidth) { pDis = Vector2.Distance(pVer, nVer); i++; // cVer = nVer; nVer = vertices[i % n]; continue; } pFactor = pDis / strokeWidth; nFactor = nDis / strokeWidth; Vector2 perPC = CGAlgorithm.Perp(pVer, cVer, strokeWidth); Vector2 perCN = CGAlgorithm.Perp(cVer, nVer, strokeWidth); int sign = ForceEarCut.ComputeSpannedAreaSign(pVer, cVer, nVer); if (sign < 0) { // sign < 0 : // p // \ // \ // === c --> n === Vector2 skewPoint = cVer + perPC; //CGAlgorithm.Intersect2D_2SkewSegments(pVer + perPC, cVer + perPC , cVer + perCN, nVer + perCN, ref skewPoint) ; if (CGAlgorithm.Intersect2D_2SkewSegments(pVer + perPC, cVer + perPC, cVer + perCN, nVer + perCN, ref skewPoint)) { if (vertNum > initIndex) { verts[vertNum - 1] = skewPoint; } verts.Add(pVer); verts.Add(skewPoint); verts.Add(cVer); verts.Add(nVer + perCN); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(0, pFactor)); uvs.Add(new Vector2(1, pFactor + nFactor)); if (_facing == Facing.FACE_FORWARD) { tris.Add(vertNum); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 1); } else if (_facing == Facing.FACE_BACK) { tris.Add(vertNum); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 3); } vertNum += 4; } } else { // or sign > 0 : // p // / // / // === n <-- c === // // }else{ //--------------------------------------------------------------------------- verts.Add(pVer); verts.Add(cVer + perPC); verts.Add(cVer); verts.Add(cVer + perCN); verts.Add(nVer + perCN); uvs.Add(new Vector2(0, 0)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(0, pFactor)); uvs.Add(new Vector2(1, pFactor)); uvs.Add(new Vector2(1, pFactor + nFactor)); if (_facing == Facing.FACE_FORWARD) { tris.Add(vertNum); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 4); tris.Add(vertNum + 3); } else if (_facing == Facing.FACE_BACK) { tris.Add(vertNum); tris.Add(vertNum + 1); tris.Add(vertNum + 2); tris.Add(vertNum + 2); tris.Add(vertNum + 1); tris.Add(vertNum + 3); tris.Add(vertNum + 2); tris.Add(vertNum + 3); tris.Add(vertNum + 4); } vertNum += 5; } i++; pVer = cVer; cVer = nVer; nVer = vertices[i % n]; pDis = nDis; } }