private void CancelConvert() { phase = MeshToTerrainPhase.idle; if (container != null) { DestroyImmediate(container); } Dispose(); }
private void Prepare() { activeIndex = 0; checkedTexures = new List <Texture2D>(); colors = null; heightmap = null; progress = 0; terrainObjects = new List <MeshToTerrainObject>(); if (prefs.terrainType != MeshToTerrainSelectTerrainType.newTerrains) { prefs.adjustMeshSize = false; } GetResultFolder(); if (!CheckValues()) { Dispose(); phase = MeshToTerrainPhase.idle; return; } if (prefs.adjustMeshSize) { meshContainer = new GameObject("__Mesh Container__"); meshContainer.transform.position = minBounds; } PrepareMeshes(terrainObjects); if (prefs.adjustMeshSize) { float sx = prefs.heightmapResolution * prefs.newTerrainCountX / boundsRange.x; float sz = prefs.heightmapResolution * prefs.newTerrainCountY / boundsRange.z; meshScale = new Vector3(sx, (sx + sz) / 2, sz); meshContainer.transform.localScale = meshScale; boundsRange.Scale(meshScale); maxBounds = minBounds + boundsRange; } if (prefs.terrainType == MeshToTerrainSelectTerrainType.newTerrains) { phase = MeshToTerrainPhase.createTerrains; } else { phase = MeshToTerrainPhase.generateHeightmaps; } }
private void CreateTerrain(int terrainIndex) { int x = terrainIndex % prefs.newTerrainCountX; int y = terrainIndex / prefs.newTerrainCountX; float w = boundsRange.x; float h = boundsRange.z; float sW = w / prefs.newTerrainCountX; float sH = h / prefs.newTerrainCountY; float sY = boundsRange.y * 1.5f; float offX = (w - sW * prefs.newTerrainCountX) / 2; float offY = (h - sH * prefs.newTerrainCountY) / 2; string terrainName = string.Format("Terrain {0}x{1}", x, y); GameObject terrainGO = CreateTerrainGameObject(sW, sY, sH, terrainName); terrainGO.name = terrainName; terrainGO.transform.parent = container.transform; terrainGO.transform.localPosition = new Vector3(x * sW + offX, 0, y * sH + offY); prefs.terrains.Add(terrainGO.GetComponent <Terrain>()); activeIndex++; progress = activeIndex / (float)(prefs.newTerrainCountX * prefs.newTerrainCountY); if (activeIndex >= prefs.newTerrainCountX * prefs.newTerrainCountY) { if (prefs.terrains.Count > 1) { for (int i = 0; i < prefs.terrains.Count; i++) { SetTerrainNeighbors(i); } } activeIndex = 0; progress = 0; phase = MeshToTerrainPhase.generateHeightmaps; } }
private void Finish() { #if RTP if (prefs.generateTextures) { ReliefTerrain reliefTerrain = prefs.terrains[0].GetComponent <ReliefTerrain>(); ReliefTerrainGlobalSettingsHolder settingsHolder = reliefTerrain.globalSettingsHolder; settingsHolder.numLayers = 4; settingsHolder.splats = new Texture2D[4]; settingsHolder.Bumps = new Texture2D[4]; settingsHolder.Heights = new Texture2D[4]; for (int i = 0; i < 4; i++) { settingsHolder.splats[i] = rtpTextures[i * 3]; settingsHolder.Heights[i] = rtpTextures[i * 3 + 1]; settingsHolder.Bumps[i] = rtpTextures[i * 3 + 2]; } settingsHolder.GlobalColorMapBlendValues = new Vector3(1, 1, 1); settingsHolder._GlobalColorMapNearMIP = 1; settingsHolder.GlobalColorMapSaturation = 1; settingsHolder.GlobalColorMapSaturationFar = 1; settingsHolder.GlobalColorMapBrightness = 1; settingsHolder.GlobalColorMapBrightnessFar = 1; foreach (Terrain item in prefs.terrains) { item.GetComponent <ReliefTerrain>().RefreshTextures(); } settingsHolder.Refresh(); } #endif if (prefs.adjustMeshSize) { float w = originalBoundsRange.x; float h = originalBoundsRange.z; float sW = w / prefs.newTerrainCountX; float sH = h / prefs.newTerrainCountY; float sY = originalBoundsRange.y * 1.5f; float tsw = sW; float tsh = sH; if (prefs.textureCaptureMode == MeshToTerrainTextureCaptureMode.camera) { tsw = tsw / prefs.textureResolution * (prefs.textureResolution + 4); tsh = tsh / prefs.textureResolution * (prefs.textureResolution + 4); } else { tsw = tsw / prefs.textureWidth * (prefs.textureWidth + 2); tsh = tsh / prefs.textureHeight * (prefs.textureHeight + 2); } float offX = (w - sW * prefs.newTerrainCountX) / 2; float offY = (h - sH * prefs.newTerrainCountY) / 2; for (int x = 0; x < prefs.newTerrainCountX; x++) { for (int y = 0; y < prefs.newTerrainCountY; y++) { Terrain t = prefs.terrains[y * prefs.newTerrainCountX + x]; t.transform.localPosition = new Vector3(x * sW + offX, 0, y * sH + offY); t.terrainData.size = new Vector3(sW, sY, sH); #if !RTP if (prefs.generateTextures) { #if UNITY_2018_3_OR_NEWER TerrainLayer[] terrainLayers = t.terrainData.terrainLayers; TerrainLayer item = terrainLayers[0]; #else SplatPrototype[] splatPrototypes = t.terrainData.splatPrototypes; SplatPrototype item = splatPrototypes[0]; #endif item.tileSize = new Vector2(tsw, tsh); if (prefs.textureCaptureMode == MeshToTerrainTextureCaptureMode.camera) { item.tileOffset = new Vector2(t.terrainData.size.x / prefs.textureResolution / 1.5f, t.terrainData.size.z / prefs.textureResolution / 1.5f); } else { item.tileOffset = new Vector2(t.terrainData.size.x / prefs.textureWidth / 1.5f, t.terrainData.size.z / prefs.textureHeight / 1.5f); } #if UNITY_2018_3_OR_NEWER t.terrainData.terrainLayers = terrainLayers; #else t.terrainData.splatPrototypes = splatPrototypes; #endif } #endif } } } if (prefs.terrainType == MeshToTerrainSelectTerrainType.newTerrains) { EditorGUIUtility.PingObject(container); } else { foreach (Terrain t in prefs.terrains) { EditorGUIUtility.PingObject(t.gameObject); } } Dispose(); phase = MeshToTerrainPhase.idle; }
private void UpdateTextureRaycast(Terrain t) { int mLayer = 1 << prefs.meshLayer; float raycastDistance = maxBounds.y - minBounds.y + 10; Vector3 vScale = t.terrainData.size; Vector3 beginPoint = t.transform.position; Vector3 raycastDirection = -Vector3.up; if (prefs.direction == MeshToTerrainDirection.normal) { beginPoint.y += raycastDistance; } else { beginPoint.y = maxBounds.y - raycastDistance; raycastDirection = Vector3.up; } float tsx = prefs.textureWidth + 1; float tsy = prefs.textureHeight + 1; vScale.x = vScale.x / tsx; vScale.z = vScale.z / tsy; beginPoint += new Vector3(vScale.x / 2, 0, vScale.z / 2); Renderer lastRenderer = null; Vector2[] uv = null; int[] triangles = null; Vector3[] verticles = null; if (colors == null) { colors = new Color[prefs.textureWidth * prefs.textureHeight]; lastX = 0; } long startTicks = DateTime.Now.Ticks; for (int tx = lastX; tx < prefs.textureWidth; tx++) { for (int ty = 0; ty < prefs.textureHeight; ty++) { int cPos = ty * prefs.textureWidth + tx; Vector3 curPoint = beginPoint + new Vector3(tx * vScale.x, 0, ty * vScale.z); colors[cPos] = GetColor(curPoint, raycastDistance, raycastDirection, mLayer, ref lastRenderer, ref triangles, ref verticles, ref uv); } if (new TimeSpan(DateTime.Now.Ticks - startTicks).TotalSeconds >= 1) { lastX = tx; progress = (activeIndex + lastX / (float)prefs.textureWidth) / prefs.terrains.Count; return; } } lastX = 0; SetTexturesToTerrain(t); colors = null; EditorUtility.UnloadUnusedAssetsImmediate(); GC.Collect(); activeIndex++; progress = activeIndex / (float)prefs.terrains.Count; if (activeIndex >= prefs.terrains.Count) { activeIndex = 0; phase = MeshToTerrainPhase.finish; } }
private void UpdateTextureCamera(Terrain t) { int mLayer = 1 << prefs.meshLayer; float raycastDistance = maxBounds.y - minBounds.y + 10; Vector3 vScale = t.terrainData.size; float tsx = prefs.textureResolution + 1; float tsy = prefs.textureResolution + 1; vScale.x = vScale.x / tsx; vScale.z = vScale.z / tsy; Vector3 beginPoint = t.transform.position; if (prefs.direction == MeshToTerrainDirection.normal) { beginPoint.y += raycastDistance; } else { beginPoint.y = maxBounds.y - raycastDistance; } Vector3 curPoint = beginPoint + new Vector3(prefs.textureResolution / 2 * vScale.x, 0, prefs.textureResolution / 2 * vScale.z); GameObject cameraGO = new GameObject("__Mesh to Terrain Camera__"); Camera camera = cameraGO.AddComponent <Camera>(); cameraGO.transform.position = curPoint; cameraGO.transform.rotation = Quaternion.Euler(prefs.direction == MeshToTerrainDirection.normal? 90: -90, 0, 0); camera.orthographic = true; camera.orthographicSize = boundsRange.x / 2 / prefs.newTerrainCountX; camera.clearFlags = CameraClearFlags.Color; camera.backgroundColor = prefs.textureEmptyColor; camera.cullingMask = mLayer; camera.targetTexture = new RenderTexture(prefs.textureResolution, prefs.textureResolution, 16); RenderTexture currentRT = RenderTexture.active; RenderTexture.active = camera.targetTexture; camera.Render(); Texture2D texture = new Texture2D(prefs.textureResolution, prefs.textureResolution); texture.ReadPixels(new Rect(0, 0, prefs.textureResolution, prefs.textureResolution), 0, 0); texture.Apply(); RenderTexture.active = currentRT; string textureFilename = Path.Combine(resultFolder, t.name + ".png"); File.WriteAllBytes(textureFilename, texture.EncodeToPNG()); AssetDatabase.Refresh(); TextureImporter importer = AssetImporter.GetAtPath(textureFilename) as TextureImporter; if (importer != null) { importer.maxTextureSize = Mathf.Max(prefs.textureWidth, prefs.textureHeight); importer.wrapMode = TextureWrapMode.Clamp; AssetDatabase.ImportAsset(textureFilename, ImportAssetOptions.ForceUpdate); } texture = (Texture2D)AssetDatabase.LoadAssetAtPath(textureFilename, typeof(Texture2D)); DestroyImmediate(cameraGO); #if !RTP Vector2 tileSize = new Vector2( t.terrainData.size.x / prefs.textureResolution * (prefs.textureResolution + 2), t.terrainData.size.z / prefs.textureResolution * (prefs.textureResolution + 2)); Vector2 tileOffset = new Vector2( t.terrainData.size.x / prefs.textureResolution / 2, t.terrainData.size.z / prefs.textureResolution / 2); #if UNITY_2018_3_OR_NEWER TerrainLayer l = new TerrainLayer { tileSize = tileSize, tileOffset = tileOffset, diffuseTexture = texture }; string layerPath = Path.Combine(resultFolder, t.name + ".terrainlayer"); AssetDatabase.CreateAsset(l, layerPath); AssetDatabase.Refresh(); t.terrainData.terrainLayers = new[] { AssetDatabase.LoadAssetAtPath <TerrainLayer>(layerPath) }; #else SplatPrototype sp = new SplatPrototype { tileSize = tileSize, tileOffset = tileOffset, texture = texture }; t.terrainData.splatPrototypes = new[] { sp }; #endif #else LoadRTPTextures(); #if UNITY_2018_3_OR_NEWER TerrainLayer[] ls = new TerrainLayer[4]; for (int i = 0; i < 4; i++) { TerrainLayer l = ls[i] = new TerrainLayer { diffuseTexture = rtpTextures[i * 3] }; string layerPath = Path.Combine(resultFolder, t.name + " " + i + ".terrainlayer"); AssetDatabase.CreateAsset(l, layerPath); AssetDatabase.Refresh(); ls[i] = AssetDatabase.LoadAssetAtPath <TerrainLayer>(layerPath); } t.terrainData.terrainLayers = ls; #else SplatPrototype[] sps = new SplatPrototype[4]; for (int i = 0; i < 4; i++) { sps[i] = new SplatPrototype { texture = rtpTextures[i * 3] }; } t.terrainData.splatPrototypes = sps; #endif ReliefTerrain reliefTerrain = t.gameObject.GetComponent <ReliefTerrain>() ?? t.gameObject.AddComponent <ReliefTerrain>(); reliefTerrain.InitArrays(); reliefTerrain.ColorGlobal = texture; #endif activeIndex++; progress = activeIndex / (float)prefs.terrains.Count; if (activeIndex >= prefs.terrains.Count) { activeIndex = 0; phase = MeshToTerrainPhase.finish; } }
private void UpdateTerrain(Terrain t) { int mLayer = 1 << prefs.meshLayer; float raycastDistance = (maxBounds.y - minBounds.y) * 1.5f; Vector3 vScale = t.terrainData.heightmapScale; Vector3 beginPoint = t.transform.position; Vector3 raycastDirection = Vector3.down; if (prefs.direction == MeshToTerrainDirection.normal) { beginPoint.y += raycastDistance; } else { beginPoint.y = maxBounds.y - raycastDistance; raycastDirection = Vector3.up; } if (heightmap == null) { heightmap = new float[t.terrainData.heightmapWidth, t.terrainData.heightmapHeight]; lastX = 0; } long startTicks = DateTime.Now.Ticks; float nodataValue = prefs.holes == MeshToTerrainHoles.minimumValue? 0: float.MinValue; for (int tx = lastX; tx < t.terrainData.heightmapWidth; tx++) { for (int ty = 0; ty < t.terrainData.heightmapHeight; ty++) { Vector3 curPoint = beginPoint + new Vector3(tx * vScale.x, 0, ty * vScale.z); RaycastHit hit; if (Physics.Raycast(curPoint, raycastDirection, out hit, raycastDistance, mLayer)) { if (prefs.direction == MeshToTerrainDirection.normal) { float v = (raycastDistance - hit.distance) / vScale.y; heightmap[ty, tx] = v; } else { heightmap[ty, tx] = hit.distance / vScale.y; } } else { heightmap[ty, tx] = nodataValue; } } if (new TimeSpan(DateTime.Now.Ticks - startTicks).TotalSeconds >= 1) { lastX = tx; progress = (activeIndex + lastX / (float)t.terrainData.heightmapWidth) / prefs.terrains.Count; return; } } lastX = 0; if (prefs.holes == MeshToTerrainHoles.neighborAverage) { AverageFillHoles(); } if (prefs.useHeightmapSmoothing) { SmoothHeightmap(); } t.terrainData.SetHeights(0, 0, heightmap); t.Flush(); heightmap = null; lastTransform = null; lastMesh = null; lastTriangles = null; lastVerticles = null; activeIndex++; progress = activeIndex / (float)prefs.terrains.Count; if (activeIndex >= prefs.terrains.Count) { activeIndex = 0; progress = 0; phase = prefs.generateTextures ? MeshToTerrainPhase.generateTextures : MeshToTerrainPhase.finish; } }
private void UpdateTextureCamera(Terrain t) { int mLayer = 1 << prefs.meshLayer; float raycastDistance = maxBounds.y - minBounds.y + 10; Vector3 vScale = t.terrainData.size; float tsx = prefs.textureResolution + 1; float tsy = prefs.textureResolution + 1; vScale.x = vScale.x / tsx; vScale.z = vScale.z / tsy; Vector3 beginPoint = t.transform.position; if (prefs.direction == MeshToTerrainDirection.normal) { beginPoint.y += raycastDistance; } else { beginPoint.y = maxBounds.y - raycastDistance; } Vector3 curPoint = beginPoint + new Vector3(prefs.textureResolution / 2 * vScale.x, 0, prefs.textureResolution / 2 * vScale.z); GameObject cameraGO = new GameObject("__Mesh to Terrain Camera__"); Camera camera = cameraGO.AddComponent <Camera>(); cameraGO.transform.position = curPoint; cameraGO.transform.rotation = Quaternion.Euler(prefs.direction == MeshToTerrainDirection.normal? 90: -90, 0, 0); camera.orthographic = true; camera.orthographicSize = boundsRange.x / 2 / prefs.newTerrainCountX; camera.clearFlags = CameraClearFlags.Color; camera.backgroundColor = prefs.textureEmptyColor; camera.cullingMask = mLayer; camera.targetTexture = new RenderTexture(prefs.textureResolution, prefs.textureResolution, 16); RenderTexture currentRT = RenderTexture.active; RenderTexture.active = camera.targetTexture; camera.Render(); Texture2D texture = new Texture2D(prefs.textureResolution, prefs.textureResolution); texture.ReadPixels(new Rect(0, 0, prefs.textureResolution, prefs.textureResolution), 0, 0); texture.Apply(); RenderTexture.active = currentRT; string textureFilename = Path.Combine(resultFolder, t.name + ".png"); File.WriteAllBytes(textureFilename, texture.EncodeToPNG()); AssetDatabase.Refresh(); TextureImporter importer = AssetImporter.GetAtPath(textureFilename) as TextureImporter; if (importer != null) { importer.maxTextureSize = Mathf.Max(prefs.textureWidth, prefs.textureHeight); importer.wrapMode = TextureWrapMode.Clamp; AssetDatabase.ImportAsset(textureFilename, ImportAssetOptions.ForceUpdate); } texture = (Texture2D)AssetDatabase.LoadAssetAtPath(textureFilename, typeof(Texture2D)); DestroyImmediate(cameraGO); SetTexturesToTerrain(t, texture); activeIndex++; progress = activeIndex / (float)prefs.terrains.Count; if (activeIndex >= prefs.terrains.Count) { activeIndex = 0; phase = MeshToTerrainPhase.finish; } }