public void fill3DLeafMesh(TerrainOutputMesh terrainOutputMesh, int leafCount, int leafSize, int maxCenterOffset) { int currentVertexAndFaceIdx = 1; List <Branch> terminalBranches = new List <Branch>(branchesWithoutSuccessor); for (int i = 0; i < leafCount; i++) { System.Console.WriteLine("Leaf A"); Branch branch = terminalBranches[SpaceColonization.random.Next(terminalBranches.Count)]; addLeaf(branch.Pos, leafSize, maxCenterOffset, terrainOutputMesh, currentVertexAndFaceIdx); if (terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count > 4000) { terrainOutputMesh.VertexData.Add(new List <float[]>()); terrainOutputMesh.FacesData.Add(new List <int[]>()); terrainOutputMesh.TexureCoordData.Add(new List <float[]>()); terrainOutputMesh.FacesTextureCoordData.Add(new List <int[]>()); terrainOutputMesh.MaterialName.Add("Leaves"); terrainOutputMesh.MaterialColor.Add("#ffffffff"); terrainOutputMesh.MaterialMode.Add(TerrainOutputMesh.RenderingMode.transparent); terrainOutputMesh.MaterialTexture.Add("VegetationMaterials" + System.IO.Path.DirectorySeparatorChar + "leafTexture.png"); currentVertexAndFaceIdx++; } } }
public void addLeaf(Vector position, float size, float maxCenterOffset, TerrainOutputMesh terrainOutputMesh, int currentVertexAndFaceIdx) { Vector center = new Vector( (float)(position.Vx - (maxCenterOffset / 2.0f) + maxCenterOffset * SpaceColonization.random.NextDouble()), (float)(position.Vy - (maxCenterOffset / 2.0f) + maxCenterOffset * SpaceColonization.random.NextDouble()), (float)(position.Vz - (maxCenterOffset / 2.0f) + maxCenterOffset * SpaceColonization.random.NextDouble())); Vector direction = new Vector( center.Vx + (1.0f / 2.0f - (float)SpaceColonization.random.NextDouble()), center.Vy + (1.0f / 2.0f - (float)SpaceColonization.random.NextDouble()), center.Vz + (1.0f / 2.0f - (float)SpaceColonization.random.NextDouble()) ); Vector center2 = new Vector( (float)(position.Vx - (maxCenterOffset / 2.0f) + maxCenterOffset * SpaceColonization.random.NextDouble()) + 0.0001f, (float)(position.Vy - (maxCenterOffset / 2.0f) + maxCenterOffset * SpaceColonization.random.NextDouble()), (float)(position.Vz - (maxCenterOffset / 2.0f) + maxCenterOffset * SpaceColonization.random.NextDouble())); fillCircle(center, direction, 4, size, terrainOutputMesh.VertexData[currentVertexAndFaceIdx], terrainOutputMesh.FacesData[currentVertexAndFaceIdx], 0, false); terrainOutputMesh.FacesData[currentVertexAndFaceIdx].Add(new int[] { terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 3, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 2, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count }); terrainOutputMesh.FacesData[currentVertexAndFaceIdx].Add(new int[] { terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 2, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 1, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count }); fillCircle(center2, direction, 4, size, terrainOutputMesh.VertexData[currentVertexAndFaceIdx], terrainOutputMesh.FacesData[currentVertexAndFaceIdx], 0, false); terrainOutputMesh.FacesData[currentVertexAndFaceIdx].Add(new int[] { terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 2, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 3, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count }); terrainOutputMesh.FacesData[currentVertexAndFaceIdx].Add(new int[] { terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 1, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count - 2, terrainOutputMesh.VertexData[currentVertexAndFaceIdx].Count }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 0.0f, 0.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 1.0f, 0.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 1.0f, 1.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 0.0f, 1.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 0.0f, 0.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 1.0f, 0.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 1.0f, 1.0f }); terrainOutputMesh.TexureCoordData[currentVertexAndFaceIdx].Add(new float[] { 0.0f, 1.0f }); }
private static void exportHeightMap(float?[][] heightMap, TerrainOutputMesh terrainOutputMesh, float heightFactor) { int chunk = 65; int xStart = 0; int xEnd = chunk; System.Console.WriteLine("xEnd: " + xEnd + " " + heightMap.Length); int currentChunk = 0; while (xEnd <= heightMap.Length) { int yStart = 0; int yEnd = chunk; System.Console.WriteLine("yEnd: " + yEnd + " " + heightMap.Length); while (yEnd <= heightMap.Length) { terrainOutputMesh.VertexData.Add(new List <float[]>()); terrainOutputMesh.FacesData.Add(new List <int[]>()); for (int x = xStart; x < xEnd; x++) { for (int y = yStart; y < yEnd; y++) { terrainOutputMesh.VertexData[currentChunk].Add(new float[] { x, (float)(heightMap[x][y] * heightFactor), y }); } } for (int x = 0; x < xEnd - xStart - 1; x++) { for (int y = 1; y < yEnd - yStart; y++) { terrainOutputMesh.FacesData[currentChunk].Add(new int[] { y + x * (yEnd - yStart) + 1, y + (x + 1) * (yEnd - yStart), y + x * (yEnd - yStart) }); terrainOutputMesh.FacesData[currentChunk].Add(new int[] { y + x * (yEnd - yStart) + 1, y + (x + 1) * (yEnd - yStart) + 1, y + (x + 1) * (yEnd - yStart) }); } } yStart = yEnd - 1; yEnd = yStart + chunk; currentChunk++; System.Console.WriteLine("yEnd: " + yEnd + " " + heightMap.Length); } xStart = xEnd - 1; xEnd = xStart + chunk; System.Console.WriteLine("xEnd: " + xEnd + " " + heightMap.Length); } }
public static void FillHeightMapMesh(TerrainOutputMesh splittedMesh, GeoPoint[][] heightMapGeoPoints, float cellSize, float minHeight, float maxHeight, List <float[]> grassLand) { float maxHeightValue = 0; for (int x = 0; x < heightMapGeoPoints.Length; x++) { for (int y = 0; y < heightMapGeoPoints[x].Length; y++) { if (maxHeightValue < heightMapGeoPoints[x][y].Height) { maxHeightValue = heightMapGeoPoints[x][y].Height; } } } int chunk = 0; float heightFactor = (maxHeight / maxHeightValue) / cellSize; TerrainOutput terrainOutputSplitted = splitTerrainSegments(heightMapGeoPoints); for (int x = 0; x < heightMapGeoPoints.Length; x++) { for (int y = 0; y < heightMapGeoPoints[x].Length; y++) { if (heightMapGeoPoints[x][y].Type.Equals(CellType.Grass)) { grassLand.Add(new float[] { heightMapGeoPoints[x][y].X, heightMapGeoPoints[x][y].Y, heightMapGeoPoints[x][y].Height * heightFactor }); } } } splittedMesh.CameraPosition = new float[] { 0, heightMapGeoPoints.Length / 4, 0 }; splittedMesh.CameraRotation = new float[] { 22.5f, 45, 0 }; foreach (CellType type in Enum.GetValues(typeof(CellType))) { splittedMesh.VertexData.Add(new List <float[]>()); splittedMesh.FacesData.Add(new List <int[]>()); splittedMesh.MaterialColor.Add(""); splittedMesh.MaterialTexture.Add(""); splittedMesh.TexureCoordData.Add(new List <float[]>()); exportSplittedHeightMap(heightMapGeoPoints, splittedMesh, chunk, heightFactor, type); chunk++; } exportTransitionHeightMap_(heightMapGeoPoints, splittedMesh, heightFactor); }
public static void FillHeightMapMesh(TerrainOutputMesh splittedMesh, float[][] heightMap, float cellSize, float minHeight, float maxHeight, List <float[]> grassLand) { GeoPoint[][] heightMapGeoPoints = new GeoPoint[heightMap.Length][]; for (int x = 0; x < heightMap.Length; x++) { heightMapGeoPoints[x] = new GeoPoint[heightMap[x].Length]; for (int y = 0; y < heightMap[x].Length; y++) { GeoPoint geoPoint = new GeoPoint(); geoPoint.Height = (float)heightMap[x][y]; geoPoint.X = x; geoPoint.Y = y; heightMapGeoPoints[x][y] = geoPoint; } } FillHeightMapMesh(splittedMesh, heightMapGeoPoints, cellSize, minHeight, maxHeight, grassLand); }
internal void Init(TerrainOutput terrainOutput_) { terrainOutput = (TerrainOutputMesh)terrainOutput_; meshes = new List <Mesh>(); materials = new List <Material>(); subMeshes = new List <List <Mesh> >(); subMaterials = new List <List <Material> >(); processMesh(terrainOutput, meshes, materials); /*foreach (string meshPath in terrainOutput.MeshPath) * { * Mesh mesh = new Mesh(); * ObjImporter newMesh = new ObjImporter(); * mesh = newMesh.ImportFile(meshPath); * meshes.Add(mesh); * //mesh.RecalculateNormals(); * }*/ }
private static void exportSplittedHeightMap(GeoPoint[][] heightMap, TerrainOutputMesh terrainOutputMesh, int chunk, float heightFactor, CellType type) { //string color = "#00ff00ff"; string texture = "grassTexture.png"; switch (type) { case CellType.Snow: //color = "#ffffffff"; texture = "snowTexture.png"; break; case CellType.Rock: //color = "#999999ff"; texture = "rockTexture.png"; break; case CellType.Grass: //color = "#00ff00ff"; texture = "grassTexture.png"; break; } string color = "#ffffffff"; terrainOutputMesh.MaterialColor[chunk] = color; terrainOutputMesh.MaterialTexture[chunk] = "HeightMapMaterials" + System.IO.Path.DirectorySeparatorChar + texture; List <GeoPoint> tempVertices = new List <GeoPoint>(); List <GeoPoint[]> tempFaces = new List <GeoPoint[]>(); for (int x = 0; x < heightMap.Length; x++) { for (int y = 0; y < heightMap[x].Length; y++) { heightMap[x][y].VertexIdx = -1; } } for (int x = 0; x < heightMap.Length; x++) { for (int y = 1; y < heightMap[x].Length; y++) { if (heightMap[x][y].Type == type) { //terrainOutputMesh.VertexData[chunk].Add(new float[] { x, (float)(heightMap[x][y].Height * heightFactor), y }); tempVertices.Add(heightMap[x][y]); if (x < (heightMap[x].Length - 1)) { if (heightMap[x][y - 1].Type == type && heightMap[x + 1][y - 1].Type == type && heightMap[x + 1][y].Type == type) { // A tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); } if (heightMap[x][y - 1].Type == type && heightMap[x + 1][y - 1].Type != type && heightMap[x + 1][y].Type == type) { // B tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x][y - 1] }); } // C // D if (heightMap[x][y - 1].Type != type && heightMap[x + 1][y - 1].Type == type && heightMap[x + 1][y].Type == type) { // E tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); } if (heightMap[x][y - 1].Type == type && heightMap[x + 1][y - 1].Type == type && heightMap[x + 1][y].Type != type) { // F tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); } } if (x > 0 && heightMap[x - 1][y].Type != type && heightMap[x][y - 1].Type == type && heightMap[x - 1][y - 1].Type == type) { // G tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x][y - 1], heightMap[x - 1][y - 1] }); } } } } int vertexIdx = 1; foreach (GeoPoint[] geoPoints in tempFaces) { foreach (GeoPoint geoPoint in geoPoints) { if (geoPoint.VertexIdx == -1) { terrainOutputMesh.VertexData[chunk].Add(new float[] { geoPoint.X, (float)(geoPoint.Height * heightFactor), geoPoint.Y }); geoPoint.VertexIdx = vertexIdx; vertexIdx++; terrainOutputMesh.TexureCoordData[chunk].Add(new float[] { (geoPoint.X % 2 == 0?0:1), (geoPoint.Y % 2 == 0?0:1) }); } } terrainOutputMesh.FacesData[chunk].Add(new int[] { geoPoints[0].VertexIdx, geoPoints[1].VertexIdx, geoPoints[2].VertexIdx, }); } }
public List <TerrainOutput> StartProcess(List <TerrainInput> terrainInputs, Dictionary <LayerType, WorkflowData> workflowData) { System.Console.WriteLine("Will begin vegetation"); List <TerrainOutput> terrainOutputs = new List <TerrainOutput>(); /*System.Console.WriteLine("A"); * Dictionary<string, TerrainInput> inputMap = new Dictionary<string, TerrainInput>(); * Dictionary<string, FormField> formFieldsMap = new Dictionary<string, FormField>(); * createInputMap(terrainInputs, inputMap, formFieldsMap); * System.Console.WriteLine("B"); * string rules = ((FormFieldText)formFieldsMap["lSystemInput_formFieldRules"]).Value; * System.Console.WriteLine("C"); * Dictionary<char, string> originDestinationMap = new Dictionary<char, string>(); * System.Console.WriteLine("D"); * foreach (string rule in rules.Split(',')) * { * originDestinationMap.Add(rule.Split('>')[0][0], rule.Split('>')[1]); * } * System.Console.WriteLine("E"); * string production = Vegetation.createProducton("", "", ((FormFieldText)formFieldsMap["lSystemInput_formFieldAxiom"]).Value, originDestinationMap, ((FormFieldInteger)formFieldsMap["lSystemInput_formFieldIterations"]).Value); * System.Console.WriteLine("F"); * terrainOutputs.Add(Turtle.drawProduction(production, * ((FormFieldInteger)formFieldsMap["lSystemInput_formFieldStartWidth"]).Value, * ((FormFieldInteger)formFieldsMap["lSystemInput_formFieldStartHeight"]).Value, * ((FormFieldInteger)formFieldsMap["lSystemInput_formFieldStartX"]).Value, * ((FormFieldInteger)formFieldsMap["lSystemInput_formFieldStartY"]).Value, * (float)((FormFieldNumber)formFieldsMap["lSystemInput_formFieldStrokeX"]).Value, * (float)((FormFieldNumber)formFieldsMap["lSystemInput_formFieldStrokeY"]).Value, * ((FormFieldInteger)formFieldsMap["lSystemInput_formFieldRotation"]).Value)); * * System.Console.WriteLine(production); * * TerrainOutputValues terrainOutputValues = new TerrainOutputValues(); * terrainOutputValues.Key = "terrainOutputValues"; * terrainOutputValues.Title = "Result values"; * * terrainOutputValues.ValueKeys.Add("production"); * terrainOutputValues.ValueTitles.Add("Production"); * terrainOutputValues.Values.Add(production); * * System.Console.WriteLine("Will end vegetation"); * * terrainOutputs.Add(terrainOutputValues);*/ try { Dictionary <string, TerrainInput> inputMap = new Dictionary <string, TerrainInput>(); Dictionary <string, FormField> formFieldsMap = new Dictionary <string, FormField>(); createInputMap(terrainInputs, inputMap, formFieldsMap); terrainOutputs.AddRange(SpaceColonization.createTree( ((FormFieldInteger)formFieldsMap["treeParameters_formFieldStartSpace"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_formFieldStartSpace"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_formFieldStartSpace"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_minLeafDistance"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_maxLeafDistance"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_pointCount"]).Value, ((TerrainInputSketch)inputMap["treeTopSketch"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_leafCount"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_leafSize"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_leafOffset"]).Value, ((FormFieldInteger)formFieldsMap["treeParameters_branchLength"]).Value)); if (workflowData.ContainsKey(LayerType.HeightMap)) { HeightmapWorkflowData heightmapWorkflowData = (HeightmapWorkflowData)workflowData[LayerType.HeightMap]; TerrainOutputMesh terrainOutputMesh = new TerrainOutputMesh(); terrainOutputMesh.Title = "Terrain"; terrainOutputMesh.Key = "terrainHeightMap"; List <float[]> grassLand = new List <float[]>(); MeshGeneratorHelpers.FillHeightMapMesh(terrainOutputMesh, heightmapWorkflowData.HeightmapCells, heightmapWorkflowData.CellSize, heightmapWorkflowData.MinHeight, heightmapWorkflowData.MaxHeight, grassLand); int numOfRepeats = ((FormFieldInteger)formFieldsMap["treeParameters_numOfTrees"]).Value; TerrainOutputMesh treeMesh = (TerrainOutputMesh)terrainOutputs[0]; treeMesh.Title = "Tree"; treeMesh.Key = "Tree"; terrainOutputMesh.SubMeshes.Add((TerrainOutputMesh)terrainOutputs[0]); terrainOutputMesh.Positions.Add(new List <float[]>()); terrainOutputMesh.Scales.Add(new List <float[]>()); terrainOutputMesh.Rotations.Add(new List <float[]>()); for (int i = 0; i < numOfRepeats; i++) { if (grassLand.Count > 0) { int idx = SpaceColonization.random.Next(grassLand.Count); terrainOutputMesh.Positions[0].Add(new float[] { grassLand[idx][0] - 1f, grassLand[idx][2], grassLand[idx][1] - 1f }); terrainOutputMesh.Scales[0].Add(new float[] { 0.005f, 0.005f, 0.005f }); terrainOutputMesh.Rotations[0].Add(new float[] { 0f, 0f, 0f }); grassLand.RemoveAt(idx); } } terrainOutputs.Insert(0, terrainOutputMesh); } } catch (Exception ex) { System.Console.WriteLine(ex.Message); throw ex; } return(terrainOutputs); }
private void processMesh(TerrainOutputMesh terrainOutput, List <Mesh> meshes, List <Material> materials) { for (int chunk = 0; chunk < terrainOutput.VertexData.Count; chunk++) { Mesh mesh = new Mesh(); Vector3[] vertexArray = new Vector3[terrainOutput.VertexData[chunk].Count]; for (int i = 0; i < terrainOutput.VertexData[chunk].Count; i++) { vertexArray[i] = new Vector3(terrainOutput.VertexData[chunk][i][0], terrainOutput.VertexData[chunk][i][1], terrainOutput.VertexData[chunk][i][2]); } mesh.vertices = vertexArray; Vector3[] normalArray = new Vector3[terrainOutput.NormalData[chunk].Count]; for (int i = 0; i < terrainOutput.NormalData[chunk].Count; i++) { normalArray[i] = new Vector3(terrainOutput.NormalData[chunk][i][0], terrainOutput.NormalData[chunk][i][1], terrainOutput.NormalData[chunk][i][2]); } mesh.normals = normalArray; if (terrainOutput.TexureCoordData.Count > 0 && terrainOutput.TexureCoordData[chunk].Count > 0) { Vector2[] uvArray = new Vector2[terrainOutput.TexureCoordData[chunk].Count]; for (int i = 0; i < terrainOutput.TexureCoordData[chunk].Count; i++) { uvArray[i] = new Vector2(terrainOutput.TexureCoordData[chunk][i][0], terrainOutput.TexureCoordData[chunk][i][1]); } mesh.uv = uvArray; } int[] triangles = new int[terrainOutput.FacesData[chunk].Count * 3]; for (int i = 0; i < terrainOutput.FacesData[chunk].Count; i++) { int idx = i * 3; triangles[idx] = terrainOutput.FacesData[chunk][i][0] - 1; triangles[idx + 1] = terrainOutput.FacesData[chunk][i][1] - 1; triangles[idx + 2] = terrainOutput.FacesData[chunk][i][2] - 1; } mesh.triangles = triangles; mesh.RecalculateBounds(); mesh.Optimize(); meshes.Add(mesh); System.Console.WriteLine("Mesh created"); if (terrainOutput.MaterialColor.Count > 0 || terrainOutput.MaterialMode.Count > 0 || terrainOutput.MaterialTexture.Count > 0) { System.Console.WriteLine("Creating material"); Material material = new Material(Shader.Find("Standard")); material.SetFloat("_Glossiness", 0); if (terrainOutput.MaterialMode.Count > 0) { Material alfaMaterial = Resources.Load <Material>("Materials/Alfa"); System.Console.WriteLine("Mode: " + (byte)terrainOutput.MaterialMode[chunk]); material.SetFloat("_Mode", (byte)terrainOutput.MaterialMode[chunk]); switch ((byte)terrainOutput.MaterialMode[chunk]) { case 0: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; break; case 1: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; break; case 2: /*material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); * material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); * material.SetInt("_ZWrite", 0); * material.DisableKeyword("_ALPHATEST_ON"); * material.EnableKeyword("_ALPHABLEND_ON"); * material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); * material.renderQueue = 3000;*/ material = alfaMaterial; break; case 3: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 0); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; break; } } if (terrainOutput.MaterialColor.Count > 0) { Color color; ColorUtility.TryParseHtmlString(terrainOutput.MaterialColor[chunk], out color); material.SetColor("_Color", color); System.Console.WriteLine(terrainOutput.MaterialColor[chunk]); System.Console.WriteLine("" + color.r + " " + color.g + " " + color.b + " " + color.a); } if (terrainOutput.MaterialTexture.Count > 0 && terrainOutput.MaterialTexture[chunk].Length > 0) { System.Console.WriteLine("file://" + terrainOutput.MaterialTexture[chunk]); WWW www = new WWW("file://" + terrainOutput.MaterialTexture[chunk]); Texture2D texture = new Texture2D(4, 4, TextureFormat.DXT1, false); www.LoadImageIntoTexture(texture); material.mainTexture = texture; } materials.Add(material); } else { System.Console.WriteLine("No material"); materials.Add(null); } } if (terrainOutput.SubMeshes != null) { foreach (TerrainOutputMesh subMesh in terrainOutput.SubMeshes) { subMeshes.Add(new List <Mesh>()); subMaterials.Add(new List <Material>()); processMesh(subMesh, subMeshes[0], subMaterials[0]); } } }
public static void SaveMeshFile_(string filename_, TerrainOutputMesh terrainOutputMesh) { List <string> fileNames = new List <string>(); Console.WriteLine("Mesh chunks count: " + terrainOutputMesh.VertexData.Count); Console.WriteLine("Color count: " + terrainOutputMesh.MaterialColor.Count); for (int chunk = 0; chunk < terrainOutputMesh.VertexData.Count; chunk++) { string filename = filename_.Replace(".obj", "_" + chunk + ".obj"); fileNames.Add(filename); StreamWriter sw = File.CreateText(filename); if (terrainOutputMesh.MaterialFile != null && terrainOutputMesh.MaterialFile.Length != 0) { sw.WriteLine("mtllib " + PluginManager.PLUGINS_PATH + Path.DirectorySeparatorChar + terrainOutputMesh.MaterialFile); } Console.WriteLine("Mesh vertex count: " + terrainOutputMesh.VertexData[chunk].Count); Console.WriteLine("Mesh faces count: " + terrainOutputMesh.FacesData[chunk].Count); foreach (float[] vertex in terrainOutputMesh.VertexData[chunk]) { string line = "v "; for (var i = 0; i < vertex.Length; i++) { line += vertex[i] + " "; } sw.WriteLine(line); } if (terrainOutputMesh.TexureCoordData.Count > 0 && terrainOutputMesh.TexureCoordData[chunk].Count > 0) { foreach (float[] textureVertices in terrainOutputMesh.TexureCoordData[chunk]) { string line = "vt "; for (var i = 0; i < textureVertices.Length; i++) { line += textureVertices[i] + " "; } sw.WriteLine(line); } } Dictionary <int, List <float[]> > vertexNormals = new Dictionary <int, List <float[]> >(); Dictionary <int, int> vertexNormal = new Dictionary <int, int>(); foreach (int[] face in terrainOutputMesh.FacesData[chunk]) { float[] n = triangleNormal(terrainOutputMesh.VertexData[chunk][face[0] - 1], terrainOutputMesh.VertexData[chunk][face[1] - 1], terrainOutputMesh.VertexData[chunk][face[2] - 1]); for (var i = 0; i < face.Length; i++) { if (!vertexNormals.ContainsKey(face[i])) { vertexNormals.Add(face[i], new List <float[]>()); } vertexNormals[face[i]].Add(n); } } int vn = 1; foreach (int v in vertexNormals.Keys) { float[] vnormal = meanNormal(vertexNormals[v]); string line = "vn "; for (var i = 0; i < vnormal.Length; i++) { line += vnormal[i] + " "; } sw.WriteLine(line); vertexNormal.Add(v, vn); vn++; } if (terrainOutputMesh.MaterialName.Count > 0 && terrainOutputMesh.MaterialName[chunk].Length > 0) { sw.WriteLine("usemtl " + terrainOutputMesh.MaterialName[chunk]); } int j = 0; foreach (int[] face in terrainOutputMesh.FacesData[chunk]) { int[] textureVertex = null; if (terrainOutputMesh.FacesTextureCoordData.Count > 0 && terrainOutputMesh.FacesTextureCoordData[chunk].Count > 0) { textureVertex = terrainOutputMesh.FacesTextureCoordData[chunk][j]; } string line = "f "; for (var i = 0; i < face.Length; i++) { line += face[i] + "/" + (textureVertex == null?"":("" + textureVertex[i])) + "/" + vertexNormal[face[i]] + " "; } sw.WriteLine(line); j++; } sw.Close(); } terrainOutputMesh.VertexData.Clear(); terrainOutputMesh.FacesData.Clear(); terrainOutputMesh.MeshPath = fileNames; }
public List <int> fill3DBranch(Vector v1, Vector v2, float width, int sides, TerrainOutputMesh terrainOutputMesh, List <int> previousVertex) { int initialIdx = terrainOutputMesh.VertexData[0].Count; if (previousVertex == null) { fillCircle(v1, v2, sides, width, terrainOutputMesh.VertexData[0], terrainOutputMesh.FacesData[0], 0, true); fillCircle(v2, v1, sides, width, terrainOutputMesh.VertexData[0], terrainOutputMesh.FacesData[0], (float)Math.PI, true); int i; i = initialIdx + 2; terrainOutputMesh.FacesData[0].Add(new int[] { i, i + sides + 1, i + 1 }); terrainOutputMesh.FacesData[0].Add(new int[] { i + sides + 1, i + sides + sides, i + 1 }); for (i = 2; i < sides; i++) { terrainOutputMesh.FacesData[0].Add(new int[] { i + initialIdx + 1, initialIdx + 2 + sides + sides - (i - 2), i + initialIdx + 2 }); terrainOutputMesh.FacesData[0].Add(new int[] { initialIdx + 2 + sides + sides - (i - 2), initialIdx + 2 + sides + sides - (i - 2) - 1, i + initialIdx + 2 }); } i = initialIdx + sides + 1; terrainOutputMesh.FacesData[0].Add(new int[] { i, initialIdx + 2 + sides + 2, initialIdx + 2 }); terrainOutputMesh.FacesData[0].Add(new int[] { initialIdx + 2 + sides + 2, initialIdx + 2 + sides + 1, initialIdx + 2 }); } else { int initialVertices = terrainOutputMesh.VertexData[0].Count; fillCircle(v2, v1, sides, width, terrainOutputMesh.VertexData[0], terrainOutputMesh.FacesData[0], (float)Math.PI, false); terrainOutputMesh.FacesData[0].Add(new int[] { previousVertex[0], initialVertices + 1, previousVertex[sides - 1] }); terrainOutputMesh.FacesData[0].Add(new int[] { previousVertex[sides - 1], initialVertices + 1, initialVertices + sides }); for (int i = 1; i < sides; i++) { terrainOutputMesh.FacesData[0].Add(new int[] { previousVertex[i], initialVertices + i + 1, previousVertex[i - 1] }); terrainOutputMesh.FacesData[0].Add(new int[] { previousVertex[i - 1], initialVertices + i + 1, initialVertices + i }); } List <int> newPreviousVertex = new List <int>(); for (int i = 1; i <= sides; i++) { newPreviousVertex.Add(initialVertices + i); } return(newPreviousVertex); } return(null); }
public void fill3DMesh(TerrainOutputMesh terrainOutputMesh) { int maxWidthFactor = 20; if (branches[0].WidthFactor > 0) { maxWidthFactor = branches[0].WidthFactor; } float textureSideStep = 1.0f / branchSides; foreach (Branch branch in branches) { float textureStep = ((float)(maxWidthFactor - branch.WidthFactor)) * textureStepJump; float thickness = ((float)branch.WidthFactor / (float)maxWidthFactor) * 30.0f; if (branch.Parent != null) { if (branch.WidthFactor == 0) { terrainOutputMesh.VertexData[0].Add(new float[] { branch.Pos.Vx, branch.Pos.Vy, branch.Pos.Vz }); terrainOutputMesh.TexureCoordData[0].Add(new float[] { 0.5f, textureStep }); int pointVertex = terrainOutputMesh.VertexData[0].Count; for (int i = 0; i < branchSides - 1; i++) { terrainOutputMesh.FacesData[0].Add(new int[] { branch.Parent.vertexes[i], branch.Parent.vertexes[i + 1], pointVertex }); } terrainOutputMesh.FacesData[0].Add(new int[] { branch.Parent.vertexes[branchSides - 1], branch.Parent.vertexes[0], pointVertex }); } else { branch.vertexes = fill3DBranch(branch.Parent.Pos, branch.Pos, thickness, branchSides, terrainOutputMesh, branch.Parent.vertexes); for (int i = 0; i < branchSides; i++) { terrainOutputMesh.TexureCoordData[0].Add(new float[] { textureSideStep *i, textureStep }); } } } else { Vector oldPos = new Vector( branch.Pos.Vx - branch.Dir.Vx, branch.Pos.Vy - branch.Dir.Vy, branch.Pos.Vz - branch.Dir.Vz ); fillCircle(branch.Pos, oldPos, branchSides, thickness, terrainOutputMesh.VertexData[0], terrainOutputMesh.FacesData[0], (float)Math.PI, false); for (int i = 0; i < branchSides; i++) { terrainOutputMesh.TexureCoordData[0].Add(new float[] { textureSideStep *i, textureStep }); } List <int> oldVertex = new List <int>(); for (int i = 1; i <= branchSides; i++) { oldVertex.Add(i); } branch.vertexes = oldVertex; } } }
public static List <TerrainOutput> createTree(int width, int height, int depth, int minDist, int maxDist, int pointCount, int[][] treeTopSketch, int leafCount, int leafSize, int maxCenterOffset, int branchSize) { SpaceColonization.branchSize = branchSize; treeTopSketch = Helpers.Instance.ResizePixels(treeTopSketch, treeTopSketch.Length, treeTopSketch.Length, width, height); List <TreeSection> treeSections = new List <TreeSection>(); createTreeTopCircunferenceLookUp(treeTopSketch, treeSections); List <TreeSection> treeSectionOdds = new List <TreeSection>(); for (int i = 0; i < treeSections.Count; i++) { for (int j = 0; j < treeSections[i].EndX - treeSections[i].StartX; j++) { treeSectionOdds.Add(treeSections[i]); } } Tree tree = new Tree(pointCount, width, height, depth, minDist, maxDist, treeSectionOdds); TerrainOutputMesh terrainOutputMesh = new TerrainOutputMesh(); terrainOutputMesh.Key = "TreeMesh"; terrainOutputMesh.Title = "Tree Mesh"; terrainOutputMesh.CameraPosition = new float[] { width / 2, height / 2, -depth }; terrainOutputMesh.CameraRotation = new float[] { 0, 0, 0 }; terrainOutputMesh.MaterialFile = "VegetationMaterials" + System.IO.Path.DirectorySeparatorChar + "material.mtl"; System.Console.WriteLine("Gen A"); terrainOutputMesh.VertexData.Add(new List <float[]>()); terrainOutputMesh.FacesData.Add(new List <int[]>()); terrainOutputMesh.TexureCoordData.Add(new List <float[]>()); terrainOutputMesh.FacesTextureCoordData.Add(new List <int[]>()); terrainOutputMesh.MaterialName.Add("Branches"); terrainOutputMesh.MaterialColor.Add("#ffffffff"); terrainOutputMesh.MaterialMode.Add(TerrainOutputMesh.RenderingMode.opaque); terrainOutputMesh.MaterialTexture.Add("VegetationMaterials" + System.IO.Path.DirectorySeparatorChar + "wood.png"); System.Console.WriteLine("Gen B"); tree.fill3DMesh(terrainOutputMesh); System.Console.WriteLine("Gen C"); terrainOutputMesh.VertexData.Add(new List <float[]>()); terrainOutputMesh.FacesData.Add(new List <int[]>()); terrainOutputMesh.TexureCoordData.Add(new List <float[]>()); terrainOutputMesh.FacesTextureCoordData.Add(new List <int[]>()); terrainOutputMesh.MaterialName.Add("Leaves"); terrainOutputMesh.MaterialColor.Add("#ffffffff"); terrainOutputMesh.MaterialMode.Add(TerrainOutputMesh.RenderingMode.fade); terrainOutputMesh.MaterialTexture.Add("VegetationMaterials" + System.IO.Path.DirectorySeparatorChar + "leafTexture.png"); System.Console.WriteLine("Gen D"); tree.fill3DLeafMesh(terrainOutputMesh, leafCount, leafSize, maxCenterOffset); System.Console.WriteLine("Gen E"); List <TerrainOutput> outputs = new List <TerrainOutput>(); outputs.Add(terrainOutputMesh); /*outputs.Add(createImage(tree, "Tree XY", "TreeXY", "xy", width, height)); * outputs.Add(createImage(tree, "Tree ZY", "TreeZY", "zy", depth, height)); * outputs.Add(createImage(tree, "Tree XZ", "TreeXZ", "xz", width, depth));*/ return(outputs); }
private static void exportTransitionHeightMap(GeoPoint[][] heightMap, TerrainOutputMesh terrainOutputMesh, int chunk, float heightFactor) { Dictionary <CellType, float[]> typeUvsStart = new Dictionary <CellType, float[]>(); typeUvsStart.Add(CellType.Grass, new float[] { 0, 1 }); typeUvsStart.Add(CellType.Snow, new float[] { 1, 1 }); typeUvsStart.Add(CellType.Rock, new float[] { 0, 0 }); Dictionary <CellType, float[]> typeUvsEnd = new Dictionary <CellType, float[]>(); typeUvsEnd.Add(CellType.Grass, new float[] { 0, 0.33f }); typeUvsEnd.Add(CellType.Snow, new float[] { 1, 0.33f }); typeUvsEnd.Add(CellType.Rock, new float[] { 0.66f, 1 }); List <GeoPoint> tempVertices = new List <GeoPoint>(); List <GeoPoint[]> tempFaces = new List <GeoPoint[]>(); for (int x = 0; x < heightMap.Length; x++) { for (int y = 0; y < heightMap[x].Length; y++) { heightMap[x][y].VertexIdx = -1; heightMap[x][y].uv = null; } } for (int x = 0; x < heightMap.Length; x++) { for (int y = 1; y < heightMap[x].Length; y++) { //terrainOutputMesh.VertexData[chunk].Add(new float[] { x, (float)(heightMap[x][y].Height * heightFactor), y }); tempVertices.Add(heightMap[x][y]); if (x < (heightMap[x].Length - 1) && (heightMap[x][y].Type != heightMap[x][y - 1].Type || heightMap[x][y].Type != heightMap[x + 1][y - 1].Type || heightMap[x][y].Type != heightMap[x + 1][y].Type)) { if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // A tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // B tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y].Type) { // C tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } if (heightMap[x][y].Type == heightMap[x][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // D tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } if (heightMap[x][y].Type == heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // E tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y].Type) { // F tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } if (heightMap[x][y].Type == heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y].Type) { // G tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); tempFaces.Add(new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }); setTransitionUv(tempFaces[tempFaces.Count - 1]); } } } } int vertexIdx = 1; foreach (GeoPoint[] geoPoints in tempFaces) { foreach (GeoPoint geoPoint in geoPoints) { if (geoPoint.VertexIdx == -1) { terrainOutputMesh.VertexData[chunk].Add(new float[] { geoPoint.X, (float)(geoPoint.Height * heightFactor), geoPoint.Y }); geoPoint.VertexIdx = vertexIdx; vertexIdx++; terrainOutputMesh.TexureCoordData[chunk].Add(geoPoint.uv); } } terrainOutputMesh.FacesData[chunk].Add(new int[] { geoPoints[0].VertexIdx, geoPoints[1].VertexIdx, geoPoints[2].VertexIdx, }); } }
private static void exportTransitionHeightMap_(GeoPoint[][] heightMap, TerrainOutputMesh terrainOutputMesh, float heightFactor) { Dictionary <string, List <GeoPoint[]> > tempFaces = new Dictionary <string, List <GeoPoint[]> >(); GeoPoint[] tempFace; for (int x = 0; x < heightMap.Length; x++) { for (int y = 0; y < heightMap[x].Length; y++) { //heightMap[x][y].VertexIdx = -1; //heightMap[x][y].uv = null; heightMap[x][y].uvMap = new Dictionary <string, List <float[]> >(); heightMap[x][y].currentUv = 0; } } for (int x = 0; x < heightMap.Length; x++) { for (int y = 1; y < heightMap[x].Length; y++) { //terrainOutputMesh.VertexData[chunk].Add(new float[] { x, (float)(heightMap[x][y].Height * heightFactor), y }); //tempVertices.Add(heightMap[x][y]); if (x < (heightMap[x].Length - 1) && (heightMap[x][y].Type != heightMap[x][y - 1].Type || heightMap[x][y].Type != heightMap[x + 1][y - 1].Type || heightMap[x][y].Type != heightMap[x + 1][y].Type)) { if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // A tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }; addTempFaceList(tempFaces, tempFace); tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }; addTempFaceList(tempFaces, tempFace); } if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // B tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }; addTempFaceList(tempFaces, tempFace); tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }; addTempFaceList(tempFaces, tempFace); } if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y].Type) { // C tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }; addTempFaceList(tempFaces, tempFace); } if (heightMap[x][y].Type == heightMap[x][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // D tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }; addTempFaceList(tempFaces, tempFace); } if (heightMap[x][y].Type == heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y].Type) { // E tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }; addTempFaceList(tempFaces, tempFace); tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }; addTempFaceList(tempFaces, tempFace); } if (heightMap[x][y].Type != heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y].Type) { // F tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }; addTempFaceList(tempFaces, tempFace); tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }; addTempFaceList(tempFaces, tempFace); } if (heightMap[x][y].Type == heightMap[x][y - 1].Type && heightMap[x][y].Type != heightMap[x + 1][y - 1].Type && heightMap[x][y].Type == heightMap[x + 1][y].Type) { // G tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y], heightMap[x + 1][y - 1] }; addTempFaceList(tempFaces, tempFace); tempFace = new GeoPoint[] { heightMap[x][y], heightMap[x + 1][y - 1], heightMap[x][y - 1] }; addTempFaceList(tempFaces, tempFace); } } } } foreach (string signature in tempFaces.Keys) { System.Console.Out.WriteLine("# Signature: " + signature); int vertexIdx = 1; /*foreach (GeoPoint[] geoPoints in tempFaces[signature]) * { * foreach (GeoPoint geoPoint in geoPoints) * { * geoPoint.VertexIdx = -1; * } * }*/ terrainOutputMesh.VertexData.Add(new List <float[]>()); terrainOutputMesh.FacesData.Add(new List <int[]>()); terrainOutputMesh.MaterialColor.Add("#ffffffff"); terrainOutputMesh.MaterialTexture.Add("HeightMapMaterials" + System.IO.Path.DirectorySeparatorChar + "transitionTexture.png"); terrainOutputMesh.TexureCoordData.Add(new List <float[]>()); int chunk = terrainOutputMesh.VertexData.Count - 1; foreach (GeoPoint[] geoPoints in tempFaces[signature]) { foreach (GeoPoint geoPoint in geoPoints) { terrainOutputMesh.VertexData[chunk].Add(new float[] { geoPoint.X, (float)(geoPoint.Height * heightFactor), geoPoint.Y }); terrainOutputMesh.TexureCoordData[chunk].Add(geoPoint.uvMap[signature][0]); geoPoint.uvMap[signature].RemoveAt(0); } terrainOutputMesh.FacesData[chunk].Add(new int[] { vertexIdx, vertexIdx + 1, vertexIdx + 2, }); vertexIdx += 3; } } }
public static void SaveMeshFile(string filename_, TerrainOutputMesh terrainOutputMesh) { if (terrainOutputMesh.NormalData != null && terrainOutputMesh.NormalData.Count > 0) { return; } List <string> fileNames = new List <string>(); Console.WriteLine("Mesh chunks count: " + terrainOutputMesh.VertexData.Count); Console.WriteLine("Color count: " + terrainOutputMesh.MaterialColor.Count); Dictionary <string, List <float[]> > vertexNormals = new Dictionary <string, List <float[]> >(); Dictionary <string, float[]> finalNormals = new Dictionary <string, float[]>(); for (int chunk = 0; chunk < terrainOutputMesh.VertexData.Count; chunk++) { foreach (int[] face in terrainOutputMesh.FacesData[chunk]) { float[] n = triangleNormal(terrainOutputMesh.VertexData[chunk][face[0] - 1], terrainOutputMesh.VertexData[chunk][face[1] - 1], terrainOutputMesh.VertexData[chunk][face[2] - 1]); for (var i = 0; i < face.Length; i++) { string vertexSignature = getVertexSignature(terrainOutputMesh.VertexData[chunk][face[i] - 1]); if (!vertexNormals.ContainsKey(vertexSignature)) { vertexNormals.Add(vertexSignature, new List <float[]>()); } vertexNormals[vertexSignature].Add(n); } } } foreach (string vertexSignature in vertexNormals.Keys) { float[] vnormal = meanNormal(vertexNormals[vertexSignature]); finalNormals.Add(vertexSignature, vnormal); } for (int chunk = 0; chunk < terrainOutputMesh.VertexData.Count; chunk++) { if (terrainOutputMesh.MaterialTexture.Count > 0 && terrainOutputMesh.MaterialTexture[chunk].Length > 0) { terrainOutputMesh.MaterialTexture[chunk] = PluginManager.PLUGINS_PATH + Path.DirectorySeparatorChar + terrainOutputMesh.MaterialTexture[chunk]; } terrainOutputMesh.NormalData.Add(new List <float[]>()); foreach (float[] vertex in terrainOutputMesh.VertexData[chunk]) { string vertexSignature = getVertexSignature(vertex); terrainOutputMesh.NormalData[chunk].Add(finalNormals[vertexSignature]); } terrainOutputMesh.FaceNormalData.Add(new List <int[]>()); foreach (int[] face in terrainOutputMesh.FacesData[chunk]) { int[] faceNormals = new int[3]; faceNormals[0] = face[0]; faceNormals[1] = face[1]; faceNormals[2] = face[2]; terrainOutputMesh.FaceNormalData[chunk].Add(faceNormals); } } foreach (TerrainOutputMesh subMesh in terrainOutputMesh.SubMeshes) { SaveMeshFile(filename_, subMesh); } }
public static void startWork(List <TerrainInput> terrainInputs, List <TerrainOutput> terrainOutputs, HeightmapWorkflowData heightmapWorkflowData) { int size = 513; Dictionary <string, TerrainInput> inputMap = new Dictionary <string, TerrainInput>(); Dictionary <string, FormField> formFieldsMap = new Dictionary <string, FormField>(); createInputMap(terrainInputs, inputMap, formFieldsMap); System.Console.Out.WriteLine("Starting"); switch (((FormFieldOptions)formFieldsMap["parameters_gridSize"]).Value) { case 0: size = 65; break; case 1: size = 129; break; case 2: size = 257; break; case 3: size = 513; break; case 4: size = 1025; break; } Random random; if (targetSamples > 0) { random = new Random(); if (curSample == 0) { meanHeight = new List <float>(); meanVariance = new List <float>(); } } else { random = new Random(((FormFieldInteger)formFieldsMap["parameters_seed"]).Value); } //Random random = new Random(((FormFieldInteger)formFieldsMap["parameters_seed"]).Value); float heightFactor = (float)((FormFieldInteger)formFieldsMap["parameters_maxHeight"]).Value / (float)((FormFieldInteger)formFieldsMap["parameters_cellSize"]).Value; float?[][] heightMap = new float?[size][]; for (int x = 0; x < heightMap.Length; x++) { heightMap[x] = new float?[size]; for (int y = 0; y < heightMap.Length; y++) { heightMap[x][y] = null; } } System.Console.Out.WriteLine("Data created"); TerrainOutputImage terrainOutputRidges = new TerrainOutputImage(); terrainOutputRidges.Title = "Ridges"; terrainOutputRidges.Key = "ridges"; List <List <GeoPoint> > ridges = new List <List <GeoPoint> >(); if (((FormFieldCheck)formFieldsMap["parameters_useRidgeSketch"]).Value) { int[][] resizedPixels = Helpers.Instance.ResizePixels(((TerrainInputSketch)inputMap["ridgeSketch"]).Value, ((TerrainInputSketch)inputMap["ridgeSketch"]).Width, ((TerrainInputSketch)inputMap["ridgeSketch"]).Height, size, size); terrainOutputRidges.ImageData = resizedPixels; for (int x = 0; x < heightMap.Length; x++) { for (int y = 0; y < heightMap.Length; y++) { float height = (float)(((resizedPixels[x][y] & 0xff000000) >> 24) / 256.0); if (height != 0) { heightMap[x][y] = height; } } } } else { int ridgeParticles = ((FormFieldInteger)formFieldsMap["parameters_ridgeParticles"]).Value; RidgeHelpers.createRidges(heightMap, ridges, random, ridgeParticles); terrainOutputRidges.ImageData = new int[heightMap.Length][]; for (int x = 0; x < heightMap.Length; x++) { terrainOutputRidges.ImageData[x] = new int[heightMap.Length]; for (int y = 0; y < heightMap[x].Length; y++) { byte color = 0; if (heightMap[x][y] != null) { color = (byte)(heightMap[x][y] * 256); } terrainOutputRidges.ImageData[x][y] = (color << 24) | (color << 16) | (color << 8) | 0xff; } } } GeoPoint[][] gaussGeoPoints = TerrainHelpers.calculateDistanceToRidges(heightMap); TerrainOutputImage gaussTerrainOutputHeightMap = new TerrainOutputImage(); gaussTerrainOutputHeightMap.Title = "Gauss Height map"; gaussTerrainOutputHeightMap.Key = "gaussHeightMap"; gaussTerrainOutputHeightMap.ImageData = new int[gaussGeoPoints.Length][]; for (int x = 0; x < gaussGeoPoints.Length; x++) { gaussTerrainOutputHeightMap.ImageData[x] = new int[gaussGeoPoints.Length]; for (int y = 0; y < gaussGeoPoints[x].Length; y++) { byte color = (byte)(gaussGeoPoints[x][y].Height * 256); gaussTerrainOutputHeightMap.ImageData[x][y] = (color << 24) | (color << 16) | (color << 8) | 0xff; } } float?[][] gaussHeightMap = new float?[gaussGeoPoints.Length][]; for (int x = 0; x < gaussGeoPoints.Length; x++) { gaussHeightMap[x] = new float?[gaussGeoPoints.Length]; for (int y = 0; y < gaussGeoPoints[x].Length; y++) { gaussHeightMap[x][y] = gaussGeoPoints[x][y].Height; } } int[][] roughnessSketch = Helpers.Instance.ResizePixels(((TerrainInputSketch)inputMap["roughnessSketch"]).Value, ((TerrainInputSketch)inputMap["roughnessSketch"]).Width, ((TerrainInputSketch)inputMap["roughnessSketch"]).Height, size, size); float[][] roughness = new float[size][]; int veryLowColor = ColorToInt(stringToColor("#0000ffff")); int lowColor = ColorToInt(stringToColor("#00ffffff")); int highColor = ColorToInt(stringToColor("#ffff00ff")); int veryHighColor = ColorToInt(stringToColor("#ff0000ff")); for (int x = 0; x < size; x++) { roughness[x] = new float[size]; for (int y = 0; y < size; y++) { if (roughnessSketch[x][y] == veryLowColor) { roughness[x][y] = 0.5f; } else if (roughnessSketch[x][y] == lowColor) { roughness[x][y] = 0.75f; } else if (roughnessSketch[x][y] == highColor) { roughness[x][y] = 1.25f; } else if (roughnessSketch[x][y] == veryHighColor) { roughness[x][y] = 1.5f; } else { roughness[x][y] = 1f; } } } TerrainOutputImage terrainOutputRoughness = new TerrainOutputImage(); terrainOutputRoughness.Title = "Roughness"; terrainOutputRoughness.Key = "roughness"; terrainOutputRoughness.ImageData = roughnessSketch; //List<GeoPoint> riverPoints = RiverHelpers.traceRivers(gaussHeightMap, ridges, 8, random); /*foreach(GeoPoint geoPoint in riverPoints) * { * heightMap[geoPoint.X][geoPoint.Y] = geoPoint.Height; * }*/ List <GeoPoint> riverPoints = new List <GeoPoint>(); System.Console.Out.WriteLine("Ridges created"); TerrainHelpers.generateTerrain(heightMap, random, roughness, riverPoints, gaussHeightMap); System.Console.Out.WriteLine("Terrain created"); int termalErosionPass = ((FormFieldInteger)formFieldsMap["parameters_thermalErosionPass"]).Value; if (termalErosionPass != 0) { ErosionHelpers.applyThermalErosion(heightMap, termalErosionPass); System.Console.Out.WriteLine("ThermalErosion applied"); } int hydraulicErosionPass = ((FormFieldInteger)formFieldsMap["parameters_hydraulicErosionPass"]).Value; if (hydraulicErosionPass != 0) { HydraulicErosionCell[][] hydraulicErosionCells = ErosionHelpers.applyHydraulicErosion(heightMap, hydraulicErosionPass); System.Console.Out.WriteLine("HydraulicErosion applied"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("###Pass " + hydraulicErosionPass + "######"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); System.Console.Out.WriteLine("########################"); } System.Console.Out.WriteLine("##From terrain changed!!!"); String meanHeightStr = "Mean samples: "; String meanVarianceStr = "Mean variance: "; Boolean doContinue = true; if (targetSamples > 0) { //meanHeight = new List<float>(); //meanVariance = new List<float>(); int count = 0; double sum = 0; double diffSum = 0; for (int x = 0; x < heightMap.Length; x++) { for (int y = 0; y < heightMap[x].Length; y++) { count++; sum += heightMap[x][y].Value; diffSum += Math.Abs(getAdjacentCellsMean(heightMap, x, y).Value - heightMap[x][y].Value); } } float mean = (float)(sum / count); float diffMean = (float)(diffSum / count); meanHeight.Add(mean); meanVariance.Add(diffMean); foreach (float meanValue in meanHeight) { meanHeightStr += "#" + meanValue; } foreach (float varianceValue in meanVariance) { meanVarianceStr += "#" + varianceValue; } System.Console.Out.WriteLine(meanHeightStr); System.Console.Out.WriteLine(meanVarianceStr); curSample++; if (curSample < targetSamples) { terrainOutputs.Clear(); System.Console.Out.WriteLine("Starting sample:" + curSample); doContinue = false; startWork(terrainInputs, terrainOutputs, heightmapWorkflowData); } else { System.Console.Out.WriteLine("All samples done"); } } if (!doContinue) { return; } TerrainOutputMesh terrainOutputMesh = new TerrainOutputMesh(); terrainOutputMesh.Title = "Height map mesh"; terrainOutputMesh.Key = "heightMap"; terrainOutputMesh.CameraPosition = new float[] { 0, size / 4, 0 }; terrainOutputMesh.CameraRotation = new float[] { 22.5f, 45, 0 }; exportHeightMap(heightMap, terrainOutputMesh, heightFactor); TerrainOutputImage terrainOutputHeightMap = new TerrainOutputImage(); terrainOutputHeightMap.Title = "Height map bmp"; terrainOutputHeightMap.Key = "heightMapBmp"; GeoPoint[][] heightMapGeoPoints = new GeoPoint[heightMap.Length][]; terrainOutputHeightMap.ImageData = new int[heightMap.Length][]; heightmapWorkflowData.HeightmapCells = new float[heightMap.Length][]; float maxHeight = 0; float minHeight = 1; for (int x = 0; x < heightMap.Length; x++) { heightMapGeoPoints[x] = new GeoPoint[heightMap[x].Length]; terrainOutputHeightMap.ImageData[x] = new int[heightMap.Length]; heightmapWorkflowData.HeightmapCells[x] = new float[heightMap.Length]; for (int y = 0; y < heightMap[x].Length; y++) { GeoPoint geoPoint = new GeoPoint(); geoPoint.Height = (float)heightMap[x][y]; geoPoint.X = x; geoPoint.Y = y; heightMapGeoPoints[x][y] = geoPoint; byte color = (byte)(heightMap[x][y] * 256); terrainOutputHeightMap.ImageData[x][y] = (color << 24) | (color << 16) | (color << 8) | 0xff; heightmapWorkflowData.HeightmapCells[x][y] = (float)heightMap[x][y]; if (maxHeight < (float)heightMap[x][y]) { maxHeight = (float)heightMap[x][y]; } if (minHeight > (float)heightMap[x][y]) { minHeight = (float)heightMap[x][y]; } } } heightmapWorkflowData.MaxHeight = maxHeight * (float)((FormFieldInteger)formFieldsMap["parameters_maxHeight"]).Value; heightmapWorkflowData.MinHeight = minHeight * (float)((FormFieldInteger)formFieldsMap["parameters_maxHeight"]).Value; heightmapWorkflowData.CellSize = (float)((FormFieldInteger)formFieldsMap["parameters_cellSize"]).Value; foreach (GeoPoint geoPoint in riverPoints) { byte color = (byte)(geoPoint.Height * 256); terrainOutputHeightMap.ImageData[geoPoint.X][geoPoint.Y] = (0x00 << 24) | (0x00 << 16) | (color << 8) | 0xff; } int chunk = 0; TerrainOutputMesh splittedMesh = new TerrainOutputMesh(); splittedMesh.Title = "Terrain"; splittedMesh.Key = "terrainHeightMap"; List <float[]> grassLand = new List <float[]>(); MeshGeneratorHelpers.FillHeightMapMesh(splittedMesh, heightMapGeoPoints, heightmapWorkflowData.CellSize, heightmapWorkflowData.MinHeight, heightmapWorkflowData.MaxHeight, grassLand); /*splittedMesh.VertexData.Add(new List<float[]>()); * splittedMesh.FacesData.Add(new List<int[]>()); * splittedMesh.MaterialColor.Add("#ffffffff"); * splittedMesh.MaterialTexture.Add("HeightMapMaterials\\transitionTexture.png"); * splittedMesh.TexureCoordData.Add(new List<float[]>()); * exportTransitionHeightMap(heightMapGeoPoints, splittedMesh, chunk, heightFactor);*/ terrainOutputs.Add(splittedMesh); //terrainOutputs.Add(terrainOutputMesh); terrainOutputs.Add(terrainOutputHeightMap); terrainOutputs.Add(gaussTerrainOutputHeightMap); terrainOutputs.Add(terrainOutputRidges); //terrainOutputs.Add(terrainOutputObject); //terrainOutputs.Add(terrainOutputRoughness); //terrainOutputs.Add(terrainOutputSplitted); //Vector[][] waterVelocityField = RiverHelpers.getVelocityField(gaussHeightMap); //terrainOutputs.Add(RiverHelpers.getVectorFieldImage(waterVelocityField)); }