void ExportMask(float[] data, int size, int resolution, string name, DateTime stamp, float spread, bool isClip, bool isReadable) { //Create interpolated array from data so the mask resolution does not need to match the terrain height map size. InterpolatedArray2f heightMap = new InterpolatedArray2f(data, size, size, 1, false); //Create the path name to save mask. string fileName = string.Format("{0}-{1:yyyyMMdd-HHmmss}.png", name, stamp); string path = System.IO.Path.Combine(Application.dataPath, fileName); path = path.Replace('\\', '/'); Texture2D mask = null; //Create the mask texture. Clip masks are created slightly different. if (isClip) { mask = ShoreMaskGenerator.CreateClipMask(heightMap, resolution, resolution, m_oceanLevel + spread, TextureFormat.ARGB32); } else { mask = ShoreMaskGenerator.CreateMask(heightMap, resolution, resolution, m_oceanLevel, spread, TextureFormat.ARGB32); } //Save the texture. byte[] bytes = mask.EncodeToPNG(); System.IO.File.WriteAllBytes(path, bytes); DestroyImmediate(mask); string relativePath = "Assets/" + fileName; //Update asset data base with new mask texture. AssetDatabase.ImportAsset(relativePath, ImportAssetOptions.ForceUpdate); //Create a importer from the texture so some of its settings can be changed. AssetImporter tmp = TextureImporter.GetAtPath(relativePath); TextureImporter importer = tmp as TextureImporter; if (importer != null) { //Change some of the settings of textures. //Should always be bilinear clamped with no mipmaps. //Height and clip masks should also be readable. importer.wrapMode = TextureWrapMode.Clamp; importer.filterMode = FilterMode.Bilinear; importer.textureType = TextureImporterType.Default; importer.mipmapEnabled = false; importer.isReadable = isReadable; AssetDatabase.ImportAsset(relativePath, ImportAssetOptions.ForceUpdate); } else { string msg = string.Format("{0:MM/dd/yy H:mm:ss zzz} - Failed to modify texture settings after creation. You will need to manually adjust texture settings.", DateTime.Now); Ocean.LogInfo(msg); } }
private void CreateShoreMasks() { this.Release(); Terrain component = base.GetComponent<Terrain>(); if (component == null) { Ocean.LogWarning("The AddAutoShoreMask script must be attached to a component with a Terrain. The shore mask will not be created."); base.enabled = false; return; } if (component.terrainData == null) { Ocean.LogWarning("The terrain data is null. The shore mask will not be created."); base.enabled = false; return; } Vector3 size = component.terrainData.size; this.resolution = Mathf.Clamp(this.resolution, 32, 4096); this.m_width = size.x; this.m_height = size.z; float level = Ocean.Instance.level; float[] data = ShoreMaskGenerator.CreateHeightMap(component); int heightmapResolution = component.terrainData.heightmapResolution; InterpolatedArray2f heightMap = new InterpolatedArray2f(data, heightmapResolution, heightmapResolution, 1, false); if (this.useHeightMask || this.useNormalMask || this.useFoamMask) { this.m_heightMask = ShoreMaskGenerator.CreateMask(heightMap, this.resolution, this.resolution, level, this.heightSpread, TextureFormat.ARGB32); } if (this.useEdgeFoam) { this.m_edgeFoam = ShoreMaskGenerator.CreateMask(heightMap, this.resolution, this.resolution, level, this.foamSpread, TextureFormat.ARGB32); } if (this.useClipMask) { this.m_clipMask = ShoreMaskGenerator.CreateClipMask(heightMap, this.resolution, this.resolution, level + this.clipOffset, TextureFormat.ARGB32); } if (this.useHeightMask) { this.m_overlays[0].HeightTex.mask = this.m_heightMask; } if (this.useNormalMask) { this.m_overlays[0].NormalTex.mask = this.m_heightMask; } if (this.useFoamMask) { this.m_overlays[0].FoamTex.mask = this.m_heightMask; } if (this.useEdgeFoam) { this.m_overlays[0].FoamTex.tex = this.m_edgeFoam; } if (this.useClipMask) { this.m_overlays[0].ClipTex.tex = this.m_clipMask; } if (!this.m_registered) { Ocean.Instance.OverlayManager.Add(this.m_overlays[0]); this.m_registered = true; } this.m_heightSpread = this.heightSpread; this.m_foamSpread = this.foamSpread; this.m_clipOffset = this.clipOffset; this.m_resolution = (float)this.resolution; }
void CreateShoreMasks() { Terrain terrain; GameObject obj = Selection.activeGameObject; //If obj is null user has not selected a object. if (obj == null) { string msg = string.Format("{0:MM/dd/yy H:mm:ss zzz} - No object was selected. Please select the terrain in the scene. The shore mask will not be created.", DateTime.Now); Ocean.LogInfo(msg); return; } terrain = obj.GetComponent <Terrain>(); //If terrain is null user has not selected a object with a terrain component. if (terrain == null) { string msg = string.Format("{0:MM/dd/yy H:mm:ss zzz} - Selected object was not a terrain. The shore mask will not be created.", DateTime.Now); Ocean.LogInfo(msg); return; } //If terrain data is null user has deleted the data at some point. if (terrain.terrainData == null) { string msg = string.Format("{0:MM/dd/yy H:mm:ss zzz} - Terrains data is null. The shore mask will not be created.", DateTime.Now); Ocean.LogInfo(msg); return; } DateTime time = DateTime.Now; //Get the height map data from the terrain. float[] data = ShoreMaskGenerator.CreateHeightMap(terrain); int resolution = terrain.terrainData.heightmapResolution; //Export each of the masks if required. if (m_exportHeightMask) { ExportMask(data, resolution, m_heightMaskResolution, terrain.name + "-HeightMask", time, m_heightMaskSpread, false, true); } if (m_exportEdgeFoam) { ExportMask(data, resolution, m_edgeFoamResolution, terrain.name + "-EdgeFoam", time, m_edgeFoamSpread, false, false); } if (m_exportFoamMask) { ExportMask(data, resolution, m_foamMaskResolution, terrain.name + "-FoamMask", time, m_foamMaskSpread, false, false); } if (m_exportNormalMask) { ExportMask(data, resolution, m_normalMaskResolution, terrain.name + "-NormalMask", time, m_normalMaskSpread, false, false); } if (m_exportClipMask) { ExportMask(data, resolution, m_clipMaskResolution, terrain.name + "-ClipMask", time, m_clipMaskOffset, true, true); } }
void CreateShoreMasks() { //float t = Time.realtimeSinceStartup; Release(); Terrain terrain = GetComponent <Terrain>(); if (terrain == null) { //If there gameobject has not terrain print a warning and return. //Do this rather than have a terrain as a required component as it would be //rather annoying for the script to create a terrain if added to wrong gameobject. Ocean.LogWarning("The AddAutoShoreMask script must be attached to a component with a Terrain. The shore mask will not be created."); enabled = false; return; } if (terrain.terrainData == null) { //This can happen if the terrain data in asset folder is deleted Ocean.LogWarning("The terrain data is null. The shore mask will not be created."); enabled = false; return; } Vector3 size = terrain.terrainData.size; resolution = Mathf.Clamp(resolution, 32, 4096); m_width = size.x; m_height = size.z; float level = Ocean.Instance.level; float[] data = ShoreMaskGenerator.CreateHeightMap(terrain); int actualResolution = terrain.terrainData.heightmapResolution; InterpolatedArray2f heightMap = new InterpolatedArray2f(data, actualResolution, actualResolution, 1, false); if (useHeightMask || useNormalMask || useFoamMask) { m_heightMask = ShoreMaskGenerator.CreateMask(heightMap, resolution, resolution, level, heightSpread, TextureFormat.ARGB32); } if (useEdgeFoam) { m_edgeFoam = ShoreMaskGenerator.CreateMask(heightMap, resolution, resolution, level, foamSpread, TextureFormat.ARGB32); } if (useClipMask) { m_clipMask = ShoreMaskGenerator.CreateClipMask(heightMap, resolution, resolution, level + clipOffset, TextureFormat.ARGB32); } if (useHeightMask) { m_overlays[0].HeightTex.mask = m_heightMask; } if (useNormalMask) { m_overlays[0].NormalTex.mask = m_heightMask; } if (useFoamMask) { m_overlays[0].FoamTex.mask = m_heightMask; } if (useEdgeFoam) { m_overlays[0].FoamTex.tex = m_edgeFoam; } if (useClipMask) { m_overlays[0].ClipTex.tex = m_clipMask; } if (!m_registered) { Ocean.Instance.OverlayManager.Add(m_overlays[0]); m_registered = true; } m_heightSpread = heightSpread; m_foamSpread = foamSpread; m_clipOffset = clipOffset; m_resolution = resolution; //Debug.Log("Shore mask creation time = " + (Time.realtimeSinceStartup - t) * 1000.0f); }