// Functional constructor 1 public RoseMap(DirectoryInfo assetDir) { this.m_assetDir = assetDir; m_name = assetDir.Name; foreach(DirectoryInfo dir in assetDir.GetDirectories()) { RosePatch patch = new RosePatch(dir); if(patch.m_isValid) m_patches.Add (patch); } }
// Functional constructor 1 public RoseMap(DirectoryInfo assetDir) { this.m_assetDir = assetDir; m_name = assetDir.Name; foreach (DirectoryInfo dir in assetDir.GetDirectories()) { RosePatch patch = new RosePatch(dir); if (patch.m_isValid) { m_patches.Add(patch); } } }
private void ImportMap(string mapName) { Debug.Log ("Importing map from " + m_inputDir + "..."); bool success = true; DirectoryInfo dirs = new DirectoryInfo(m_inputDir); GameObject map = new GameObject(); map.name = mapName; GameObject terrain = new GameObject(); terrain.name = "Ground"; terrain.transform.parent = map.transform; terrain.layer = LayerMask.NameToLayer("Floor"); GameObject terrainObjects = new GameObject(); terrainObjects.name = "Objects"; terrainObjects.transform.parent = map.transform; terrainObjects.layer = LayerMask.NameToLayer("MapObjects"); List<RosePatch> patches = new List<RosePatch>(); Dictionary<string, Rect> atlasRectHash = new Dictionary<string, Rect>(); Dictionary<string, Texture2D> atlasTexHash = new Dictionary< string, Texture2D >(); List<Texture2D> textures = new List<Texture2D>(); // Instantiate all patches foreach(DirectoryInfo dir in dirs.GetDirectories()) { if(!dir.Name.Contains(".")) { RosePatch patch = new RosePatch( dir ); patch.Load(); patch.UpdateAtlas( ref atlasRectHash, ref atlasTexHash, ref textures ); patches.Add ( patch ); } } // Create a texture atlas from the textures of all patches and populate the rectangles in the hash // Figure out the required size of the atlas from the number of textures in the atlas int height, width; // these must be powers of 2 to be compatible with iPhone if( atlasRectHash.Count <= 16 ) width = height = 4*256; else if( atlasRectHash.Count <= 32 ) { width = 8*256; height = 4*256; } else if( atlasRectHash.Count <= 64 ) { width = 8*256; height = 8*256; } else if( atlasRectHash.Count <= 128 ) { width = 16*256; height = 8*256; } else if( atlasRectHash.Count <= 256 ) { width = 16*256; height = 16*256; } else throw new Exception("Number of tiles in terrain is larger than supported by terrain atlas"); Texture2D atlas = new Texture2D(width, height); // Pack the textures into one texture atlas Rect[] rects = atlas.PackTextures( textures.ToArray(), 0, Math.Max(width, height) ); atlas.anisoLevel = 11; Texture2D myAtlas = new Texture2D(width, height); myAtlas.SetPixels32( atlas.GetPixels32(0), 0); string atlasPath = "Assets/Terrain/Textures/" + mapName + "_atlas.png"; if( !File.Exists( atlasPath )) { FileStream fs = new FileStream( atlasPath, FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); bw.Write(myAtlas.EncodeToPNG()); bw.Close(); fs.Close(); AssetDatabase.Refresh(); } myAtlas = Utils.loadTex(ref atlasPath); // copy rects back to hash (should update rect refs in Tile objects int rectID = 0; foreach( string key in atlasTexHash.Keys) atlasRectHash[key] = rects[rectID++]; // Generate the patches foreach(RosePatch patch in patches) patch.Import(terrain.transform, terrainObjects.transform, myAtlas, myAtlas, atlasRectHash); //blend vertex normals at the seams between patches Dictionary<string, List<PatchNormalIndex>> patchNormalLookup = new Dictionary<string, List<PatchNormalIndex>>(); int patchID = 0; // combine all normal lookups into one big lookup containing patch ID and normal ID foreach(RosePatch patch in patches) { // go through the lookup of this patch and append all normal id's to big lookup foreach(string vertex in patch.edgeVertexLookup.Keys) { List<PatchNormalIndex> ids = new List<PatchNormalIndex>(); foreach(int id in patch.edgeVertexLookup[vertex]) ids.Add(new PatchNormalIndex(patchID, id)); if(!patchNormalLookup.ContainsKey(vertex)) patchNormalLookup.Add(vertex, ids); else patchNormalLookup[vertex].AddRange(ids); } patchID++; } // go through each enttry in the big lookup and calculate avg normal, then assign to corresponding patches foreach(string vertex in patchNormalLookup.Keys) { Vector3 avg = Vector3.zero; // First pass: calculate average normal foreach(PatchNormalIndex entry in patchNormalLookup[vertex]) avg += patches[entry.patchID].m_mesh.normals[entry.normalID]; avg.Normalize(); // Second pass: assign new normal to corresponding patches foreach(PatchNormalIndex entry in patchNormalLookup[vertex]) patches[entry.patchID].m_mesh.normals[entry.normalID] = avg; } terrainObjects.transform.localScale = new Vector3(1.0f, 1.0f, -1.0f); terrainObjects.transform.Rotate (0.0f, -90.0f, 0.0f); terrainObjects.transform.position = new Vector3(5200.0f, 0.0f, 5200.0f); if(success) Debug.Log ("Map Import Complete"); else Debug.Log ("!Map Import Failed"); }