public static Mesh triangulate(Paths paths, AXTexCoords tex) { //Debug.Log ("B"); List <Mesh> meshes = new List <Mesh>(); foreach (Path path in paths) { meshes.Add(AXPolygon.triangulate(Clipper.CleanPolygon(path), tex)); } // combine CombineInstance[] combine = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { combine[i].mesh = meshes[i]; combine[i].transform = Matrix4x4.identity; } Mesh mesh = new Mesh(); mesh.CombineMeshes(combine); mesh.RecalculateNormals(); return(mesh); }
public AXMesh(Mesh m, Matrix4x4 mx, Material _mat, AXTexCoords tex) { //Debug.Log("new axmesh: "+ uShift); mesh = m; transMatrix = mx; mat = _mat; uScale = tex.scale.x; vScale = tex.scale.y; uShift = tex.shift.x; vShift = tex.shift.y; }
public static Mesh triangulate(Spline s, AXTexCoords tex) { Debug.Log("E"); if (s == null) { return(null); } // poly has verts that are delimeted by 8888888 for holes // 1. transpose points to poly2tri structures // 2. create mesh Polygon _polygon = null; List <PolygonPoint> _points = new List <PolygonPoint>(); for (int i = 0; i < s.controlVertices.Count; i++) { _points.Add(new PolygonPoint((double)s.controlVertices[i].x, (double)s.controlVertices[i].y)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); } // populate the polygon triangles if (_polygon != null) { P2T.Triangulate(_polygon); return(polygon2mesh(_polygon, tex)); } return(null); }
// use trianges to construct a mesh public static Mesh polygon2meshOLD(Polygon poly, AXTexCoords tex) { Debug.Log(" OOOOOOOO " + poly.Triangles.ToString()); for (int i = 0; i < poly.Points.Count; i++) { TriangulationPoint pt = poly.Points [i]; Debug.Log("pt [" + i + "] " + pt); } if (tex == null) { tex = new AXTexCoords(); } Mesh tmpMesh = new Mesh(); Vector3[] verts = new Vector3[3 * poly.Triangles.Count]; Vector2[] uv = new Vector2[3 * poly.Triangles.Count]; int[] triangles = new int[3 * poly.Triangles.Count]; Vector3[] normals = new Vector3[3 * poly.Triangles.Count]; Vector3[] tangents = new Vector3[3 * poly.Triangles.Count]; int curv = 0; float u, v; Vector3 normal = Vector3.up; Vector3 tangent = Vector3.right; foreach (DelaunayTriangle triangle in poly.Triangles) { verts[curv] = new Vector3((float)triangle.Points[0].X, 0, (float)triangle.Points[0].Y); if (tex.scale.x != 0) { u = (verts[curv].x + tex.shift.x) / tex.scale.x; v = (verts[curv].z + tex.shift.y) / tex.scale.y; } else { u = (verts[curv].x / .3f); v = (verts[curv].z / .3f); } uv [curv] = new Vector2(u, v); triangles[curv] = curv; normals[curv] = normal; tangents[curv] = tangent; curv++; verts[curv] = new Vector3((float)triangle.Points[2].X, 0, (float)triangle.Points[2].Y); if (tex.scale.x != 0) { u = (verts[curv].x + tex.shift.x) / tex.scale.x; v = (verts[curv].z + tex.shift.y) / tex.scale.y; } else { u = (verts[curv].x / .3f); v = (verts[curv].z / .3f); } uv [curv] = new Vector2(u, v); //Debug.Log ("uv = " + u + ", " + v); triangles[curv] = curv; normals[curv] = normal; tangents[curv] = tangent; curv++; verts[curv] = new Vector3((float)triangle.Points[1].X, 0, (float)triangle.Points[1].Y); if (tex.scale.x != 0) { u = (verts[curv].x + tex.shift.x) / tex.scale.x; v = (verts[curv].z + tex.shift.y) / tex.scale.y; } else { u = (verts[curv].x / .3f); v = (verts[curv].z / .3f); } uv [curv] = new Vector2(u, v); triangles[curv] = curv; normals[curv] = normal; tangents[curv] = tangent; curv++; } tmpMesh.vertices = verts; tmpMesh.uv = uv; tmpMesh.triangles = triangles; tmpMesh.normals = normals; AXGeometryTools.Utilities.calculateMeshTangents(ref tmpMesh); //tmpMesh.tangents = tangents; return(tmpMesh); }
// use trianges to construct a mesh public static Mesh polygon2mesh(Polygon poly, AXTexCoords tex) { Dictionary <TriangulationPoint, int> pointsDict = new Dictionary <TriangulationPoint, int>(); // GATHER UNIQUE POINTS INTO DICTIONARY int index = 0; foreach (DelaunayTriangle triangle in poly.Triangles) { if (!pointsDict.ContainsKey(triangle.Points[0])) { pointsDict[triangle.Points[0]] = index++; } if (!pointsDict.ContainsKey(triangle.Points[1])) { pointsDict[triangle.Points[1]] = index++; } if (!pointsDict.ContainsKey(triangle.Points[2])) { pointsDict[triangle.Points[2]] = index++; } } // CREAT VERTICES FROM UNIQUES Vector3[] vertices = new Vector3[pointsDict.Count]; index = 0; foreach (TriangulationPoint pt in pointsDict.Keys) { vertices[index++] = new Vector3((float)pt.X, 0, (float)pt.Y); } if (tex == null) { tex = new AXTexCoords(); } Mesh tmpMesh = new Mesh(); int[] triangles = new int[3 * poly.Triangles.Count]; int cursor = 0; foreach (DelaunayTriangle triangle in poly.Triangles) { triangles[cursor++] = pointsDict[triangle.Points[0]]; //curv; triangles[cursor++] = pointsDict[triangle.Points[2]]; //curv; triangles[cursor++] = pointsDict[triangle.Points[1]]; //curv; } // SET OTHER MESH DATA Vector2[] uv = new Vector2[vertices.Length]; Vector3[] normals = new Vector3[vertices.Length]; Vector4[] tangents = new Vector4[vertices.Length]; Vector4 tangent = new Vector4(1, 0, 0, -1); float u, v; for (int i = 0; i < vertices.Length; i++) { if (tex.scale.x != 0) { u = (vertices[i].x + tex.shift.x) / tex.scale.x; v = (vertices[i].z + tex.shift.y) / tex.scale.y; } else { u = (vertices[i].x / .3f); v = (vertices[i].z / .3f); } uv [i] = (tex.rotateCapsTex) ? new Vector2(v, u) : new Vector2(u, v); normals[i] = Vector3.up; tangents[i] = tangent; } // POPULATE MESH tmpMesh.vertices = vertices; tmpMesh.uv = uv; tmpMesh.triangles = triangles; tmpMesh.normals = normals; tmpMesh.tangents = tangents; //Utilities.calculateMeshTangents(tmpMesh); return(tmpMesh); }
public static Mesh triangulate(AXSpline poly, float height, AXTexCoords tex) { // poly has verts that are delimeted by 8888888 for holes //Debug.Log ("F"); // 1. transpose points to poly2tri structures // 2. create mesh Polygon _polygon = null; List <AXSpline> parts = poly.getSolidAndHoles(); if (parts == null || parts.Count == 0) { return(null); } // CONTOUR AXSpline contour = parts[0]; List <PolygonPoint> _points = new List <PolygonPoint>(); for (int ii = 0; ii < contour.vertCount; ii++) { _points.Add(new PolygonPoint((double)contour.verts[ii].x, (double)contour.verts[ii].y)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); // HOLES? if (parts.Count > 1) { for (int i = 1; i < parts.Count; i++) { List <PolygonPoint> _holepoints = new List <PolygonPoint>(); for (int ii = 0; ii < parts[i].vertCount; ii++) { _holepoints.Add(new PolygonPoint((double)parts[i].verts[ii].x, (double)parts[i].verts[ii].y)); } if (_holepoints.Count >= 3) { Polygon _hole = new Polygon(_holepoints); _polygon.AddHole(_hole); } } } } // populate the polygon triangles if (_polygon != null) { P2T.Triangulate(_polygon); return(polygon2mesh(_polygon, tex)); } return(null); }
public static Mesh triangulatePolyNode(PolyNode node, AXTexCoords tex, int seglenBigInt = 1000000) { //Debug.Log ("D " + seglenBigInt); Polygon _polygon = null; if (seglenBigInt < 10) { seglenBigInt = 999999; } List <Mesh> meshes = new List <Mesh>(); // Contour is Solid PolygonPoints _points = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(node.Contour), seglenBigInt)); } else { _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(node.Contour)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); } //Debug.Log ("_polygon="+_points.Count); // ADD HOLES TO POLYGON foreach (PolyNode subnode in node.Childs) { PolygonPoints hpoints = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { hpoints = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(subnode.Contour), seglenBigInt)); } else { hpoints = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(subnode.Contour)); } if (hpoints.Count >= 3) { _polygon.AddHole(new Polygon(hpoints)); } } try { // STEINER POINTS ClipperOffset co = new ClipperOffset(); co.AddPath(node.Contour, AXClipperLib.JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon); //addSteinerPointsAtAllOffsets(ref _polygon, ref co, seglenBigInt/AXGeometryTools.Utilities.IntPointPrecision, seglenBigInt); addSteinerPointsAtAllOffsets(ref _polygon, ref co, (float)seglenBigInt / ((float)AXGeometryTools.Utilities.IntPointPrecision), seglenBigInt); P2T.Triangulate(_polygon); meshes.Add(polygon2mesh(_polygon, tex)); } catch { //Debug.Log ("Can't triangulate: probably point on edge."); } // Continue down the tree... /* * foreach(PolyNode cnode in node.Childs) * { * Mesh submesh = triangulatePolyNode(cnode, tex); * if (submesh != null) * meshes.Add(submesh); * } */ CombineInstance[] combine = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { combine[i].mesh = meshes[i]; combine[i].transform = Matrix4x4.identity; } Mesh mesh = new Mesh(); mesh.CombineMeshes(combine); mesh.RecalculateNormals(); return(mesh); }
/* bridges to poly2tri * */ public static Mesh triangulate(Path path, AXTexCoords tex, int seglen = 0) { /* Assume a single path with no holes * and return a mesh. */ if (path == null || path.Count < 3) { return(null); } if (path[path.Count - 1].X == path[0].X && path[path.Count - 1].Y == path[0].Y) { path.RemoveAt(path.Count - 1); } else if (AXGeometryTools.Utilities.IntPointsAreNear(path[0], path[path.Count - 1])) { path.RemoveAt(path.Count - 1); } //Paths tmpPaths = Clipper.SimplifyPolygon (path); //CombineInstance[] combinator = new CombineInstance[tmpPaths.Count]; //for (int i = 0; i < tmpPaths.Count; i++) { Mesh mesh = null; PolygonPoints _points; // = AXGeometryTools.Utilities.path2polygonPts (Pather.cleanPath(path)); if (seglen > 0) { _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(path), seglen)); } else { _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(path)); } Polygon _polygon = null; if (_points.Count >= 3) { _polygon = new Polygon(_points); if (_polygon != null) { try { // Testing Steiner // for (int j = -10; j<10; j++) // { // for (int k = -10; k<10; k++) // _polygon.AddSteinerPoint(new TriangulationPoint(.1f*j, k*.1f)); // } P2T.Triangulate(_polygon); //foreach (DelaunayTriangle triangle in _polygon.Triangles) mesh = polygon2mesh(_polygon, tex); } catch { Debug.Log("Can't triangulate: probably point on edge."); } } //combinator[i].mesh = mesh; //combinator [i].transform = Matrix4x4.identity; //return mesh; //} } // Mesh returnMesh = new Mesh(); // returnMesh.CombineMeshes(combinator); // return returnMesh; return(mesh); }
public static Mesh triangulate(List <PolyNode> childs, AXTexCoords tex, int seglenBigInt = 1000000) { //Debug.Log ("C " + seglenBigInt); Polygon _polygon = null; List <Mesh> meshes = new List <Mesh>(); if (seglenBigInt < 10) { seglenBigInt = 100000; } //int count = 0; foreach (PolyNode node in childs) { // Contour is Solid // List<TriangulationPoint> tripoints = new List<TriangulationPoint>(); // // // Testing Steiner // int cells = 6; // for (int j = -cells/2; j<cells/2; j++) // { // for (int k = -cells/3; k<cells/2; k++) // if (Clipper.PointInPolygon( AXGeometryTools.Utilities.Vec2_2_IntPt(new Vector2(2f*j, k*2f)), node.Contour) > 0) // { // //Debug.Log("add steiner " + .4f*j +", " + k*.2f); // tripoints.Add(new TriangulationPoint(.4f*j, k*.2f)); // } // } PolygonPoints _points = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { _points = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(node.Contour), seglenBigInt)); } else { _points = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(node.Contour)); } // POLYGON if (_points.Count >= 3) { _polygon = new Polygon(_points); } // ADD HOLES TO POLYGON foreach (PolyNode subnode in node.Childs) { PolygonPoints hpoints = null; if (seglenBigInt > 0 && seglenBigInt != 9999999) { hpoints = AXGeometryTools.Utilities.path2polygonPts(Pather.segmentPath(Clipper.CleanPolygon(subnode.Contour), seglenBigInt)); } else { hpoints = AXGeometryTools.Utilities.path2polygonPts(Clipper.CleanPolygon(subnode.Contour)); } if (hpoints.Count >= 3) { _polygon.AddHole(new Polygon(hpoints)); } } try { // STEINER POINTS ClipperOffset co = new ClipperOffset(); co.AddPath(node.Contour, AXClipperLib.JoinType.jtSquare, AXClipperLib.EndType.etClosedPolygon); addSteinerPointsAtAllOffsets(ref _polygon, ref co, (float)seglenBigInt / ((float)AXGeometryTools.Utilities.IntPointPrecision), seglenBigInt); P2T.Triangulate(_polygon); meshes.Add(polygon2mesh(_polygon, tex)); } catch { //Debug.Log ("Can't triangulate: probably point on edge."); } // Continue down the tree... foreach (PolyNode cnode in node.Childs) { Mesh submesh = triangulate(cnode, tex); if (submesh != null) { meshes.Add(submesh); } } } CombineInstance[] combine = new CombineInstance[meshes.Count]; for (int i = 0; i < meshes.Count; i++) { combine[i].mesh = meshes[i]; combine[i].transform = Matrix4x4.identity; } Mesh mesh = new Mesh(); mesh.CombineMeshes(combine); mesh.RecalculateNormals(); return(mesh); }
public static Mesh triangulate(PolyNode polynode, AXTexCoords tex, int seglen = 100000) { return(triangulate(polynode.Childs, tex, seglen)); }
// GENERATE public void generate(ref Mesh mesh, AXTexCoords tex) { if (tex == null) { return; } // Combine the plan and sections to make the fabric float uShift = tex.shift.x; float vShift = tex.shift.y; float uScale = tex.scale.x; float vScale = tex.scale.y; float sx = side_x / 2; //float sy = side_y; float sz = side_z / 2; int faces = (top?1:0) + (bottom?1:0); int totalVertCount = (top?4:0) + (bottom?4:0); int totalTriangCount = faces * 2; Vector3[] p = new Vector3[4]; p[0] = new Vector3(-sx, 0, -sz); p[1] = new Vector3(sx, 0, -sz); p[2] = new Vector3(sx, 0, sz); p[3] = new Vector3(-sx, 0, sz); Vector3[] vt = new Vector3[totalVertCount]; Vector2[] uv = new Vector2[totalVertCount]; int vc = 0; if (top) { vt[vc++] = p[0]; vt[vc++] = p[1]; vt[vc++] = p[2]; vt[vc++] = p[3]; vc -= 4; uv[vc++] = new Vector2(0, side_y); uv[vc++] = new Vector2(side_x, side_y); uv[vc++] = new Vector2(side_x, side_y + side_z); uv[vc++] = new Vector2(0, side_y + side_z); } if (bottom) { vt[vc++] = p[3]; vt[vc++] = p[2]; vt[vc++] = p[1]; vt[vc++] = p[0]; vc -= 4; uv[vc++] = new Vector2(0, -side_z); uv[vc++] = new Vector2(side_x, -side_z); uv[vc++] = new Vector2(side_x, 0); uv[vc++] = new Vector2(0, 0); } for (int i = 0; i < uv.Length; i++) { uv[i] = new Vector2(uv[i].x / uScale + uShift, uv[i].y / vScale + vShift); } int[] t = new int[totalTriangCount * 3]; int tc = 0; for (int f = 0; f < faces; f++) { int b = f * 4; t[tc++] = b + 0; t[tc++] = b + 2; t[tc++] = b + 1; t[tc++] = b + 0; t[tc++] = b + 3; t[tc++] = b + 2; } mesh.vertices = vt; mesh.triangles = t; mesh.uv = uv; mesh.RecalculateNormals(); }
// GENERATE public void generate(ref Mesh mesh, AXTexCoords tex) { if (tex == null) { return; } // Combine the plan and sections to make the fabric float uShift = tex.shift.x; float vShift = tex.shift.y; float uScale = tex.scale.x; float vScale = tex.scale.y; //bool smooth = (breakAngle > 90) ? true : false; float sx = side_x / 2; float sy = side_y; float sz = side_z / 2; int faces = (front?1:0) + (back?1:0) + (left?1:0) + (right?1:0) + (top?1:0) + (bottom?1:0); int totalVertCount = faces * 4; int totalTriangCount = faces * 2; Vector3[] p = new Vector3[8]; p[0] = new Vector3(-sx, 0, -sz); p[1] = new Vector3(sx, 0, -sz); p[2] = new Vector3(sx, 0, sz); p[3] = new Vector3(-sx, 0, sz); p[4] = new Vector3(-sx, sy, -sz); p[5] = new Vector3(sx, sy, -sz); p[6] = new Vector3(sx, sy, sz); p[7] = new Vector3(-sx, sy, sz); // Y-AXIS JITTER /* * if (false) * { * for (int i=4; i<8; i++) * p[i].y *= Mathf.PerlinNoise(p[i].x+100, p[i].z+100); * } */ Vector3[] vt = new Vector3[totalVertCount]; Vector2[] uv = new Vector2[totalVertCount]; int vc = 0; if (front) { vt[vc++] = p[0]; vt[vc++] = p[1]; vt[vc++] = p[5]; vt[vc++] = p[4]; vc -= 4; uv[vc++] = new Vector2(0, 0); uv[vc++] = new Vector2(side_x, 0); uv[vc++] = new Vector2(side_x, side_y); uv[vc++] = new Vector2(0, side_y); } if (right) { vt[vc++] = p[1]; vt[vc++] = p[2]; vt[vc++] = p[6]; vt[vc++] = p[5]; vc -= 4; uv[vc++] = new Vector2(side_x, 0); uv[vc++] = new Vector2(side_x + side_z, 0); uv[vc++] = new Vector2(side_x + side_z, side_y); uv[vc++] = new Vector2(side_x, side_y); } if (back) { vt[vc++] = p[2]; vt[vc++] = p[3]; vt[vc++] = p[7]; vt[vc++] = p[6]; vc -= 4; uv[vc++] = new Vector2(side_x + side_z, 0); uv[vc++] = new Vector2(side_x * 2 + side_z, 0); uv[vc++] = new Vector2(side_x * 2 + side_z, side_y); uv[vc++] = new Vector2(side_x + side_z, side_y); } if (left) { vt[vc++] = p[3]; vt[vc++] = p[0]; vt[vc++] = p[4]; vt[vc++] = p[7]; vc -= 4; uv[vc++] = new Vector2(-side_z, 0); uv[vc++] = new Vector2(0, 0); uv[vc++] = new Vector2(0, side_y); uv[vc++] = new Vector2(-side_z, side_y); } if (top) { vt[vc++] = p[4]; vt[vc++] = p[5]; vt[vc++] = p[6]; vt[vc++] = p[7]; vc -= 4; uv[vc++] = new Vector2(0, side_y); uv[vc++] = new Vector2(side_x, side_y); uv[vc++] = new Vector2(side_x, side_y + side_z); uv[vc++] = new Vector2(0, side_y + side_z); } if (bottom) { vt[vc++] = p[3]; vt[vc++] = p[2]; vt[vc++] = p[1]; vt[vc++] = p[0]; vc -= 4; uv[vc++] = new Vector2(0, -side_z); uv[vc++] = new Vector2(side_x, -side_z); uv[vc++] = new Vector2(side_x, 0); uv[vc++] = new Vector2(0, 0); } for (int i = 0; i < uv.Length; i++) { uv[i] = new Vector2(uv[i].x / uScale + uShift, uv[i].y / vScale + vShift); } int[] t = new int[totalTriangCount * 3]; int tc = 0; for (int f = 0; f < faces; f++) { int b = f * 4; t[tc++] = b + 0; t[tc++] = b + 2; t[tc++] = b + 1; t[tc++] = b + 0; t[tc++] = b + 3; t[tc++] = b + 2; } mesh.vertices = vt; mesh.triangles = t; mesh.uv = uv; mesh.RecalculateNormals(); }
public Mesh generate(Spline planSpline, AXTexCoords tex, LineType lineType) { int planCount = (planSpline.isClosed ? planSpline.controlVertices.Count : planSpline.controlVertices.Count - 1); int planlen = planSpline.derivedVertices.Count; //Debug.Log ("planlen="+planlen); //Debug.Log ("plan.isClosed="+planSpline.isClosed); List <Vector3> vertices = new List <Vector3>(); List <Vector2> uv = new List <Vector2>(); List <int> triangles = new List <int>(); List <Vector3> quadNormals = new List <Vector3>(); List <Vector3> quadTangentsU = new List <Vector3>(); List <Vector3> quadTangentsV = new List <Vector3>(); //int prev_i; int next_i; float len; float u = tex.shift.x / tex.scale.x; float v1 = tex.shift.y / tex.scale.y; float v2 = (tex.shift.y + height) / tex.scale.y; //bool isAcute; int LL = 0; int UL = 1; int LR = 2; int UR = 3; List <Vector2> verts = planSpline.controlVertices; int edgeVertCt = 0; for (int i = 0; i < planCount; i++) { // add quad //prev_i = (i == 0) ? (verts.Count-1) : i-1; next_i = (i == (verts.Count - 1)) ? 0 : i + 1; // THIS VERT (only if if (i == 0 || planSpline.isSharp(i)) { // LOWER vertices.Add(new Vector3(verts[i].x, 0, verts[i].y)); if (tex.rotateSidesTex) { uv.Add(new Vector2(v1, u)); } else { uv.Add(new Vector2(u, v1)); } // upper vertices.Add(new Vector3(verts[i].x, getHeight(verts[i].x, verts[i].y), verts[i].y)); if (tex.rotateSidesTex) { uv.Add(new Vector2(v2, u)); } else { uv.Add(new Vector2(u, v2)); } //uv.Add(new Vector2(u, v2)); if (i > 0) { LL += 2; UL += 2; LR += 2; UR += 2; } edgeVertCt++; } // NEXT VERT len = Vector3.Distance(verts[i], verts[next_i]); u += len / tex.scale.x; vertices.Add(new Vector3(verts[next_i].x, 0, verts[next_i].y)); if (tex.rotateSidesTex) { uv.Add(new Vector2(v1, u)); } else { uv.Add(new Vector2(u, v1)); } vertices.Add(new Vector3(verts[next_i].x, getHeight(verts[next_i].x, verts[next_i].y), verts[next_i].y)); if (tex.rotateSidesTex) { uv.Add(new Vector2(v2, u)); } else { uv.Add(new Vector2(u, v2)); } if (i > 0) { LL += 2; UL += 2; LR += 2; UR += 2; } edgeVertCt++; triangles.Add(LL); triangles.Add(UL); triangles.Add(LR); triangles.Add(LR); triangles.Add(UL); triangles.Add(UR); // QUAD NORMAL: use quad to calculate its normal (lefthand rule in unity) Vector3 Tv = vertices[UL] - vertices[LL]; Vector3 Tu = vertices[LR] - vertices[LL]; quadNormals.Add(Vector3.Cross(Tv, Tu).normalized); quadTangentsV.Add(Tv); quadTangentsU.Add(Tu); } Mesh mesh = new Mesh(); mesh.vertices = vertices.ToArray(); mesh.uv = uv.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); // NORMALS Vector3[] normals = new Vector3[mesh.vertices.Length]; //mesh.normals; // PLAN int p_cur = 0; for (int i = 0; i < planSpline.controlVertices.Count; i++) { int left_i = (i + planSpline.controlVertices.Count - 1) % (planSpline.controlVertices.Count); int right_i = i; //Debug.Log(left_i + " ["+i+"] p_cur="+p_cur); Vector3 normalLeft = Vector2.zero; Vector3 normalRight = Vector2.zero; Vector3 normalN = Vector2.zero; if (i > 0 || planSpline.isClosed) { normalLeft = quadNormals[left_i]; } if (i < planCount - 1 || planSpline.isClosed) { normalRight = quadNormals[right_i]; } if ((i > 0 && i < planCount - 1) || planSpline.isClosed) { normalN = (normalLeft + normalRight).normalized; } // VERTEX ADDRESSES (if not geom sharp, the left addresses will not be used...) int thisRight = p_cur * 2; int thisRightU = thisRight + 1; int thisLeft = (i == 0) ? (planlen * 2 - 2) : thisRight - 2; int thisLeftU = thisLeft + 1; //Debug.Log ("["+i+"] isSharp="+ planSpline.isSharp(i)+" ... p_cur="+p_cur+ "::=> " + thisLeft + ", " + thisLeftU + " <> " + thisRight + ", " + thisRightU); // ASSIGN NORMALS if (i < planCount) { if (!planSpline.isBlend(i) || (i == 0 && !planSpline.isClosed)) { normals[thisRight] = normalRight; normals[thisRightU] = normalRight; } else { normals[thisRight] = normalN; normals[thisRightU] = normalN; } } else if (planSpline.isClosed) { normals[thisRight] = normalRight; normals[thisRightU] = normalRight; } if (i > 0) { if (!planSpline.isBlend(i) || (i == (planSpline.controlVertices.Count - 1) && !planSpline.isClosed)) { normals[thisLeft] = normalLeft; normals[thisLeftU] = normalLeft; } else { normals[thisLeft] = normalN; normals[thisLeftU] = normalN; } } else if (planSpline.isClosed) { normals[thisLeft] = normalN; normals[thisLeftU] = normalN; } p_cur++; next_i = (i < planSpline.controlVertices.Count - 1) ? i + 1 : 0; //Debug.Log("tris "+i+ ": "+ planSpline.isSharp(i)); if (planSpline.isSharp(next_i)) { p_cur++; } } mesh.normals = normals; return(mesh); }
/* * public void setBase(Vector3 a, Vector3 b, Vector3 c) * { * useBase = true; * _base = new Plane(a, b, c); * } * public void setBase(Plane p) * { * useElev = true; * _base = p; * } */ public Mesh generate(Spline planSpline, float hgt, AXTexCoords tex, LineType lineType) { height = hgt; return(generate(planSpline, tex, lineType)); }
// GENERATE public void generate(ref Mesh mesh, AXTexCoords tex) { if (tex == null) { return; } // Combine the plan and sections to make the fabric // float uShift = tex.shift.x; // float vShift = tex.shift.y; // float uScale = tex.scale.x; // float vScale = tex.scale.y; int secVertCount = (bevel > 0) ? 4 : 2; Vector3[] secVerts = new Vector3[secVertCount]; if (bevel <= 0) { secVerts[0] = new Vector3(R, 0, 0); secVerts[1] = new Vector3(r, 0, 0); } else { float tanb = h / (R - r); float a = (bevel * tanb) / (1 + tanb); float c = bevel - a; Debug.Log(R + ", " + bevel + " :: " + (R - bevel)); Debug.Log("tanb=" + tanb + ", a=" + a + ", c=" + c); secVerts[0] = new Vector3((R - bevel), 0, 0); secVerts[1] = new Vector3((R - c), a, 0); secVerts[2] = new Vector3((r + c), (h - a), 0); secVerts[3] = new Vector3((r - bevel), h, 0); } //bool smooth = (breakAngle > 90) ? true : false; float angle = 360.0f / segs; // Make Mesh int vertCount = secVerts.Length * 2 * segs; Vector3[] vertices = new Vector3[vertCount]; Vector2[] uvs = new Vector2[vertCount]; int faceCount = (secVerts.Length - 1) * segs; int[] triangles = new int[6 * faceCount]; Matrix4x4 localM = Matrix4x4.identity; // CREATE VERTICES for (int seg = 0; seg < segs; seg++) { Quaternion rot = Quaternion.Euler(0, angle * seg, 0); localM = Matrix4x4.TRS(Vector3.zero, rot, Vector3.one); for (int j = 0; j < secVerts.Length; j++) { vertices[(j + seg * j)] = localM.MultiplyPoint3x4(secVerts[j]); } } int tri = 0; // CREATE TRIANGLES for (int seg = 0; seg < segs - 1; seg++) { for (int j = 0; j < secVerts.Length - 1; j++) { vertices[(j + seg * j)] = localM.MultiplyPoint3x4(secVerts[j]); triangles[tri++] = (j + seg * j); triangles[tri++] = (j + (seg + 1) * j); triangles[tri++] = ((j + 1) + (seg + 1) * j); triangles[tri++] = (j + seg * j); triangles[tri++] = ((j + 1) + (seg + 1) * j); triangles[tri++] = ((j + 1) + (seg + 1) * j); } } mesh.vertices = vertices; mesh.uv = uvs; mesh.triangles = triangles; // int faces = (front?1:0) + (back?1:0) + (left?1:0) + (right?1:0) + (top?1:0) + (bottom?1:0); // int totalVertCount = faces * 4; // int totalTriangCount = faces * 2; // // Vector3[] p = new Vector3[8]; // // p[0] = new Vector3(-sx, 0, -sz); // p[1] = new Vector3( sx, 0, -sz); // p[2] = new Vector3( sx, 0, sz); // p[3] = new Vector3(-sx, 0, sz); // // p[4] = new Vector3(-sx, sy, -sz); // p[5] = new Vector3( sx, sy, -sz); // p[6] = new Vector3( sx, sy, sz); // p[7] = new Vector3(-sx, sy, sz); // // // // // Y-AXIS JITTER // /* // if (false) // { // for (int i=4; i<8; i++) // p[i].y *= Mathf.PerlinNoise(p[i].x+100, p[i].z+100); // } // */ // // // // Vector3[] vt = new Vector3[totalVertCount]; // Vector2[] uv = new Vector2[totalVertCount]; // // // int vc = 0; // // if (front) // { // vt[vc++] = p[0]; // vt[vc++] = p[1]; // vt[vc++] = p[5]; // vt[vc++] = p[4]; // // vc -= 4; // uv[vc++] = new Vector2( 0, 0); // uv[vc++] = new Vector2(side_x, 0); // uv[vc++] = new Vector2(side_x, side_y); // uv[vc++] = new Vector2( 0, side_y); // // // } // if (right) // { // vt[vc++] = p[1]; // vt[vc++] = p[2]; // vt[vc++] = p[6]; // vt[vc++] = p[5]; // // vc -= 4; // uv[vc++] = new Vector2(side_x, 0); // uv[vc++] = new Vector2(side_x+side_z, 0); // uv[vc++] = new Vector2(side_x+side_z, side_y); // uv[vc++] = new Vector2( side_x, side_y); // } // if (back) // { // vt[vc++] = p[2]; // vt[vc++] = p[3]; // vt[vc++] = p[7]; // vt[vc++] = p[6]; // vc -= 4; // uv[vc++] = new Vector2(side_x+side_z, 0); // uv[vc++] = new Vector2(side_x*2+side_z, 0); // uv[vc++] = new Vector2(side_x*2+side_z, side_y); // uv[vc++] = new Vector2(side_x+side_z, side_y); // } // if (left) // { // vt[vc++] = p[3]; // vt[vc++] = p[0]; // vt[vc++] = p[4]; // vt[vc++] = p[7]; // vc -= 4; // uv[vc++] = new Vector2(-side_z, 0); // uv[vc++] = new Vector2( 0, 0); // uv[vc++] = new Vector2( 0, side_y); // uv[vc++] = new Vector2(-side_z, side_y); // } // if (top) // { // vt[vc++] = p[4]; // vt[vc++] = p[5]; // vt[vc++] = p[6]; // vt[vc++] = p[7]; // vc -= 4; // uv[vc++] = new Vector2( 0, side_y); // uv[vc++] = new Vector2( side_x, side_y); // uv[vc++] = new Vector2( side_x, side_y+side_z); // uv[vc++] = new Vector2( 0, side_y+side_z); // } // if (bottom) // { // vt[vc++] = p[3]; // vt[vc++] = p[2]; // vt[vc++] = p[1]; // vt[vc++] = p[0]; // vc -= 4; // uv[vc++] = new Vector2( 0, -side_z); // uv[vc++] = new Vector2( side_x, -side_z); // uv[vc++] = new Vector2( side_x, 0); // uv[vc++] = new Vector2( 0, 0); // } // // for (int i=0; i<uv.Length; i++) // uv[i] = new Vector2(uv[i].x/uScale+uShift, uv[i].y/vScale+vShift); // // int[] t = new int[totalTriangCount*3]; // // int tc = 0; // // for (int f=0; f<faces; f++) // { // int b = f*4; // t[tc++] = b+0; // t[tc++] = b+2; // t[tc++] = b+1; // // t[tc++] = b+0; // t[tc++] = b+3; // t[tc++] = b+2; // } // // // // mesh.vertices = vt; // mesh.triangles = t; // mesh.uv = uv; // mesh.RecalculateNormals(); // // }