public void UpdateMesh() { var sw = Stopwatch.StartNew(); var mesh = MeshFilter.mesh = FlatMeshGenerator.GenerateFlatMesh(Size, scale); mesh.RecalculateNormals(); sw.Stop(); var elapsedMs = (double)sw.ElapsedTicks / Stopwatch.Frequency * 1000D; UnityEngine.Debug.Log("UpdateMesh: " + elapsedMs + "ms"); }
////////////////////////////////////////////////////////////////////////////// // // //Unity Functions // // // ////////////////////////////////////////////////////////////////////////////// void Start() { //First check if meshes inside 'meshfilterCollection' can be combined FlatMeshGenerator.COMBINE_INFO combineInfo; combineInfo = FlatMeshGenerator.CanBeMeshesCombined(meshfilterCollection); if (combineInfo != FlatMeshGenerator.COMBINE_INFO.OK) { //Houston we have a problem Debug.LogError(combineInfo.ToString()); return; } //Will contain bake results Mesh newMesh = null; //Will contain baking reports, will help if something goes wrong FlatMeshGenerator.CONVERTION_INFO[] convertionInfo; //Same as above but with more detail info string[] convertionInfoString; //Generating flat meshes and then combining newMesh = FlatMeshGenerator.GenerateFlatMeshesAndThenCombine(meshfilterCollection, out convertionInfo, out convertionInfoString, flatOptions); //Check reports if (convertionInfoString != null) { for (int i = 0; i < convertionInfoString.Length; i++) { if (convertionInfo[i] != FlatMeshGenerator.CONVERTION_INFO.Ok) { Debug.LogWarning(convertionInfoString[i]); } } } //Successful conversation if (newMesh != null) { gameObject.AddComponent <MeshFilter>().sharedMesh = newMesh; gameObject.AddComponent <MeshRenderer>().sharedMaterial = vertexColorMaterial; } }
////////////////////////////////////////////////////////////////////////////// // // //Unity Functions // // // ////////////////////////////////////////////////////////////////////////////// void Start() { if (targetTerrain == null) { return; } //Will contain bake results //Need - array - as FlatMeshGenerator returns mesh array depending on chunk count Mesh[] newMesh = null; //Will contain baking reports, will help if something goes wrong FlatMeshGenerator.CONVERTION_INFO[] convertionInfo; //Same as above but with more detail info string[] convertionInfoString; //Generating flat terrain newMesh = FlatMeshGenerator.GenerateFlatTerrain(targetTerrain, out convertionInfo, out convertionInfoString, flatOptions); //Check reports if (convertionInfoString != null) { for (int i = 0; i < convertionInfoString.Length; i++) { Debug.LogWarning(convertionInfoString[i]); } } //Successful conversation if (newMesh != null) { for (int i = 0; i < newMesh.Length; i++) { //Create new gameobject for each chunk GameObject chunk = new GameObject(newMesh[i].name); chunk.AddComponent <MeshFilter>().sharedMesh = newMesh[i]; chunk.AddComponent <MeshRenderer>().sharedMaterial = vertexColorMaterial; //Move to parent chunk.transform.parent = this.gameObject.transform; chunk.transform.localPosition = Vector3.zero; } } }
private void SpawnChunk(int size, int xPos, int yPos) { var chunk = new GameObject { name = string.Format("Terrain chunk [{0}, {1}]", xPos, yPos) }; chunk.transform.parent = transform; var meshFilter = chunk.AddComponent <MeshFilter>(); meshFilter.mesh = FlatMeshGenerator.GenerateFlatMesh(size, scale); var renderer = chunk.AddComponent <MeshRenderer>(); renderer.material = terrainMaterial; }
//map generation script public void GenerateMap() { #region variables and setup //this is the base noise module that will be manipulated baseModule = null; //this is the noisemap that will be generated noiseMap = null; MapDisplay display = FindObjectOfType <MapDisplay>(); if (!useRandomSeed) { seedValue = seed.GetHashCode(); } else { seedValue = UnityEngine.Random.Range(0, 10000000); } #endregion #region Noise Function Setup for (int i = 0; i < noiseFunctions.Length; i++) { noiseFunctions[i].seed = seedValue + i; } //generates noise for every noisefunction for (int i = 0; i < noiseFunctions.Length; i++) { if (noiseFunctions[i].enabled) { noiseFunctions[i].MakeNoise(); } } //manipulates the base module based on the noise modules for (int i = 0; i < noiseFunctions.Length; i++) { //for first valid noise pattern simply pass the noise function if (baseModule == null && noiseFunctions[i].enabled) { baseModule = noiseFunctions[i].moduleBase; } //all others valid add to the previous iteration of the baseModule else if (noiseFunctions[i].enabled) { baseModule = new Add(baseModule, noiseFunctions[i].moduleBase); } } //clamps the module to between 1 and 0 if (clamped) { baseModule = new Clamp(0, 1, baseModule); } noiseMap = new Noise2D(mapWidth, mapHeight, baseModule); #endregion #region Planet Generator if (mapType == MapType.Planet) { noiseMap.GenerateSpherical(-90, 90, -180, 180); Color[] colorMap = new Color[noiseMap.Width * noiseMap.Height]; textures[0] = new Texture2D(noiseMap.Width, noiseMap.Height); if (renderType == RenderType.Greyscale) { textures[0] = noiseMap.GetTexture(LibNoise.Unity.Gradient.Grayscale); } else { for (int y = 0; y < noiseMap.Height; y++) { for (int x = 0; x < noiseMap.Width; x++) { float currentHeight = noiseMap[x, y]; for (int i = 0; i < regions.Length; i++) { if (currentHeight <= regions[i].height) { colorMap[y * noiseMap.Width + x] = regions[i].color; break; } } } } textures[0].SetPixels(colorMap); } textures[0].Apply(); Mesh newMesh = SphereMagic.CreatePlanet(PlanetItterations, radius, baseModule, heightMultiplier, regions); display.DrawMesh(newMesh, textures[0]); } #endregion #region Flat Terrain else if (mapType == MapType.FlatTerrain) { display.TextureRender = FindObjectOfType <Renderer>(); textures[0] = noiseMap.GetTexture(LibNoise.Unity.Gradient.Grayscale); Color[] colorMap = new Color[noiseMap.Width * noiseMap.Height]; for (int y = 0; y < noiseMap.Height; y++) { for (int x = 0; x < noiseMap.Width; x++) { float currentHeight = noiseMap[x, y]; for (int i = 0; i < regions.Length; i++) { if (currentHeight <= regions[i].height) { colorMap[y * noiseMap.Width + x] = regions[i].color; break; } } } } textures[0].SetPixels(colorMap); textures[0].Apply(); display.DrawMesh(FlatMeshGenerator.GenerateTerrainMesh(noiseMap, heightMultiplier, heightAdjuster), textures[0]); } #endregion }
/// <summary> /// The Core Map Generation Method, in essence this method /// takes the stack of noise methods and processes them /// sequentially and generates a resultant noise map. /// It then calls a function to generate the Mesh (or 3D object) /// and applies the noise to the mesh inside of the function /// to draw the mesh. /// -RGS /// </summary> public void GenerateMap() { #region variables and setup //This function prevents the generation from happening if there is no noise stack to process. if ((noiseFunctions == null) || (noiseFunctions.Length < 1)) { noiseFunctions = new NoiseFunction[1]; noiseFunctions[0] = new NoiseFunction(); noiseFunctions[0].GetDefault(); } //this is the base noise module that will be manipulated baseModule = null; //this is the noisemap that will be generated noiseMap = null; ///next two commands interface with multithreaded renderer ///to shut it down if it's running. The bool adds a hard ///abort check that doesn't rely on the timestamp HaltThreads(); reset = true; //misc Setup MapDisplay display = FindObjectOfType <MapDisplay>(); #endregion #region Noise Map Initialization //Generates a random seed and passes it to the noise processor if (!useRandomSeed) { seedValue = seed.GetHashCode(); } else { seedValue = UnityEngine.Random.Range(0, 10000000); } baseModule = NoiseProcessor.InitNoise(noiseFunctions, seedValue); //This clamps the module to between 1 and 0, sort of... //because of the way coherent noise works, it's not possible to completely //eliminate the possibility that a value will fall outside these ranges. if (clamped) { baseModule = new Clamp(0, 1, baseModule); } noiseMap = new Noise2D(mapWidth, mapHeight, baseModule); #endregion #region Planet Generator Setup if (mapType == MapType.Planet) { mapHeight = mapWidth / 2; renderType = RenderType.Color; if ((oceans) && (!waterMesh.activeSelf)) { waterMesh.SetActive(true); } if (waterMesh != null) { waterMesh.transform.localScale = 2 * (new Vector3(radius + seaLevelOffset, radius + seaLevelOffset, radius + seaLevelOffset)); if (!oceans) { waterMesh.SetActive(false); } } } #endregion #region Flat Terrain Generator //non functional else if (mapType == MapType.FlatTerrain) { noiseMap = new Noise2D(100, 100, baseModule); noiseMap.GeneratePlanar(-1, 1, -1, 1, seamless); display.TextureRender = FindObjectOfType <Renderer>(); mapTexture = GetMapTexture(renderType, noiseMap); display.DrawMesh(FlatMeshGenerator.GenerateTerrainMesh(noiseMap, heightMultiplier, heightAdjuster), mapTexture); } #endregion #region Start Multithreaded Noisemapping if (multithreading) { ThreadMap(); } #endregion }
////////////////////////////////////////////////////////////////////////////// // // //Unity Functions // // // ////////////////////////////////////////////////////////////////////////////// void Start() { Mesh origianlMesh = null; //Get original mesh from MeshFilter or SkinnedMeshRenderer MeshFilter meshFilter = GetComponent <MeshFilter>(); SkinnedMeshRenderer skinnedMeshRenderer = GetComponent <SkinnedMeshRenderer>(); if (meshFilter != null) { origianlMesh = meshFilter.sharedMesh; } if (origianlMesh == null && skinnedMeshRenderer != null) { origianlMesh = skinnedMeshRenderer.sharedMesh; } //Oops, no mesh found if (origianlMesh == null) { return; } //Will contain bake results Mesh newMesh = null; //Will contain baking reports, will help if something goes wrong FlatMeshGenerator.CONVERTION_INFO[] convertionInfo; //Same as above but with more detail info string[] convertionInfoString; //Generating flat mesh newMesh = FlatMeshGenerator.GenerateFlatMesh(GetComponent <Renderer>(), out convertionInfo, out convertionInfoString, flatOptions); //Check reports if (convertionInfoString != null) { for (int i = 0; i < convertionInfoString.Length; i++) { Debug.Log(convertionInfoString[i]); } } //Successful conversation if (newMesh != null) { //Replace old mesh with new one if (meshFilter != null) { meshFilter.sharedMesh = newMesh; } else if (skinnedMeshRenderer != null) { skinnedMeshRenderer.sharedMesh = newMesh; } //Replace material to make baked data visible GetComponent <Renderer>().sharedMaterials = new Material[] { vertexColorMaterial }; } }
/// <summary> /// The Core Map Generation Method, in essence this method /// takes the stack of noise methods and processes them /// sequentially and generates a resultant noise map. /// It then calls a function to generate the Mesh (or 3D object) /// and applies the noise to the mesh inside of the function /// to draw the mesh. /// /// Also in this located in this region is the map texture generator, /// which actually makes up a signifigant bulk of the computational /// cost of most map generation schemas I've found useful. /// -RGS /// </summary> public void GenerateMap() { //MFU Need to work on the hiearchy / code reduction //in this method in particular. //MFU After reorganization add easier initial generation //calls with different types of arguments (files / settings mixtures). #region variables and setup //autoUpdate saftey catch disabled after implementing multithreading, may be added again if this is pulled back out. //if (autoUpdate && (mapWidth > 400 || mapHeight > 200)) //{ // mapWidth = 400; // mapHeight = 200; // Debug.Log("Texture resolution reduced to 400x200 max during Auto Update!"); //} //this is the base noise module that will be manipulated baseModule = null; //this is the noisemap that will be generated noiseMap = null; //next two commands interface with multithreaded renderer HaltThreads(); reset = true; MapDisplay display = FindObjectOfType <MapDisplay>(); if (!useRandomSeed) { seedValue = seed.GetHashCode(); } else { seedValue = UnityEngine.Random.Range(0, 10000000); } #endregion #region Noise Function Setup for (int i = 0; i < noiseFunctions.Length; i++) { noiseFunctions[i].seed = seedValue + i; noiseFunctions[i].MakeNoise(); //for first valid noise pattern simply pass the noise function if (baseModule == null && noiseFunctions[i].enabled) { baseModule = noiseFunctions[i].moduleBase; } //all others valid add to the previous iteration of the baseModule else if (noiseFunctions[i].enabled) { //this is where I want to do blend mode adjustments using //libNoise add, blend, subtract, multiply etc as an effect (along with falloffs maybe) baseModule = new Add(baseModule, noiseFunctions[i].moduleBase); } } //clamps the module to between 1 and 0, sort of... //because of the way coherent noise works, it's not possible to completely //eliminate the possibility that a value will fall outside these ranges. if (clamped) { baseModule = new Clamp(0, 1, baseModule); } noiseMap = new Noise2D(mapWidth, mapHeight, baseModule); #endregion #region Planet Generator if (mapType == MapType.Planet) { mapHeight = mapWidth / 2; renderType = RenderType.Color; noiseMap = new Noise2D(100, 100, baseModule); noiseMap.GenerateSpherical(-90, 90, -180, 180); mapTexture = GetMapTexture(renderType, noiseMap); if ((oceans) && (!waterMesh.activeSelf)) { waterMesh.SetActive(true); } if (waterMesh != null) { //MFU better Sea Level Autoupdate / switch waterMesh.transform.localScale = 2 * (new Vector3(radius + seaLevelOffset, radius + seaLevelOffset, radius + seaLevelOffset)); if (!oceans) { waterMesh.SetActive(false); } } display.DrawMesh(SphereMagic.CreatePlanet(PlanetItterations, radius, baseModule, heightMultiplier, regions), mapTexture); } #endregion #region Flat Terrain Generator //non functional else if (mapType == MapType.FlatTerrain) { noiseMap = new Noise2D(100, 100, baseModule); noiseMap.GeneratePlanar(-1, 1, -1, 1, seamless); display.TextureRender = FindObjectOfType <Renderer>(); mapTexture = GetMapTexture(renderType, noiseMap); display.DrawMesh(FlatMeshGenerator.GenerateTerrainMesh(noiseMap, heightMultiplier, heightAdjuster), mapTexture); } #endregion #region Start Multithreaded Noisemapping if (drawInProgress) { HaltThreads(); } latestTimeProcessRequested = DateTime.Now.GetHashCode(); drawInProgress = true; stop = false; StartCoroutine(TextureRefiner()); #endregion }