/// <summary> /// Create the mesh /// </summary> /// <param name="a_vertices"></param> /// <param name="a_shapeToExtrude"></param> /// <returns></returns> private void CreateTackMesh(ProTwoDShape a_twoDShape) { //loop though all the vertices for (int i = 0; i < proMesh.Vertices.Count; i++) { //this is to check if we are on the last vertex of the twoDShape //e.x ((1 + 1) / 2) % 1 = 1 //we are on the end of the twoDShape //we can not add trianles //so continue float value = ((i + 1) / (float)a_twoDShape.Vertices.Count) % 1f; if (i != 0 && value == 0) { continue; } //Make tri proMesh.Triangles.Add(i); proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count); proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1); proMesh.Triangles.Add(i); proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1); proMesh.Triangles.Add(i + 1); } }
/// <summary> /// Create all the vertices for the mesh /// </summary> private void CreateTrackVertices() { ProTwoDShape pTwoDShape = CreateTwoDShape(MeshToExtrude); //Create an array of OrientedPoint OrientedPoint[] oPoints = new OrientedPoint[_spline.SmoothNumPoints]; //Assign each oPoint for (int i = 0; i < oPoints.Length; i++) { //Get the point before current point Vector3 lastPoint = _spline.AllSmoothPoints[((i - 1) + oPoints.Length) % oPoints.Length]; //Get current point Vector3 currentPoint = _spline.AllSmoothPoints[i]; //Get the next point Vector3 nextPoint = _spline.AllSmoothPoints[((i + 1) + oPoints.Length) % oPoints.Length]; //Get the direction from currentPoint to lastPoint Vector3 lc = currentPoint - lastPoint; //Get the direction from nextPoint to currentPoint Vector3 cn = nextPoint - currentPoint; //Avgrage the start and end points for each curve //Set the points direction. This direction is the forward vector Vector3 dir = (lc + cn) * 0.5f; dir.Normalize(); //Get the right Vector dir = Vector3.Cross(dir, Vector3.up).normalized; //new the oPoint oPoints[i] = new OrientedPoint(_spline.AllSmoothPoints[i], Quaternion.LookRotation(dir, Vector3.up)); } //Generate all the center points on the mesh //This will also set the forward rotation //and UV for each point for (int i = 0; i < oPoints.Length; i++) { for (int j = 0; j < pTwoDShape.Vertices.Count; j++) { //get the forward vector Vector3 fwd = oPoints[i].Rotation * Vector3.forward; //get the position Vector3 pos = oPoints[i].Position + (pTwoDShape.Vertices[j].x * fwd); pos.y = oPoints[i].Position.y + pTwoDShape.Vertices[j].y; //add the new vertex to the proMesh.Vertices list proMesh.Vertices.Add(pos); //Setup the uv coords for this vertex float x = (float)j / (pTwoDShape.Vertices.Count - 1); float y = (float)i / oPoints.Length; Vector2 uv = new Vector2(x, y); proMesh.Uvs.Add(uv); } } }
public void CreateTrack() { if (path.NumPoints > 0) { proMesh = new ProMesh(); ProTwoDShape pTwoDShape = CreateTwoDShape(MeshToExtrude); CreateTrackVertices(); CreateTackMesh(pTwoDShape); CreateCurbVertices(); } else { Debug.Log("SPLICE CREATOR: There is no spline. Make sure there is a Voronoi diagram gnerated. Then press the" + " 'Generate Spline'"); } }
/// <summary> /// Create all the vertices for the curbs around the track /// </summary> private void CreateCurbVertices() { ProTwoDShape curbMesh = CreateTwoDShape(CurbMesh); float center = curbMesh.Center; for (int i = 0; i < curbMesh.Vertices.Count; i++) { Vector2 v = curbMesh.Vertices[i]; v *= 100; curbMesh.Vertices[i] = v; } curbMesh.ShapeWidth *= 100; //Store all the curb meshes made List <CombineInstance> allCurbMeshes = new List <CombineInstance>(); if (true) { //Go though all the vertices in the track mesh if (true) { int i = 0; //Store all the vertices for the current curb List <Vector3> curbVertices = new List <Vector3>(); //Store all the uvs for the current curb List <Vector2> curbUvs = new List <Vector2>(); //Store all the triangle for the current curb List <int> curbTriangles = new List <int>(); //Get the number of segmnets each spline curve it broken //up into int segStart = proMesh.Vertices.Count; //if we are at the start of a curve if (i % segStart == 0) { //Get the distance for the left side of the spline float splineLeft = (proMesh.Vertices[i] - proMesh.Vertices[Helper.LoopIndex(i, segStart - 2, proMesh.Vertices.Count)]).magnitude; //Get the distance for the right side of the spline float splineRight = (proMesh.Vertices[Helper.ALoopIndex(i, proMesh.Vertices.Count)] - proMesh.Vertices[Helper.LoopIndex(i, segStart - 1, proMesh.Vertices.Count)]).magnitude; //check which side of the track mesh is smaller //this is the side which will have the curb made for if (true) { curbMesh.Vertices.Reverse(); //Setup the vertices for (int j = 0; j < segStart; j += 2) { for (int k = 0; k < curbMesh.Vertices.Count; k++) { Vector3 cV; Vector3 cVT; Vector3 dir; if (j == 0 || j == segStart - 2) { cV = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)]; cVT = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)]; } else { cV = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)]; cVT = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)]; } dir = cV - cVT; //ROTATE VERTICES //Set the new vertex position Vector3 pos; if (curbMesh.Vertices[k].x < 0) { pos = cVT + (curbMesh.Vertices[k].x * dir.normalized); } else { pos = cV + (curbMesh.Vertices[k].x * dir.normalized); } if (onPlanXZ) { pos.y = 0 + curbMesh.Vertices[k].y; } else { pos.y += curbMesh.Vertices[k].y; } //add curb to vertex list curbVertices.Add(pos); //Set the new vertex uv float x = (float)j / (curbMesh.Vertices.Count - 1); float y = (float)i / 4 + 1; Vector2 uv = new Vector2(x, y); curbUvs.Add(uv); } } //for (int j = segStart - 2; j < segStart; j += 2) //{ // for (int k = 0; k < curbMesh.Vertices.Count; k++) // { // //ROTATE VERTICES // Vector3 cV = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)]; // Vector3 cVT = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)]; // Vector3 dir = cV - // cVT; // //Set the new vertex position // Vector3 pos; // if (curbMesh.Vertices[k].x < 0) // pos = cVT + (curbMesh.Vertices[k].x * dir.normalized); // else // pos = cV + (curbMesh.Vertices[k].x * dir.normalized); // pos.y = 0 + curbMesh.Vertices[k].y; // //add curb to vertex list // curbVertices.Add(pos); // //Set the new vertex uv // float x = (float)j / (curbMesh.Vertices.Count - 1); // float y = (float)i / 4 + 1; // Vector2 uv = new Vector2(x, y); // curbUvs.Add(uv); // } //} //Setup the triangles for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count); j++) { float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f; if (value != 0) { curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j + 1); } } curbMesh.Vertices.Reverse(); } CombineInstance ci = new CombineInstance(); Mesh m = new Mesh(); m.vertices = curbVertices.ToArray(); m.uv = curbUvs.ToArray(); m.triangles = curbTriangles.ToArray(); ci.mesh = m; ci.transform = transform.localToWorldMatrix; allCurbMeshes.Add(ci); } } } curbsMesh = new Mesh(); //Combine all curb meshs in to one curbsMesh.CombineMeshes(allCurbMeshes.ToArray()); //Clean up all the meshes by destroying them for (int i = 0; i < allCurbMeshes.Count; i++) { allCurbMeshes[i].mesh.Clear(); } //then create a new GameObject add a mesh filter and mesh renderer to it if (!curb) { curb = new GameObject("Curbs"); } if (!curb.GetComponent <MeshFilter>()) { curb.AddComponent <MeshFilter>(); } if (!curb.GetComponent <MeshRenderer>()) { curb.AddComponent <MeshRenderer>(); } curbsMesh.RecalculateNormals(); //set the mesh filter and mesh renderer curb.GetComponent <MeshFilter>().sharedMesh = curbsMesh; curb.GetComponent <MeshRenderer>().sharedMaterial = CurbMaterial; }
/// <summary> /// Create all the vertices for the curbs around the track /// </summary> private void CreateCurbVertices() { ProTwoDShape curbMesh = CreateTwoDShape(CurbMesh); for (int i = 0; i < curbMesh.Vertices.Count; i++) { Vector2 v = curbMesh.Vertices[i]; v *= 100; curbMesh.Vertices[i] = v; } curbMesh.ShapeWidth *= 100; //Store all the curb meshes made List <CombineInstance> allCurbMeshes = new List <CombineInstance>(); if (Spline.SplineCurveType == CurveType.Bezier) { //Go though all the vertices in the track mesh for (int i = 0; i < proMesh.Vertices.Count; i++) { //Store all the vertices for the current curb List <Vector3> curbVertices = new List <Vector3>(); //Store all the uvs for the current curb List <Vector2> curbUvs = new List <Vector2>(); //Store all the triangle for the current curb List <int> curbTriangles = new List <int>(); //Get the number of segmnets each spline curve it broken //up into int segStart = ((Spline.SmoothSplineResoultion + 1) * 2); //if we are at the start of a curve if (i % segStart == 0) { //Get the distance for the left side of the spline float splineLeft = (proMesh.Vertices[i] - proMesh.Vertices[Helper.LoopIndex(i, segStart - 2, proMesh.Vertices.Count)]).magnitude; //Get the distance for the right side of the spline float splineRight = (proMesh.Vertices[Helper.ALoopIndex(i, proMesh.Vertices.Count)] - proMesh.Vertices[Helper.LoopIndex(i, segStart - 1, proMesh.Vertices.Count)]).magnitude; //check which side of the track mesh is smaller //this is the side which will have the curb made for if (splineLeft < splineRight) { curbMesh.Vertices.Reverse(); //Setup the vertices for (int j = 0; j < segStart; j += 2) { for (int k = 0; k < curbMesh.Vertices.Count; k++) { //ROTATE VERTICES Vector3 cV = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)]; Vector3 cVT = proMesh.Vertices[Helper.LoopIndex(i, j + 1, proMesh.Vertices.Count)]; Vector3 dir = cV - cVT; //Set the new vertex position Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized); pos += (curbMesh.ShapeWidth) * dir.normalized; //if we are on the first or last row of vertices for this curb //clamp the y value to 0 if (j == 0 || j == (segStart - 2)) { pos.y = 0; } else { pos.y = 0 + curbMesh.Vertices[k].y; } //add curb to vertex list curbVertices.Add(pos); //Set the new vertex uv float x = (float)j / (curbMesh.Vertices.Count - 1); float y = (float)i / Spline.SmoothSplineResoultion + 1; Vector2 uv = new Vector2(x, y); curbUvs.Add(uv); } } //Setup the triangles for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count); j++) { float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f; if (value != 0) { curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j + 1); } } curbMesh.Vertices.Reverse(); } else if (splineLeft > splineRight) { for (int j = 1; j < segStart; j += 2) { for (int k = 0; k < curbMesh.Vertices.Count; k++) { //ROTATE VERTICES Vector3 cV = proMesh.Vertices[Helper.LoopIndex(i, j, proMesh.Vertices.Count)]; Vector3 cVT = proMesh.Vertices[Helper.LoopIndex(i, j - 1, proMesh.Vertices.Count)]; Vector3 dir = cV - cVT; Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized); pos += (curbMesh.ShapeWidth) * dir.normalized; //if we are on the first or last row of vertices for this curb //clamp the y value to 0 if (j == 1 || j == (segStart - 1)) { pos.y = 0; } else { pos.y = 0 + curbMesh.Vertices[k].y; } //add curb inner vertex first //curbVertices.Add(cV + (dir.normalized * 2)); //curbVertices.Add(cV); curbVertices.Add(pos); float x = (float)j / (curbMesh.Vertices.Count - 1); float y = (float)i / segStart; Vector2 uv = new Vector2(x, y); curbUvs.Add(uv); } } //Setup the triangles for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count + 2); j++) { float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f; if (value != 0) { curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j + 1); } } } CombineInstance ci = new CombineInstance(); Mesh m = new Mesh(); m.vertices = curbVertices.ToArray(); m.uv = curbUvs.ToArray(); m.triangles = curbTriangles.ToArray(); ci.mesh = m; ci.transform = transform.localToWorldMatrix; allCurbMeshes.Add(ci); } } } else if (Spline.SplineCurveType == CurveType.CatmullRom) { //create the curbs from the control points. This assumes that the sharepest //part of the curve is the control point //Go though all the vertices in the track mesh for (int i = 0; i < proMesh.Vertices.Count; i++) { //Store all the vertices for the current curb List <Vector3> curbVertices = new List <Vector3>(); //Store all the uvs for the current curb List <Vector2> curbUvs = new List <Vector2>(); //Store all the triangle for the current curb List <int> curbTriangles = new List <int>(); //Get the number of segmnets each spline curve it broken //up into int segStart = ((Spline.SmoothSplineResoultion + 1) * 2); if (i % segStart == 0) { //Get the overall offset value form the control point //this is the number of vertices from the control point int offset = (segStart * 2) / 8; //Get the start and end vertex point for the left side of the mesh int leftStartIndex = Helper.LoopIndex(i, -(offset + 2), proMesh.Vertices.Count); int leftEndIndex = Helper.LoopIndex(i, (offset), proMesh.Vertices.Count); //Get the distance for the left side of the spline float splineLeft = (proMesh.Vertices[leftStartIndex] - proMesh.Vertices[leftEndIndex]).magnitude; //Get the start and end vertex point for the right side of the mesh int rightStartIndex = Helper.LoopIndex(i, -(offset + 1), proMesh.Vertices.Count); int rightEndIndex = Helper.LoopIndex(i, (offset + 1), proMesh.Vertices.Count); //Get the distance for the right side of the spline float splineRight = (proMesh.Vertices[rightStartIndex] - proMesh.Vertices[rightEndIndex]).magnitude; //check which side of the track mesh is smaller //this is the side which will have the curb made for if (splineLeft < splineRight) { int cIndex = leftStartIndex; curbMesh.Vertices.Reverse(); //create mesh for (int j = 0; j < (offset * 2 + 1); j += 2) { cIndex = Helper.LoopIndex(leftStartIndex, j, proMesh.Vertices.Count); for (int k = 0; k < curbMesh.Vertices.Count; k++) { //ROTATE VERTICES Vector3 cV = proMesh.Vertices[cIndex]; Vector3 cVT = proMesh.Vertices[Helper.ALoopIndex(cIndex, proMesh.Vertices.Count)]; Vector3 dir = cV - cVT; //Set the new vertex position Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized); pos += (curbMesh.ShapeWidth) * dir.normalized; //if we are on the first or last row of vertices for this curb //clamp the y value to 0 if (j == 0 || j == (offset * 2 + 1) - 1) { pos.y = 0; } else { pos.y = 0 + curbMesh.Vertices[k].y; } //add curb to vertex list curbVertices.Add(pos); //Set the new vertex uv float x = (float)j / (curbMesh.Vertices.Count - 1); float y = (float)i / Spline.SmoothSplineResoultion + 1; Vector2 uv = new Vector2(x, y); curbUvs.Add(uv); } } //Setup the triangles for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count + 1); j++) { float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f; if (value != 0) { curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j + 1); } } curbMesh.Vertices.Reverse(); //Add new mesh to the combine instance list CombineInstance ci = new CombineInstance(); Mesh m = new Mesh(); m.vertices = curbVertices.ToArray(); m.uv = curbUvs.ToArray(); m.triangles = curbTriangles.ToArray(); ci.mesh = m; ci.transform = transform.localToWorldMatrix; allCurbMeshes.Add(ci); } else { int cIndex = rightStartIndex; //create mesh for (int j = 0; j < (offset * 2 + 1); j += 2) { cIndex = Helper.LoopIndex(rightStartIndex, j, proMesh.Vertices.Count); for (int k = 0; k < curbMesh.Vertices.Count; k++) { Vector3 cV = proMesh.Vertices[cIndex]; Vector3 cVT = proMesh.Vertices[Helper.SLoopIndex(cIndex, proMesh.Vertices.Count)]; Vector3 dir = cV - cVT; //Set the new vertex position Vector3 pos = cV + (curbMesh.Vertices[k].x * dir.normalized); pos += (curbMesh.ShapeWidth) * dir.normalized; //if we are on the first or last row of vertices for this curb //clamp the y value to 0 if (j == 0 || j == (offset * 2 + 1) - 1) { pos.y = 0; } else { pos.y = 0 + curbMesh.Vertices[k].y; } //add curb to vertex list curbVertices.Add(pos); //Set the new vertex uv float x = (float)j / (curbMesh.Vertices.Count - 1); float y = (float)i / Spline.SmoothSplineResoultion + 1; Vector2 uv = new Vector2(x, y); curbUvs.Add(uv); } } //Setup the triangles for (int j = 0; j < curbVertices.Count - (curbMesh.Vertices.Count + 1); j++) { float value = (j + 1) / (float)curbMesh.Vertices.Count % 1f; if (value != 0) { curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j); curbTriangles.Add(j + curbMesh.Vertices.Count + 1); curbTriangles.Add(j + 1); } } //Add new mesh to the combine instance list CombineInstance ci = new CombineInstance(); Mesh m = new Mesh(); m.vertices = curbVertices.ToArray(); m.uv = curbUvs.ToArray(); m.triangles = curbTriangles.ToArray(); ci.mesh = m; ci.transform = transform.localToWorldMatrix; allCurbMeshes.Add(ci); } } } } curbsMesh = new Mesh(); //Combine all curb meshs in to one curbsMesh.CombineMeshes(allCurbMeshes.ToArray()); //Clean up all the meshes by destroying them for (int i = 0; i < allCurbMeshes.Count; i++) { allCurbMeshes[i].mesh.Clear(); } }
/// <summary> /// Create the mesh /// </summary> /// <param name="a_vertices"></param> /// <param name="a_shapeToExtrude"></param> /// <returns></returns> private Mesh CreateTackMesh(ProTwoDShape a_twoDShape) { //loop though all the vertices for (int i = 0; i < proMesh.Vertices.Count; i++) { //this is to check if we are on the last vertex of the twoDShape //e.x ((1 + 1) / 2) % 1 = 1 //we are on the end of the twoDShape //we can not add trianles //so continue float value = ((i + 1) / (float)a_twoDShape.Vertices.Count) % 1f; if (i != 0 && value == 0) { continue; } //Make tri proMesh.Triangles.Add(i); proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count); proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1); proMesh.Triangles.Add(i); proMesh.Triangles.Add(i + a_twoDShape.Vertices.Count + 1); proMesh.Triangles.Add(i + 1); } //create new lists for vertices, triangles and uvs List <Vector3> meshVer = new List <Vector3>(); List <int> meshTri = new List <int>(); List <Vector2> meshUV = new List <Vector2>(); //store the current vertex/triangle count int currentVertexCount = 0; int currentTriangleCount = 0; for (int i = 0; i < (proMesh.Vertices.Count / a_twoDShape.Vertices.Count) + 1; i++) { //if the currentVertexCount is greater than proMesh.Vertices.Count //then break if (currentVertexCount > proMesh.Vertices.Count - 1) { break; } //Add vertex line for (int j = 0; j < a_twoDShape.Vertices.Count; j++) { meshVer.Add(proMesh.Vertices[j + currentVertexCount]); meshUV.Add(proMesh.Uvs[j + currentVertexCount]); } //incerment currentVertexCount currentVertexCount += a_twoDShape.Vertices.Count; //add triangle line if (currentVertexCount >= a_twoDShape.Vertices.Count * 2) { for (int j = 0; j < ((a_twoDShape.Vertices.Count * 2) - 2) * 3; j++) { meshTri.Add(proMesh.Triangles[j + currentTriangleCount]); } //incerment currentTriangleCount currentTriangleCount += ((a_twoDShape.Vertices.Count * 2) - 2) * 3; } } //Check if the spline has been closed. If it is //then do nothing. Otherwise close it if (_spline.SmoothSplineClosed) { int lastIndex = proMesh.Vertices.Count - 1; meshTri.Add(lastIndex - 1); meshTri.Add(0); meshTri.Add(1); meshTri.Add(lastIndex - 1); meshTri.Add(1); meshTri.Add(lastIndex); } //create a new mesh and assign the vertices, triangles and uvs Mesh mesh = new Mesh(); mesh.vertices = meshVer.ToArray(); mesh.triangles = meshTri.ToArray(); mesh.uv = meshUV.ToArray(); mesh.RecalculateNormals(); //return mesh return(mesh); }