/// <summary> /// Calculate the road's vertices and form triangles /// </summary> private void generateShape() { // 4 vertices for each point along the road - each forms a cross section vertices = new Vector3[roadLinePoints.Length * 4]; // 8 triangles for each set of 2 cross sections, plus 4 additional for the endpoints // Each triangle contains three points triangles = new int[((roadLinePoints.Length - 1) * 8 + 4) * 3]; // For each point on the line, generate a rectangle (cross section) // perpendicular to the line to the next point. for (int i = 0; i < roadLinePoints.Length; i++) { Vector3 a = roadLinePoints[i]; Vector3 fromPrevious = new Vector3(); Vector3 toNext = new Vector3(); if (i > 0) { fromPrevious = roadLinePoints[i] - roadLinePoints[i - 1]; } if (i < roadLinePoints.Length - 1) { toNext = roadLinePoints[i + 1] - roadLinePoints[i]; } Vector3 direction = ((fromPrevious.normalized + toNext.normalized) / 2).normalized; MeshRoadCrossSection crossSection = new MeshRoadCrossSection(a, direction, this); // Add vertices to set now vertices[i * 4] = crossSection.topLeft; vertices[i * 4 + 1] = crossSection.topRight; vertices[i * 4 + 2] = crossSection.bottomLeft; vertices[i * 4 + 3] = crossSection.bottomRight; } triangles = MeshRoadUtil.getStandardMeshTriangles(roadLinePoints.Length); }
/// <summary> /// Change the shape of a terrain to fit the bottom of this road. /// </summary> /// <param name="terrain">Terrain to be shaped.</param> private void fitTerrainToRoad(Terrain terrain) { TerrainData data = terrain.terrainData; int width = data.heightmapWidth; int height = data.heightmapHeight; // TODO: Optimize by not grabbing the entire heightmap, just what the road overlaps float[,] heightmap = data.GetHeights(0, 0, width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { Vector3 rayStart = MeshRoadUtil.terrainPointToWorld(new Vector3(x, y, 0), terrain); RaycastHit hit; if (GetComponent <MeshCollider>() .Raycast(new Ray(rayStart, terrain.transform.up), out hit, data.size.y)) { // Calculate where to set height heightmap[x, y] = MeshRoadUtil.terrainHeightFromWorld(hit.point.y, terrain); } } } data.SetHeights(0, 0, heightmap); }