public void UpdateMesh(BezierPath bPath) { if (mesh == null) { AssignMeshComponents(); } Initalize(bPath); int vertIndex = 0; int triIndex = 0; // Vertices for the top of the road are layed out: // 0 1 // 2 3 // and so on... So the triangle map 0,8,1 for example, defines a triangle from top left to bottom left to bottom right. for (int i = 0; i < vPath.NumPoints; i++) { Vector3 localUp = vPath.up; Vector3 localRight = Vector3.Cross(localUp, vPath.GetTangent(i)); // Find position to left and right of current path vertex Vector3 vertSideA = vPath.GetPoint(i) - localRight * Mathf.Abs(pathWidth); Vector3 vertSideB = vPath.GetPoint(i) + localRight * Mathf.Abs(pathWidth); // Add top of road vertices verts[vertIndex + 0] = vertSideA; verts[vertIndex + 1] = vertSideB; // Set uv on y axis to path time (0 at start of path, up to 1 at end of path) uvs[vertIndex + 0] = new Vector2(0, vPath.times[i]); uvs[vertIndex + 1] = new Vector2(1, vPath.times[i]); // Top of road normals normals[vertIndex + 0] = localUp; normals[vertIndex + 1] = localUp; // Set triangle indices if (i < vPath.NumPoints - 1 || vPath.isClosedLoop) { for (int j = 0; j < triangleMap.Length; j++) { roadTriangles[triIndex + j] = (vertIndex + triangleMap[j]) % verts.Length; } } vertIndex += 2; triIndex += 6; } mesh.Clear(); mesh.vertices = verts; mesh.uv = uvs; mesh.normals = normals; mesh.SetTriangles(roadTriangles, 0); mesh.RecalculateBounds(); meshFilter.sharedMesh = mesh; UpdateMaterials(); }
public string GenerateCompleteStatus() { /* This funciton creates the general status of the map all the players need * and sends it to them * * Mapstatus should contain the following: * * 1) The Bezier definition of the track * 2) The Vertext definition of the walls of the track * 3) Placement of all the checkpoints * */ MapStatus mapStatus = new MapStatus(); TrackController tc = GameObject.FindObjectOfType <TrackController>(); RoadMeshCreator pst = GameObject.FindObjectOfType <RoadMeshCreator>(); List <Vector3Json> bezierPoints = new List <Vector3Json>(); foreach (Vector3 point in pst.pathCreator.bezierPath.points) { bezierPoints.Add(point); } mapStatus.bezierPoints = bezierPoints; mapStatus.roadWidth = pst.roadWidth; GameObject checkpointHolder = tc.checkpointHolder; List <Vector3Json> checkPointPos = new List <Vector3Json>(); List <Vector3Json> checkPointRot = new List <Vector3Json>(); Bounds checkPointBound = checkpointHolder.transform.GetChild(0).GetComponent <BoxCollider>().bounds; for (int i = 0; i < checkpointHolder.transform.childCount; i++) { Transform t = checkpointHolder.transform.GetChild(i); checkPointPos.Add(t.position); checkPointRot.Add(t.rotation.eulerAngles); } mapStatus.checkPointPos = checkPointPos; mapStatus.checkPointRot = checkPointRot; mapStatus.checkpointSize = checkPointBound.size; mapStatus.midpoint = new List <Vector3Json>(); mapStatus.wallLeft = new List <Vector3Json>(); mapStatus.wallRight = new List <Vector3Json>(); mapStatus.roadDirection = new List <Vector3Json>(); VertexPath vertexPath = pst.pathCreator.path; Vector3[] pathPoints = vertexPath.localPoints; for (int i = 0; i < vertexPath.localPoints.Length; i++) { Vector3 midPoint = pathPoints[i]; Vector3 localRight = Vector3.Cross(Vector3.up, vertexPath.GetTangent(i)); Vector3 vertSideA = vertexPath.GetPoint(i) - localRight * Mathf.Abs(pst.roadWidth); Vector3 vertSideB = vertexPath.GetPoint(i) + localRight * Mathf.Abs(pst.roadWidth); mapStatus.midpoint.Add(midPoint); mapStatus.wallLeft.Add(vertSideA); mapStatus.wallRight.Add(vertSideB); mapStatus.roadDirection.Add(vertexPath.GetTangent(i)); } string mapStatusJson = JsonConvert.SerializeObject(mapStatus); //Debug.Log(mapStatusJson); if (debug) { for (int i = 1; i < mapStatus.wallLeft.Count; i++) { // Left Vector3 point_l1 = mapStatus.wallRight[i - 1]; Vector3 point_l2 = mapStatus.wallRight[i]; Debug.DrawLine(point_l1, point_l2, Color.red); // Right Vector3 point_r1 = mapStatus.wallLeft[i - 1]; Vector3 point_r2 = mapStatus.wallLeft[i]; Debug.DrawLine(point_r1, point_r2, Color.blue); } } return(mapStatusJson); }
//Creates a mesh around the Bezier curve public static void CreateRoadMesh(VertexPath path, Mesh mesh, float roadWidth, float thickness, bool flattenSurface, bool useRotation) { Vector3[] verts = new Vector3[path.NumPoints * 8]; Vector2[] uvs = new Vector2[verts.Length]; Vector3[] normals = new Vector3[verts.Length]; int numTris = 2 * (path.NumPoints - 1) + ((path.isClosedLoop) ? 2 : 0); int[] roadTriangles = new int[numTris * 3]; int[] underRoadTriangles = new int[numTris * 3]; int[] sideOfRoadTriangles = new int[numTris * 2 * 3]; int vertIndex = 0; int triIndex = 0; int[] triangleMap = { 0, 8, 1, 1, 8, 9 }; int[] sidesTriangleMap = { 4, 6, 14, 12, 4, 14, 5, 15, 7, 13, 15, 5 }; bool usePathNormals = !(path.space == PathSpace.xyz && flattenSurface); for (int i = 0; i < path.NumPoints; i++) { Vector3 localUp = (usePathNormals) ? Vector3.Cross(path.GetTangent(i), path.GetNormal(i)) : path.up; Vector3 localRight = (usePathNormals) ? path.GetNormal(i) : Vector3.Cross(localUp, path.GetTangent(i)); Vector3 side = useRotation ? Vector3.right : localRight; Vector3 vertSideA = path.GetPoint(i) - side * Mathf.Abs(roadWidth); Vector3 vertSideB = path.GetPoint(i) + side * Mathf.Abs(roadWidth); verts[vertIndex + 0] = vertSideA; verts[vertIndex + 1] = vertSideB; verts[vertIndex + 2] = vertSideA - localUp * thickness; verts[vertIndex + 3] = vertSideB - localUp * thickness; verts[vertIndex + 4] = verts[vertIndex + 0]; verts[vertIndex + 5] = verts[vertIndex + 1]; verts[vertIndex + 6] = verts[vertIndex + 2]; verts[vertIndex + 7] = verts[vertIndex + 3]; uvs[vertIndex + 0] = new Vector2(0, path.times[i]); uvs[vertIndex + 1] = new Vector2(1, path.times[i]); normals[vertIndex + 0] = localUp; normals[vertIndex + 1] = localUp; normals[vertIndex + 2] = -localUp; normals[vertIndex + 3] = -localUp; normals[vertIndex + 4] = -localRight; normals[vertIndex + 5] = localRight; normals[vertIndex + 6] = -localRight; normals[vertIndex + 7] = localRight; // Set triangle indices if (i < path.NumPoints - 1 || path.isClosedLoop) { for (int j = 0; j < triangleMap.Length; j++) { roadTriangles[triIndex + j] = (vertIndex + triangleMap[j]) % verts.Length; // reverse triangle map for under road so that triangles wind the other way and are visible from underneath underRoadTriangles[triIndex + j] = (vertIndex + triangleMap[triangleMap.Length - 1 - j] + 2) % verts.Length; } for (int j = 0; j < sidesTriangleMap.Length; j++) { sideOfRoadTriangles[triIndex * 2 + j] = (vertIndex + sidesTriangleMap[j]) % verts.Length; } } vertIndex += 8; triIndex += 6; } mesh.Clear(); mesh.vertices = verts; mesh.uv = uvs; mesh.normals = normals; mesh.subMeshCount = 3; mesh.SetTriangles(roadTriangles, 0); mesh.SetTriangles(underRoadTriangles, 1); mesh.SetTriangles(sideOfRoadTriangles, 2); mesh.RecalculateBounds(); }
void CreateRoadMesh() { Vector3[] verts = new Vector3[VertexPath.NumPoints * 8]; Vector2[] uvs = new Vector2[verts.Length]; Vector3[] normals = new Vector3[verts.Length]; int numTris = 2 * (VertexPath.NumPoints - 1) + ((VertexPath.isClosedLoop) ? 2 : 0); int[] roadTriangles = new int[numTris * 3]; int[] underRoadTriangles = new int[numTris * 3]; int[] sideOfRoadTriangles = new int[numTris * 2 * 3]; int vertIndex = 0; int triIndex = 0; // Vertices for the top of the road are layed out: // 0 1 // 8 9 // and so on... So the triangle map 0,8,1 for example, defines a triangle from top left to bottom left to bottom right. int[] triangleMap = { 0, 8, 1, 1, 8, 9 }; int[] sidesTriangleMap = { 4, 6, 14, 12, 4, 14, 5, 15, 7, 13, 15, 5 }; bool usePathNormals = !(VertexPath.space == PathSpace.xyz && flattenSurface); for (int i = 0; i < VertexPath.NumPoints; i++) { Vector3 localUp = (usePathNormals) ? Vector3.Cross(VertexPath.GetTangent(i), VertexPath.GetNormal(i)) : VertexPath.up; Vector3 localRight = (usePathNormals) ? VertexPath.GetNormal(i) : Vector3.Cross(localUp, VertexPath.GetTangent(i)); // Find position to left and right of current VertexPath vertex Vector3 vertSideA = VertexPath.GetPoint(i) - localRight * Mathf.Abs(roadWidth); Vector3 vertSideB = VertexPath.GetPoint(i) + localRight * Mathf.Abs(roadWidth); // Add top of road vertices verts[vertIndex + 0] = vertSideA; verts[vertIndex + 1] = vertSideB; // Add bottom of road vertices verts[vertIndex + 2] = vertSideA - localUp * thickness; verts[vertIndex + 3] = vertSideB - localUp * thickness; // Duplicate vertices to get flat shading for sides of road verts[vertIndex + 4] = verts[vertIndex + 0]; verts[vertIndex + 5] = verts[vertIndex + 1]; verts[vertIndex + 6] = verts[vertIndex + 2]; verts[vertIndex + 7] = verts[vertIndex + 3]; // Set uv on y axis to VertexPath time (0 at start of VertexPath, up to 1 at end of VertexPath) uvs[vertIndex + 0] = new Vector2(0, VertexPath.times[i]); uvs[vertIndex + 1] = new Vector2(1, VertexPath.times[i]); // Top of road normals normals[vertIndex + 0] = localUp; normals[vertIndex + 1] = localUp; // Bottom of road normals normals[vertIndex + 2] = -localUp; normals[vertIndex + 3] = -localUp; // Sides of road normals normals[vertIndex + 4] = -localRight; normals[vertIndex + 5] = localRight; normals[vertIndex + 6] = -localRight; normals[vertIndex + 7] = localRight; // Set triangle indices if (i < VertexPath.NumPoints - 1 || VertexPath.isClosedLoop) { for (int j = 0; j < triangleMap.Length; j++) { roadTriangles[triIndex + j] = (vertIndex + triangleMap[j]) % verts.Length; // reverse triangle map for under road so that triangles wind the other way and are visible from underneath underRoadTriangles[triIndex + j] = (vertIndex + triangleMap[triangleMap.Length - 1 - j] + 2) % verts.Length; } for (int j = 0; j < sidesTriangleMap.Length; j++) { sideOfRoadTriangles[triIndex * 2 + j] = (vertIndex + sidesTriangleMap[j]) % verts.Length; } } vertIndex += 8; triIndex += 6; } mesh.Clear(); mesh.vertices = verts; mesh.uv = uvs; mesh.normals = normals; mesh.subMeshCount = 3; mesh.SetTriangles(roadTriangles, 0); mesh.SetTriangles(underRoadTriangles, 1); mesh.SetTriangles(sideOfRoadTriangles, 2); mesh.RecalculateBounds(); }