public virtual MeshData getBeamMesh(Vector3 start, Vector3 end, float width, MeshData meshData) { Vector3[] points = new Vector3[3]; Vector2[] UVs = new Vector2[3]; Vector3 tip = end - start; float mag = tip.magnitude; Vector3 perp = new Vector3 (-tip.y, tip.x, tip.z) / mag; Vector3 base1 = (perp * width/4) + tip/mag; Vector3 base2 = (perp * -width/4) + tip/mag; //Vector3 base3 = Quaternion.Euler(300, 0, 0) * perp; UVs [2] = new Vector2 (0.0f, Math.Min (0.4f+width,1.0f)); UVs [1] = new Vector2 (0.0f, Math.Max (0.6f-width,0.0f)); UVs [0] = new Vector2 (0.1f, 0.5f); meshData.AddVertex(Vector3.zero); meshData.AddVertex(base1); meshData.AddVertex(base2); meshData.AddTriangle(); meshData.uv.AddRange(UVs); UVs [1] = new Vector2 (0.0f, Math.Min (0.4f+width,1.0f)); UVs [2] = new Vector2 (0.0f, Math.Max (0.6f-width,0.0f)); UVs [0] = new Vector2 (0.1f, 0.5f); meshData.AddVertex(tip); meshData.AddVertex(base2); meshData.AddVertex(base1); meshData.AddTriangle(); meshData.uv.AddRange(UVs); return meshData; }
public virtual MeshData AddQuadFlat( Vector3[] points, MeshData meshData) { //Takes 4 points, calculates two normals for two faces //Adds the points and triangles to the mesh Vector3 flatnorm1 = new Vector3(); flatnorm1 = Vector3.Cross (points [1] - points [0], points [3] - points [0]); Vector3 flatnorm2 = new Vector3(); flatnorm2 = Vector3.Cross (points [3] - points [2], points [1] - points [2]); //set the vertices meshData.AddVertex(points [0], flatnorm1); meshData.AddVertex(points [1], flatnorm1); meshData.AddVertex(points [3], flatnorm1); meshData.AddTriangle(); meshData.AddVertex(points [1], flatnorm2); meshData.AddVertex(points [2], flatnorm2); meshData.AddVertex(points [3], flatnorm2); meshData.AddTriangle(); Color32[] vcolors = new Color32[6]; vcolors [2] = Color.white; vcolors [4] = Color.white; vcolors [5] = Color.white; vcolors [0] = Color.white; vcolors [1] = Color.white; vcolors [3] = Color.white; meshData.colors.AddRange (vcolors); return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap) { int width = heightMap.GetLength (0); int height = heightMap.GetLength (1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; MeshData meshData = new MeshData (width, height); int vertexIndex = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { meshData.vertices [vertexIndex] = new Vector3 (topLeftX + x, heightMap [x, y], topLeftZ - y); meshData.uvs [vertexIndex] = new Vector2 (x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle (vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle (vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve (_heightCurve.keys); int meshSimplificationIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2; int borderedSize = heightMap.GetLength (0); int meshSize = borderedSize - 2*meshSimplificationIncrement; int meshSizeUnsimplified = borderedSize - 2; float topLeftX = (meshSizeUnsimplified - 1) / -2f; float topLeftZ = (meshSizeUnsimplified - 1) / 2f; int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData (verticesPerLine); int[,] vertexIndicesMap = new int[borderedSize,borderedSize]; int meshVertexIndex = 0; int borderVertexIndex = -1; for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { bool isBorderVertex = y == 0 || y == borderedSize - 1 || x == 0 || x == borderedSize - 1; if (isBorderVertex) { vertexIndicesMap [x, y] = borderVertexIndex; borderVertexIndex--; } else { vertexIndicesMap [x, y] = meshVertexIndex; meshVertexIndex++; } } } for (int y = 0; y < borderedSize; y += meshSimplificationIncrement) { for (int x = 0; x < borderedSize; x += meshSimplificationIncrement) { int vertexIndex = vertexIndicesMap [x, y]; Vector2 percent = new Vector2 ((x-meshSimplificationIncrement) / (float)meshSize, (y-meshSimplificationIncrement) / (float)meshSize); float height = heightCurve.Evaluate (heightMap [x, y]) * heightMultiplier; Vector3 vertexPosition = new Vector3 (topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified); meshData.AddVertex (vertexPosition, percent, vertexIndex); if (x < borderedSize - 1 && y < borderedSize - 1) { int a = vertexIndicesMap [x, y]; int b = vertexIndicesMap [x + meshSimplificationIncrement, y]; int c = vertexIndicesMap [x, y + meshSimplificationIncrement]; int d = vertexIndicesMap [x + meshSimplificationIncrement, y + meshSimplificationIncrement]; meshData.AddTriangle (a,d,c); meshData.AddTriangle (d,a,b); } vertexIndex++; } } return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve (_heightCurve.keys); int width = heightMap.GetLength (0); int height = heightMap.GetLength (1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0)?1:levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData (verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { meshData.vertices [vertexIndex] = new Vector3 (topLeftX + x, heightCurve.Evaluate (heightMap [x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs [vertexIndex] = new Vector2 (x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle (vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle (vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return meshData; }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int MeshSimplificationImplement = (levelOfDetail == 0)?1:levelOfDetail * 2; int VerticesPerLine = (width - 1) / MeshSimplificationImplement + 1; MeshData meshData = new MeshData(VerticesPerLine, VerticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += MeshSimplificationImplement) { for (int x = 0; x < width; x += MeshSimplificationImplement) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + VerticesPerLine + 1, vertexIndex + VerticesPerLine); meshData.AddTriangle(vertexIndex + VerticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap) { // Get the length of the first dimension array int width = heightMap.GetLength(0); // Get the length of the second dimension array int height = heightMap.GetLength(1); /* * x x x * -1 0 1 * * Left most point: x = (w - 1) / -2 = -1 * Top most point: z = (h - 1) / 2 = 1 * * z 1 * z 0 * z -1 */ float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; // Create a new meshData for the heightMap MeshData meshData = new MeshData(width, height); int vertexIndex = 0; // Iterate through each coordinate on the heightMap for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // Assign the height value to each vertex starting from the top left corner // topLeftX + x --> move rightward // topLeftZ - y --> move downward meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightMap[x, y], topLeftZ - y); // Let each vertex know where the uv is in relation to the rest of the map as a percentage meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); /* * i i + 1 ... * * i + w i + w + 1 ... * * Triangle 1: i, i + w + 1, i + w * Triangle 2: i + w + 1, i, i + 1 */ // Right and bottom edges of the map do not have triangles to set if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } // Return the meshData instead of mesh to allow implementation of threading so that the game doesn't freeze // when different chunks of the mesh are generated return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int meshSize = heightMap.GetLength(0) - 2 * meshSimplificationIncrement; int meshSizeUnsimplified = heightMap.GetLength(0) - 2; float topLeftX = (meshSizeUnsimplified - 1) / -2f; float topLeftZ = (meshSizeUnsimplified - 1) / 2f; int verticesPerLine = (meshSize - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, useFlatShading); int[,] vertexIndicesMap = new int[meshSize, meshSize]; int meshVertexIndex = 0; for (int y = 0; y < meshSize; y += meshSimplificationIncrement) { for (int x = 0; x < meshSize; x += meshSimplificationIncrement) { vertexIndicesMap[x, y] = meshVertexIndex; meshVertexIndex++; } } for (int y = 0; y < meshSize; y += meshSimplificationIncrement) { for (int x = 0; x < meshSize; x += meshSimplificationIncrement) { int vertexIndex = vertexIndicesMap[x, y]; float height = heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier; Vector2 percent = new Vector2((x - meshSimplificationIncrement) / (float)meshSize, (y - meshSimplificationIncrement) / (float)meshSize); Vector3 vertexPosition = new Vector3(topLeftX + percent.x * meshSizeUnsimplified, height, topLeftZ - percent.y * meshSizeUnsimplified); meshData.AddVertex(vertexPosition, percent, vertexIndex); if (x < meshSize - 1 && y < meshSize - 1) { int a = vertexIndicesMap[x, y]; int b = vertexIndicesMap[x + meshSimplificationIncrement, y]; int c = vertexIndicesMap[x, y + meshSimplificationIncrement]; int d = vertexIndicesMap[x + meshSimplificationIncrement, y + meshSimplificationIncrement]; meshData.AddTriangle(a, d, c); meshData.AddTriangle(d, a, b); } vertexIndex++; } } meshData.ProcessMesh(); return(meshData); }
private static MeshData GenerateTerrainMeshData(float[,] noiseMap, float heightMultiplier, AnimationCurve heightCurve, int LOD) { int width = noiseMap.GetLength(0); int height = noiseMap.GetLength(1); MeshData meshData = new MeshData(); int borderedVertIndex = -1; int meshVertIndex = 0; int[,] vertIndicesMap = new int[width, height]; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { bool isBorderedVertices = i == 0 || i == width - 1 || j == 0 || j == height - 1; if (isBorderedVertices) { vertIndicesMap[i, j] = borderedVertIndex; borderedVertIndex--; } else { vertIndicesMap[i, j] = meshVertIndex; meshVertIndex++; } } } for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { float x = i / (float)LOD; float z = j / (float)LOD; int vertIndex = vertIndicesMap[i, j]; float value = heightCurve.Evaluate(noiseMap[i, j]) * heightMultiplier; if (vertIndex < 0) { meshData.AddBorderedVertices(x, value, z); } else { meshData.AddVertices(x, value, z, width / LOD, height / LOD); } if (j < height - 1 && i < width - 1) { meshData.AddTriangle(vertIndicesMap[i, j], vertIndicesMap[i, j + 1], vertIndicesMap[i + 1, j + 1]); meshData.AddTriangle(vertIndicesMap[i + 1, j + 1], vertIndicesMap[i + 1, j], vertIndicesMap[i, j]); } } } return(meshData); }
public Task <MeshData> GenerateTerrainMeshNew(float[,] heightMap, int levelOfDetail) { int skipIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; var vertexIndicesMap = InitializeVertexIndicesMap(skipIncrement); var meshData = new MeshData(numVertsPerLine, skipIncrement, settings.useFlatShading); var meshVertexIndex = 0; var outOfMeshVertexIndex = -1; for (var y = 0; y < numVertsPerLine; ++y) { for (var x = 0; x < numVertsPerLine; ++x) { var v = new VertexInfo(x, y, skipIncrement, heightMap, vertexIndicesMap); if (v.isSkipped) { continue; } var vertexIndex = v.VertexIndex; var percent = new Vector2(x - 1, y - 1) / (numVertsPerLine - 3); var vertexPosition2D = settings.TopLeft + new Vector2(percent.x, -percent.y) * settings.meshWorldSize; if (v.isEdgeConnection) { var edgeConnectionVertexData = new EdgeConnectionVertexData(vertexIndex, v.VertexIndexCoordA, v.VertexIndexCoordB, v.dstPercentFromAToB); meshData.DeclareEdgeConnectionVertex(edgeConnectionVertexData); } try { meshData.AddVertex(new Vector3(vertexPosition2D.x, v.height, vertexPosition2D.y), percent, vertexIndex); } catch (IndexOutOfRangeException) { //Debug.Log(vertexIndex); } if (!v.shouldCreateTriangle) { continue; } int[] corners = v.Corners; meshData.AddTriangle(corners[0], corners[3], corners[2]); meshData.AddTriangle(corners[3], corners[0], corners[1]); } } meshData.ProcessMesh(); return(Task.FromResult(meshData)); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); int meshSimplificationIncrement = levelOfDetail.Equals(0)? 1: levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; //to keep track where we are in our 1D array Vertices //To center the vertices at the center float topLeftX = (width - 1) / -2f; //do not forget the -1 and the f for -2f to yield a float result float topLeftZ = (height - 1) / 2f; // positive 2f because the z goes up (-1 0 1 => x = (width - 1)/(-2)) float floatWidth = (float)width; float floatHeigth = (float)height; float vertexX = 0f; float vertexY = 0f; float vertexZ = 0f; AnimationCurve aHeightCurve = new AnimationCurve(heightCurve.keys); //a great improvisation over the generation for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { vertexX = x + topLeftX; vertexY = aHeightCurve.Evaluate(heightMap [x, y]) * heightMultiplier; vertexZ = topLeftZ - y; //we don't want to move down from topLeftZ, we move down the y value meshData.Vertices [vertexIndex] = new Vector3(vertexX, vertexY, vertexZ); // tell each vertex where it is in relation to the rest of the map as a percentage for both the x and the y axis //it is a percentage between 0 and 1 meshData.UVs[vertexIndex] = new Vector2(x / floatWidth, y / floatHeigth); if (x < width - 1 && y < height - 1) // we ignore the vertices at the most rigth and the most bottom { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); // first triangle (i, i+w+1, i+w) meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); // second triangle (i+w+1, i, i+1 } vertexIndex++; } } return(meshData); //useful to threading instead of returning the mesh, we return the meshData }
void CreateSquare(Vector3Int voxelCenter, MeshData meshData, Vector3Int normal) { Quaternion rotation = Quaternion.FromToRotation(new Vector3Int(0, 1, 0), normal); Vector3 a = rotation * new Vector3(0.5f, 0, 0.5f) + voxelCenter + (Vector3)normal * 0.5f; Vector3 b = rotation * new Vector3(0.5f, 0, -0.5f) + voxelCenter + (Vector3)normal * 0.5f; Vector3 c = rotation * new Vector3(-0.5f, 0, -0.5f) + voxelCenter + (Vector3)normal * 0.5f; Vector3 d = rotation * new Vector3(-0.5f, 0, 0.5f) + voxelCenter + (Vector3)normal * 0.5f; meshData.AddTriangle(a, b, c); meshData.AddTriangle(a, c, d); }
public static MeshData GenerateMesh(MapGraph mapGraph, int meshSize) { var meshData = new MeshData(); foreach (var node in mapGraph.nodesByCenterPosition.Values) { meshData.vertices.Add(node.centerPoint); var centerIndex = meshData.vertices.Count - 1; var edges = node.GetEdges().ToList(); int lastIndex = 0; int firstIndex = 0; for (var i = 0; i < edges.Count(); i++) { if (i == 0) { meshData.vertices.Add(edges[i].previous.destination.position); var j = meshData.vertices.Count - 1; meshData.vertices.Add(edges[i].destination.position); var k = meshData.vertices.Count - 1; meshData.AddTriangle(centerIndex, j, k); firstIndex = j; lastIndex = k; } else if (i < edges.Count() - 1) { meshData.vertices.Add(edges[i].destination.position); var currentIndex = meshData.vertices.Count - 1; meshData.AddTriangle(centerIndex, lastIndex, currentIndex); lastIndex = currentIndex; } else { meshData.AddTriangle(centerIndex, lastIndex, firstIndex); } } } meshData.uvs = new Vector2[meshData.vertices.Count]; for (int i = 0; i < meshData.uvs.Length; i++) { meshData.uvs[i] = new Vector2(meshData.vertices[i].x / meshSize, meshData.vertices[i].z / meshSize); } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; MeshData meshData = new MeshData(width, height); int vertexIndex = 0; //Rounds the height map values that are within the different ranges //This allows for a flatter terrain with step height levels to be generated for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (heightMap[x, y] < 0.23f) { heightMap[x, y] += 0.15f; } else if (heightMap[x, y] > 0.23f && heightMap[x, y] < 0.3f) { heightMap[x, y] = 0.4f; } else if (heightMap[x, y] > 0.3f && heightMap[x, y] < 0.6f) { heightMap[x, y] = 0.43f; } else if (heightMap[x, y] > 0.6f && heightMap[x, y] < 0.7f) { heightMap[x, y] = 0.47f; } else if (heightMap[x, y] > 0.7f) { heightMap[x, y] -= 0.1f; } meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } //GenerateObjects(heightCurve.Evaluate(heightMap[x,y]) * heightMultiplier, heightMap[x,y], width, height); vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool useFlatShading, bool buildingWall) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine, useFlatShading); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { if (buildingWall) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, topLeftZ - y, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier); } else { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); } meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { if (buildingWall) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine, vertexIndex + verticesPerLine + 1); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex + 1, vertexIndex); } else { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } } vertexIndex++; } } meshData.ProcessMesh(); return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, float borderSize, float borderMultiplier, AnimationCurve heightCurve, float waterHeight) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2.0f; float topLeftZ = (height - 1) / 2.0f; MeshData meshData = new MeshData(width, height); int vertexIndex = 0; float maxDistanceFromCenter = Vector2.Distance(new Vector2(width * 0.5f, height * 0.5f), Vector2.zero); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float distanceFromCenter = Vector2.Distance(new Vector2(x, y), new Vector2(width * 0.5f, height * 0.5f)); float distanceFromCenterPercent = distanceFromCenter / maxDistanceFromCenter; float valueFromCurve = heightCurve.Evaluate(heightMap[x, y]); float heightValue = valueFromCurve * heightMultiplier; // Ignore water etc. if (valueFromCurve >= waterHeight) { // Border if (x < borderSize || x > width - borderSize || y < borderSize || y > height - borderSize) { heightValue *= (distanceFromCenterPercent * borderMultiplier); } } meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightValue, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } ++vertexIndex; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve = null) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; MeshData meshData = new MeshData(width, height); int vertexIndex = 0; if (heightCurve == null) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, Mathf.Pow(heightMap[x, y], heightMultiplier), topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } } else { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, float uniformScale, int levelOfDetail) { int width = heightMap.GetLength(0); //dimensions of array int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; //we want central location of mesh to be 0,0 so calculating x coord of top left point float topLeftZ = (height - 1) / 2f; //similarly int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; //how much to increment by when iterating through points, so as to change detail //manually clamp to 1 int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); //data of current mesh int vertexIndex = 0; //index of current vertex for (int y = 0; y < height; y += meshSimplificationIncrement) //looping through vertices { for (int x = 0; x < width; x += meshSimplificationIncrement) { meshData.vertices[vertexIndex] = (new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMap[x, y] * heightMultiplier, topLeftZ - y) * uniformScale); //add vertex to list //topLeftX + x since we move towards positive from there. topLeftZ - y since we move down //.Evaluate returns y for inputted x value on curve meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); /* * Consider mesh with points marked as integers * 0 - 1 - 2 * | \ | \ | * 3 - 4 - 5 * | \ | \ | * 6 - 7 - 8 * at vertex 0 we set triangles of square 0,1,4,3, and so on. We do not need to do this for points on right and bottom edges * for some square * i - i+1 * | \ | * i+w - i+w+1 * our triangles are i, i+w+1, i+w and i+w+1, i, i+1 */ if (x < width - 1 && y < height - 1) //if we arent on right or bottom edge { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMeshColored(float[,] heightMap, float heightScale, AnimationCurve meshHeightCurve, TerrainType[] regions) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; MeshData meshData = new MeshData(width, height, true); int vertexCount = 0; for (int z = 0; z < height - 1; z++) { for (int x = 0; x < width - 1; x++) { // add 6 vertices and 2 triangles meshData.AddTriangle(vertexCount, vertexCount + 1, vertexCount + 2); float height1 = meshHeightCurve.Evaluate(heightMap[x, z]); float height2 = meshHeightCurve.Evaluate(heightMap[x + 1, z + 1]); float height3 = meshHeightCurve.Evaluate(heightMap[x, z + 1]); float averageHeight = (height1 + height2 + height3) / 3; Color32 regionColor = GetRegionColor(regions, averageHeight); meshData.color32s[vertexCount] = regionColor; meshData.vertices[vertexCount++] = new Vector3(topLeftX + x, height1 * heightScale, topLeftZ - z); meshData.color32s[vertexCount] = regionColor; meshData.vertices[vertexCount++] = new Vector3(topLeftX + x + 1, height2 * heightScale, topLeftZ - (z + 1)); meshData.color32s[vertexCount] = regionColor; meshData.vertices[vertexCount++] = new Vector3(topLeftX + x, height3 * heightScale, topLeftZ - (z + 1)); height1 = meshHeightCurve.Evaluate(heightMap[x + 1, z + 1]); height2 = meshHeightCurve.Evaluate(heightMap[x, z]); height3 = meshHeightCurve.Evaluate(heightMap[x + 1, z]); meshData.AddTriangle(vertexCount, vertexCount + 1, vertexCount + 2); averageHeight = (height1 + height2 + height3) / 3; regionColor = GetRegionColor(regions, averageHeight); meshData.color32s[vertexCount] = regionColor; meshData.vertices[vertexCount++] = new Vector3(topLeftX + x + 1, height1 * heightScale, topLeftZ - (z + 1)); meshData.color32s[vertexCount] = regionColor; meshData.vertices[vertexCount++] = new Vector3(topLeftX + x, height2 * heightScale, topLeftZ - z); meshData.color32s[vertexCount] = regionColor; meshData.vertices[vertexCount++] = new Vector3(topLeftX + x + 1, height3 * heightScale, topLeftZ - z); } } return(meshData); }
/// <summary> /// Generierung des Meshes auf Basis der übergebenen Werte /// </summary> /// <param name="heightMap">DIe in Noise entstandene HeightMap </param> /// <param name="heightMultiplier"> Skalierungswert der Höhe der Hügel </param> /// <param name="_heightCurve"> Lässt eine nicht-lineare Umsetzung der Höhenwerte zu </param> /// <param name="levelOfDetail"> Detailgrad des zu generierenden Meshes </param> /// <param name="flatShaded"> True, wenn die Landschaft per FlatShading erschaffen werden soll </param> /// <param name="yOffset"> Verschiebt die Map auf der Y-Achse </param> /// <param name="valleyWidth"> Breite des Tals für den Lauftrack </param> /// <param name="valleyheight"> Höhe des Tals für den Lauftrack </param> /// <param name="gradient"> Der Farbverlauf auf der Landschaft </param> public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail, bool flatShaded, float yOffset, float valleyWidth, float valleyHeight, Gradient gradient) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; // Das MeshSimplificationIncrement steuert den Detailgrad der Vertices im Mesh int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine, flatShaded); int vertexIndex = 0; for (int z = 0; z < height; z += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { float tmpYOffset = yOffset; if (x < (width / 2.0 + valleyWidth / 2.0) && x > (width / 2.0 - valleyWidth / 2.0)) { tmpYOffset += Mathf.Abs(x - width / 2) - valleyHeight; } meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, z]) * heightMultiplier + tmpYOffset, topLeftZ - z); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, z / (float)height); // Mit Evaluate wird eine verzerrbare Skalierung der HeightMap umgesetzt meshData.colors[vertexIndex] = gradient.Evaluate(meshData.vertices[vertexIndex].y); if (x < width - 1 && z < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } if (flatShaded) { meshData.FlatShading(); } return(meshData); }
//Need To generate HeightMap public static MeshData GenerataTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetial, bool isTerrain) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncriment = (levelOfDetial == 0)? 1 : levelOfDetial * 2; int verticesPerLine = (width - 1) / meshSimplificationIncriment + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncriment) { for (int x = 0; x < width; x += meshSimplificationIncriment) { //Make a note of this as its going to be needed for //Dynamically updating water heightMap float heightPoint = heightCurve.Evaluate(heightMap[x, y]) * (heightMultiplier); if (isTerrain) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightPoint, topLeftZ - y); } else { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, 1, topLeftZ - y); } meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, Gradient _colorGradient, int levelOfDetail, bool flatshading) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); Gradient colorGradient = new Gradient(); colorGradient.SetKeys(_colorGradient.colorKeys, _colorGradient.alphaKeys); int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; if (levelOfDetail == 5) { meshSimplificationIncrement = (levelOfDetail - 1) * 2; } int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, false); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, (heightCurve.Evaluate(heightMap[x, y]) * 2 - 1) * heightMultiplier, topLeftZ - y); meshData.colors[vertexIndex] = colorGradient.Evaluate(heightCurve.Evaluate(heightMap[x, y])); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } if (flatshading) { meshData.FlatShading(); } return(meshData); }
public void GenerateMesh() { Mesh mesh = MeshFilter.mesh; MeshData meshData = new MeshData(); meshData.AddTriangle(new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0)); meshData.AddTriangle(new Vector3(0, 0, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0)); // meshData.AddQuad(0, 2, 1, 1); // meshData.AddQuad(1, 2, 2, 2); // meshData.AddQuad(3, 2, 1, 3); meshData.SetMesh(MeshFilter.mesh, "newMesh"); }
public static MeshData GenerateWorldChunkMesh(WorldChunk chunk, WorldChunkSideBorders borders, WorldChunkSettings setting) { int size = setting.scaledSize; int meshSize = size + 1; // One line on top/left to create the triangles between chunks int borderedSize = meshSize + 2; // One line on every direction to calculate normals of triangle on the border of mesh float offset = (meshSize - 1) / -2f; MeshData meshData = new MeshData(meshSize); // To handle normals, the mesh have to generate vertices for 1line on each 8chunks bordered int[,] vertexIndicesMap = CreateVertexIndicesMap(borderedSize); for (int y = 0; y < borderedSize; y++) { for (int x = 0; x < borderedSize; x++) { Coord chunkCoord = new Coord(x - 1, y - 1, setting); // It's start with [-1;-1] int vertexIndex = vertexIndicesMap [x, y]; float height = chunk.GetHeightValue(chunkCoord, setting); Vector2 uv = new Vector2((x - 1) / (float)(borderedSize - 2), (y - 1) / (float)(borderedSize - 2)); Vector3 vertexPosition = new Vector3( offset + uv.x * meshSize, height, offset + uv.y * meshSize ); meshData.AddOrUpdateVertex(vertexPosition, uv, vertexIndex); if (x <= borderedSize - 2 && y <= borderedSize - 2) { int a = vertexIndicesMap[x, y]; int b = vertexIndicesMap[x + 1, y]; int c = vertexIndicesMap[x, y + 1]; int d = vertexIndicesMap[x + 1, y + 1]; // Clockwise // meshData.AddTriangle (a, d, c); // meshData.AddTriangle (d, a, b); // Counter Clockwise meshData.AddTriangle(c, d, a); meshData.AddTriangle(b, a, d); } } } return(meshData); }
public MeshData MarchCubes(int[,,] noiseGrid) { int gridX = noiseGrid.GetLength(0); int gridY = noiseGrid.GetLength(1); int gridZ = noiseGrid.GetLength(2); MeshData meshData = new MeshData(gridX, gridY, gridZ); for (int x = 0; x < gridX - 1; x++) { for (int y = 0; y < gridY - 1; y++) { for (int z = 0; z < gridZ - 1; z++) { int cubeIndex = 0; int[] vertValues = { noiseGrid[x, y, z], noiseGrid[x, y, z + 1], noiseGrid[x + 1, y, z + 1], noiseGrid[x + 1, y, z], noiseGrid[x, y + 1, z], noiseGrid[x, y + 1, z + 1], noiseGrid[x + 1, y + 1, z + 1], noiseGrid[x + 1, y + 1, z], }; for (int i = 0; i < 8; i++) { if (vertValues[i] == 1) { cubeIndex |= 1 << i; } } int[] triangulation = TriangleTable.triTable[cubeIndex]; //Debug.Log(string.Join(",", triangulation)); for (int i = 0; i < 12; i += 3) { if (triangulation[i] != -1) { Vector3 offset = new Vector3(x - gridX / 2, y - gridY / 2, z - gridZ / 2); Vector3 vertex1 = TriangleTable.midPointFromIndex(triangulation[i]); Vector3 vertex2 = TriangleTable.midPointFromIndex(triangulation[i + 1]); Vector3 vertex3 = TriangleTable.midPointFromIndex(triangulation[i + 2]); vertex1 += offset; vertex2 += offset; vertex3 += offset; meshData.AddVertices(vertex1, vertex2, vertex3); meshData.AddTriangle(); } } } } } return(meshData); }
// Use this for initialization void Start() { int tileSize = 16; MeshData meshData = new MeshData(); meshData.AddVertex(new Vector3(0, 0, 0.1f)); meshData.AddVertex(new Vector3(1, 2, 0.1f)); meshData.AddVertex(new Vector3(2, 0, 0.2f)); meshData.AddTriangle(); meshData.uv.Add(new Vector2(0, 0)); meshData.uv.Add(new Vector2(0, 1 * tileSize)); meshData.uv.Add(new Vector2(1 * tileSize, 1 * tileSize)); MeshFilter filter = gameObject.AddComponent <MeshFilter>(); filter.mesh.Clear(); filter.mesh.vertices = meshData.vertices.ToArray(); filter.mesh.triangles = meshData.triangles.ToArray(); filter.mesh.uv = meshData.uv.ToArray(); filter.mesh.RecalculateNormals(); for (int x = -20; x < 200; x++) { for (int y = -20; y < 200; y++) { CreateTri(x * triXSize / 2, y * triYSize); } } }
public static Mesh GenerateTerrainMesh(float[,] heightMap, MeshSettings meshSettings, int levelOfDetail) { var width = heightMap.GetLength(0); var height = heightMap.GetLength(1); var meshData = new MeshData(width); var topLeftX = (width - 1) / -2f; var topLeftZ = (height - 1) / 2f; var vertexIndex = 0; for (var x = 0; x < heightMap.GetLength(0); x++) { for (var y = 0; y < heightMap.GetLength(0); y++) { meshData.Vertices[vertexIndex] = new Vector3(topLeftX + x, heightMap[x,y], y - topLeftZ); meshData.Uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } //var flatShadedVertices = new Vector3[triangles.Count]; //var flatShadedUvs = new Vector2[triangles.Count]; //for (var i = 0; i < triangles.Count; i++) //{ // Debug.Log("Trying to access vertex: " + triangles[i]); // flatShadedVertices[i] = verticies[triangles[i]]; // flatShadedUvs[i] = uvs[triangles[i]]; // triangles[i] = i; //} var mesh = new Mesh(); var debug = meshData.Triangles.Any(c => c >= (72 * 72)); mesh.vertices = meshData.Vertices; mesh.uv = meshData.Uvs; mesh.triangles = meshData.Triangles; mesh.RecalculateNormals(); return mesh; }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); //offsets used to place in the center of the map float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 :levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { //offsets used to place in the center of the map meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); //no triangles to find on the right and bottom edges if (x < width - 1 && y < height - 1) { /* * yay ascii art! * i-------i+1 |\\ | | \\ | | \\ | | \\ | | \\ | | \\ | | \\| | i+w -----i+w+1 | */ meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); MeshData meshData = new MeshData(width, height); int vertexIndex = 0; //to keep track where we are in our 1D array Vertices //To center the vertices at the center float topLeftX = (width - 1) / -2f; //do not forget the -1 and the f for -2f to yield a float result float topLeftZ = (height - 1) / 2f; // positive 2f because the z is positive when we go up (-1 0 1 => x = (width - 1)/(-2)) float floatWidth = (float)width; float floatHeigth = (float)height; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { //Vertices meshData.Vertices [vertexIndex] = new Vector3(x + topLeftX, heightMap [x, y], topLeftZ - y); //we don't want to move down from topLeftZ, we move down the y value //Triangles if (x < width - 1 && y < height - 1) // we ignore the vertices at the most rigth and the most bottom { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); // first triangle (i, i+w+1, i+w) meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); // second triangle (i+w+1, i, i+1 } // tell each vertex where it is in relation to the rest of the map as a percentage for both the x and the y axis //it is a percentage between 0 and 1 meshData.UVs[vertexIndex] = new Vector2(x / floatWidth, y / floatHeigth); vertexIndex++; } } return(meshData); //useful to threading instead of returning the mesh, we return the meshData //threading: cannot create meshes inside a thread }
/// Generate a plane mesh of the size "size" public static MeshData GenPlaneMesh(Vector2 size) { MeshData meshData = new MeshData(1, (MeshFlags.Base | MeshFlags.UV)); meshData.vertices.Add(new Vector3(0, 0)); meshData.vertices.Add(new Vector3(0, size.y)); meshData.vertices.Add(new Vector3(size.x, size.y)); meshData.vertices.Add(new Vector3(size.x, 0)); meshData.UVs.Add(new Vector2(0f, 0f)); meshData.UVs.Add(new Vector2(0f, 1f)); meshData.UVs.Add(new Vector2(1f, 1f)); meshData.UVs.Add(new Vector2(1f, 0f)); meshData.AddTriangle(0, 0, 1, 2); meshData.AddTriangle(0, 0, 2, 3); meshData.Build(); return(meshData); }
public static MeshData GenerateTerrainMesh(float[] heightMap, int pixelSize, float realSize) { int width = pixelSize; int height = pixelSize; float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; float sizePerPixel = realSize / (pixelSize - 1); MeshData meshData = new MeshData(width, height); int vertexIndex = 0; // Debug.Log(string.Format("width = {0}, height = {1}", width, height)); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { float unitHeight = heightMap[y * pixelSize + x]; // meshData.vertices[vertexIndex] = new Vector3( // (topLeftX + x) * sizePerPixel, // unitHeight, // (topLeftZ - y) * sizePerPixel // ); meshData.vertices[vertexIndex] = new Vector3( (topLeftX + x) * sizePerPixel, unitHeight, (topLeftZ - y) * sizePerPixel ); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + 1, vertexIndex + width + 1); meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); } vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve height_Curve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve(height_Curve.keys); //Figure out the width and height of the map int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); //make the mesh data (x,y) perfectly in the middle //in order to create 2 new positions for x and y //with the use of the following formula //x=(w-1)/2 and the same for the z axis float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1: levelOfDetail * 2; int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; //figure out the number of vertices per line MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; //Loop through height map for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { //Create vertices meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); //create a persentage to see where the uvs are located //Setting triangles if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } //returning data instead of mesh itself because we are using threding so the environment //wont freeze up as the game loads more places. //This is becauuse unity sets as a limitation to pass the data of themesh in order to be //created instead of passing the mesh itself return(meshData); }
public static MeshData GenerateMeshData(float[,] heightMap, float gridLength, float meshHeightMultipler, AnimationCurve heightCurve, int levelOfDetail) { //LOD int meshSampleIncrement = levelOfDetail == 0 ? 1 : levelOfDetail * 2; int width = heightMap.GetLength(1); int height = heightMap.GetLength(0); float mapHalfWidth = (width - 1) * gridLength / 2f; float mapHalfHeight = (height - 1) * gridLength / 2f; int gridWidth = (width - 1) / meshSampleIncrement; int gridHeight = (height - 1) / meshSampleIncrement; MeshData meshData = new MeshData(gridWidth, gridHeight); for (int y = 0; y < height; y += meshSampleIncrement) { for (int x = 0; x < width; x += meshSampleIncrement) { //create vertices Vector3 vertice = new Vector3(x * gridLength - mapHalfWidth, heightCurve.Evaluate(heightMap[y, x]) * meshHeightMultipler, y * gridLength - mapHalfHeight); meshData.AddVertice(vertice); //create uvs Vector2 uv = new Vector2((float)x / width, (float)y / height); meshData.AddUV(uv); } } //create triangles for (int row = 0; row < gridHeight; row++) { for (int col = 0; col < gridWidth; col++) { int iVertLB = row * (gridWidth + 1) + col; int iVertRB = iVertLB + 1; int iVertLT = iVertLB + gridWidth + 1; int iVertRT = iVertLT + 1; meshData.AddTriangle(iVertLB, iVertLT, iVertRB); meshData.AddTriangle(iVertLT, iVertRT, iVertRB); } } return(meshData); }
/// Generate a plane with uv corresponding to the direction of the character. public static MeshData GenHumanMesh(Vector2 size, Direction direction) { float uy = 1f / 3f; MeshData meshData = new MeshData(1, (MeshFlags.Base | MeshFlags.UV)); meshData.vertices.Add(new Vector3(0, 0)); meshData.vertices.Add(new Vector3(0, size.y)); meshData.vertices.Add(new Vector3(size.x, size.y)); meshData.vertices.Add(new Vector3(size.x, 0)); if (direction == Direction.N) { meshData.UVs.Add(new Vector2(0f, uy)); meshData.UVs.Add(new Vector2(0f, uy * 2f)); meshData.UVs.Add(new Vector2(1f, uy * 2f)); meshData.UVs.Add(new Vector2(1f, uy)); } else if (direction == Direction.S) { meshData.UVs.Add(new Vector2(0f, uy * 2f)); meshData.UVs.Add(new Vector2(0f, 1f)); meshData.UVs.Add(new Vector2(1f, 1f)); meshData.UVs.Add(new Vector2(1f, uy * 2f)); } else if (direction == Direction.E) { meshData.UVs.Add(new Vector2(0f, 0f)); meshData.UVs.Add(new Vector2(0f, uy)); meshData.UVs.Add(new Vector2(1f, uy)); meshData.UVs.Add(new Vector2(1f, 0f)); } else if (direction == Direction.W) { meshData.UVs.Add(new Vector2(1f, 0f)); meshData.UVs.Add(new Vector2(1f, uy)); meshData.UVs.Add(new Vector2(0f, uy)); meshData.UVs.Add(new Vector2(0f, 0f)); } meshData.AddTriangle(0, 0, 1, 2); meshData.AddTriangle(0, 0, 2, 3); meshData.Build(); return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve, int levelOfDetail) { int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = (levelOfDetail == 0) ? 1 : levelOfDetail * 2; Debug.Log("msi = " + meshSimplificationIncrement); int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; Debug.Log("vpl = " + verticesPerLine); MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for (int y = 0; y < height; y += meshSimplificationIncrement) { for (int x = 0; x < width; x += meshSimplificationIncrement) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height); /* * Turning grid of vertices into triangles - only looking at each row of vertices, but not the right hand or bottom row as we're dealing with sets of four in a square * ie: * 1 2 = i i+1 * 3 4 i+width i+width+1 (i+width gives us the vertex below i as this is a 1D array) * * This is why we don't want right most or bottom most vertices, as it will try to generate triangles going off the grid * * Then we generate two triangles from each square - using example above, we have 1, 4, 3 and 4, 1, 2 */ if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return(meshData); }
public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve _heightCurve, int levelOfDetail) { AnimationCurve heightCurve = new AnimationCurve(_heightCurve.keys); int width = heightMap.GetLength(0); int height = heightMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; int meshSimplificationIncrement = levelOfDetail==0 ? 1 : levelOfDetail * 2; //Pour n'afficher qu'un certain nombre de vertices int verticesPerLine = (width - 1) / meshSimplificationIncrement + 1; MeshData meshData = new MeshData(verticesPerLine, verticesPerLine); int vertexIndex = 0; for(int y=0;y<height;y+= meshSimplificationIncrement) { for(int x=0;x<width;x+= meshSimplificationIncrement) { meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x, y]) * heightMultiplier - heightMultiplier*0.01f, topLeftZ - y); meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y/(float)height); if(x<width-1 && y < height-1) { //On ajoute 2 triangles de façon a créer une face carrée // /!\ Sens Indirect meshData.AddTriangle(vertexIndex, vertexIndex + verticesPerLine + 1, vertexIndex + verticesPerLine); meshData.AddTriangle(vertexIndex + verticesPerLine + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } return meshData; }
public override void AddBlockData(Chunk chunk, BlockPos pos, MeshData meshData, Block block) { int initialVertCount = meshData.vertices.Count; foreach (var vert in verts) { meshData.AddVertex(vert + (Vector3)pos); if (uvs.Length == 0) meshData.uv.Add(new Vector2(0, 0)); float lighting; if (Config.Toggle.BlockLighting) { lighting = block.data1 / 255f; } else { lighting = 1; } meshData.colors.Add(new Color(lighting, lighting, lighting, 1)); } if (uvs.Length != 0) { Rect texture; if (collection != null) texture = collection.GetTexture(chunk, pos, Direction.down); else texture = new Rect(); foreach (var uv in uvs) { meshData.uv.Add(new Vector2((uv.x * texture.width) + texture.x, (uv.y * texture.height) + texture.y)); } } foreach (var tri in tris) { meshData.AddTriangle(tri + initialVertCount); } }
public override void AddBlockData(Chunk chunk, BlockPos pos, MeshData meshData, Block block) { int initialVertCount = meshData.vertices.Count; foreach (var vert in verts) { meshData.AddVertex(vert + (Vector3)pos); if (uvs.Length == 0) meshData.uv.Add(new Vector2(0, 0)); float lighting; if (Config.Toggle.BlockLighting) { lighting = block.data1 / 255f; } else { lighting = 1; } meshData.colors.Add(new Color(lighting, lighting, lighting, 1)); } if (uvs.Length != 0) { foreach (var uv in uvs) { meshData.uv.Add(uv); } } foreach (var tri in tris) { meshData.AddTriangle(tri + initialVertCount); } }
public override void AddBlockData(Chunk chunk, BlockPos pos, MeshData meshData, Block block) { int initialVertCount = meshData.vertices.Count; int colInitialVertCount = meshData.colVertices.Count; foreach (var vert in verts) { meshData.AddVertex(vert + (Vector3)pos); meshData.colVertices.Add(vert + (Vector3)pos); if (uvs.Length == 0) meshData.uv.Add(new Vector2(0, 0)); float lighting; if (Config.Toggle.BlockLighting) { lighting = block.data1 / 255f; } else { lighting = 1; } meshData.colors.Add(new Color(lighting, lighting, lighting, 1)); } if (uvs.Length != 0) { Rect texture; if (collection != null) texture = collection.GetTexture(chunk, pos, Direction.down); else texture = new Rect(); foreach (var uv in uvs) { meshData.uv.Add(new Vector2((uv.x * texture.width) + texture.x, (uv.y * texture.height) + texture.y)); } } if (!chunk.GetBlock(pos.Add(Direction.up)).controller.IsSolid(Direction.down)) { foreach (var tri in trisUp) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } } if (!chunk.GetBlock(pos.Add(Direction.down)).controller.IsSolid(Direction.up)) { foreach (var tri in trisDown) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } } if (!chunk.GetBlock(pos.Add(Direction.north)).controller.IsSolid(Direction.south)) { foreach (var tri in trisNorth) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } } if (!chunk.GetBlock(pos.Add(Direction.south)).controller.IsSolid(Direction.north)) { foreach (var tri in trisSouth) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } } if (!chunk.GetBlock(pos.Add(Direction.west)).controller.IsSolid(Direction.east)) { foreach (var tri in trisWest) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } } if (!chunk.GetBlock(pos.Add(Direction.east)).controller.IsSolid(Direction.west)) { foreach (var tri in trisEast) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } } foreach (var tri in trisOther) { meshData.AddTriangle(tri + initialVertCount); meshData.colTriangles.Add(tri + colInitialVertCount); } }
public void Generate(TerrainConfig config) { config.MapHeight += 1; config.MapWidth += 1; Config = config; float[,] noiseMap = Noise.GenerateNoiseMap( config.MapWidth, config.MapHeight, config.Seed, config.NoiseScale, config.Octaves, config.Persistance, config.Lacunarity, config.Offset ); Color[] colorMap = new Color[config.MapWidth * config.MapHeight]; for (int y = 0; y < config.MapHeight; y++) { for (int x = 0; x < config.MapWidth; x++) { float currentHeight = noiseMap[x, y]; for (int i = 0; i < TerrainTypes.Length; i++) { if (currentHeight <= TerrainTypes[i].Height) { colorMap[y * config.MapWidth + x] = TerrainTypes[i].Color; //print (y * config.MapWidth + x); break; } } } } int width = noiseMap.GetLength(0); int height = noiseMap.GetLength(1); float topLeftX = (width - 1) / -2f; float topLeftZ = (height - 1) / 2f; MeshData meshData = new MeshData(width, height); int vertexIndex = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { meshData.Vertices[vertexIndex] = new Vector3((topLeftX + x) / 4, 0, (topLeftZ - y) / 4); meshData.Uvs[vertexIndex] = new Vector2((x / (float) width), (y / (float) height)); if (x < width - 1 && y < height - 1) { meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width); meshData.AddTriangle(vertexIndex + width + 1, vertexIndex, vertexIndex + 1); } vertexIndex++; } } Texture = new Texture2D(width, height); Texture.filterMode = FilterMode.Point; Texture.wrapMode = TextureWrapMode.Clamp; Texture.SetPixels(colorMap); Texture.Apply(); Mesh finalMesh = meshData.CreateMesh(); GetComponent<MeshFilter>().sharedMesh = finalMesh; GetComponent<MeshRenderer>().material.mainTexture = Texture; GetComponent<MeshCollider>().sharedMesh = finalMesh; }
public void Draw(MeshData meshData, Vector3 cubeOrigin, int[] solution, bool reverseNormal) { var edges = new List<int>(); foreach (TriangleDescriptor tri in _trianglesDescriptors) { int e0 = FilterBasedLookAtTable.Edges[solution[tri.P0A], solution[tri.P0B]]; int e1 = FilterBasedLookAtTable.Edges[solution[tri.P1A], solution[tri.P1B]]; int e2 = FilterBasedLookAtTable.Edges[solution[tri.P2A], solution[tri.P2B]]; if (!edges.Contains(e0)) edges.Add(e0); if (!edges.Contains(e1)) edges.Add(e1); if (!edges.Contains(e2)) edges.Add(e2); if (e0 == -1 || e1 == -1 || e2 == -1) throw new IndexOutOfRangeException(); if (reverseNormal) meshData.AddTriangle(edges.IndexOf(e0), edges.IndexOf(e2), edges.IndexOf(e1)); else meshData.AddTriangle(edges.IndexOf(e0), edges.IndexOf(e1), edges.IndexOf(e2)); } foreach (int edge in edges) meshData.Vertices.Add(cubeOrigin + FilterBasedLookAtTable.EdgeCenters[edge]); }