void GenerateRoads() { MassiveTile t = TerrainContainer.GetComponent <MassiveTile>(); string data = File.ReadAllText(Paths.GetPath(ePATHSPEC.ROADSPATH)); //t.GenerateRoadsJSON(data); GameObject go = new GameObject("roads"); MassiveRoad r = go.AddComponent <MassiveRoad>(); r.SetMaterial(MajorRoadMaterial, RoadMaterial, PathMaterial, RailwayMaterial); go.transform.parent = TerrainContainer.transform; go.transform.localPosition = Vector3.zero; r.Generate(data, t.PositionMeters, Paths.GetPath(ePATHSPEC.ROADSASSETPATH)); DestroyImmediate(r); AssetTools.WriteMeshAssets(go, Paths.GetPath(ePATHSPEC.ROADSASSETPATH)); }
void GenerateRoadNetworkTest() { CreateFolders(); MassiveTile t = TerrainContainer.GetComponent <MassiveTile>(); string data = File.ReadAllText(Paths.GetPath(ePATHSPEC.ROADSPATH)); Transform rn = TerrainContainer.transform.Find("roadnetwork"); if (rn != null) { GameObject.DestroyImmediate(rn.gameObject); } GameObject go = new GameObject("roadnetwork"); go.transform.parent = TerrainContainer.transform; go.transform.localPosition = Vector3.zero; go.layer = LayerMask.NameToLayer("Roads"); MassiveRoadNetwork mr = go.AddComponent <MassiveRoadNetwork>(); mr.SetMaterials(RoadMaterial, RailwayMaterial, PathMaterial, ServiceRoadMaterial); mr.CreateTest(); }
void GenerateBuildings() { MassiveTile t = TerrainContainer.GetComponent <MassiveTile>(); string data = File.ReadAllText(Paths.GetPath(ePATHSPEC.BUILDINGSPATH)); //t.GenerateRoadsJSON(data); Transform o = TerrainContainer.transform.Find("buildings"); if (o != null) { GameObject.DestroyImmediate(o.gameObject); } GameObject go = new GameObject("buildings"); MassiveBuilding b = go.AddComponent <MassiveBuilding>(); b.SetMaterial(BuildingMaterial, RoofMaterial); go.transform.parent = TerrainContainer.transform; go.transform.localPosition = Vector3.zero; b.Generate(data, go, t.PositionMeters); //DestroyImmediate(b); AssetTools.WriteMeshAssets(go, Paths.GetPath(ePATHSPEC.BUILDINGSASSETPATH)); }
void GenerateWater() { MassiveTile t = TerrainContainer.GetComponent <MassiveTile>(); t.WaterMaterial = this.WaterMaterial; if (File.Exists(Paths.GetPath(ePATHSPEC.WATERPATH))) { string data = File.ReadAllText(Paths.GetPath(ePATHSPEC.WATERPATH)); GameObject go = new GameObject(); go.transform.parent = t.transform; go.name = "water"; MassiveWater w = go.AddComponent <MassiveWater>(); w.OceanMaterial = WaterMaterial; //Ocean o = go.AddComponent<Ocean>(); //o.m_oceanMat = WaterMaterial; //o.MainCamera = Camera.main; w.GenerateWaterJSON(data, go, t.PositionMeters); go.transform.localPosition = Vector3.zero; DestroyImmediate(w); AssetTools.WriteMeshAssets(go, Paths.GetPath(ePATHSPEC.WATERASSETPATH)); } }
//TODO: Skip OBJ step and generate directly to .asset void GenerateMeshTerrain() { Done++; Debug.Log("Generating Mesh Terrain for " + TileX + "," + TileZ); AssetDatabase.Refresh(); GetContainers(); CreateFolders(); Material m = new Material(Shader.Find("Standard")); m.EnableKeyword("_BUMPMAP"); //_DETAIL_MULX2 m.color = Color.white; m.SetFloat("_SpecularHighlights", 0f); m.SetFloat("_GlossyReflections", 0f); Texture2D t2 = (Texture2D)AssetDatabase.LoadAssetAtPath <Texture2D>(Paths.GetPath(ePATHSPEC.TEXTUREPATH)); m.mainTexture = t2; Texture2D n1 = (Texture2D)AssetDatabase.LoadAssetAtPath <Texture2D>(Paths.GetPath(ePATHSPEC.NORMALMAPPATH)); m.SetTexture("_BumpMap", n1); m.SetFloat("_Glossiness", 0); AssetDatabase.CreateAsset(m, Paths.GetPath(ePATHSPEC.MATERIALPATH)); AssetDatabase.Refresh(); //TerrainSettings tset = TerrainProto.GetComponent<TerrainSettings>(); string hpath = Paths.GetPath(ePATHSPEC.HEIGHTMAPCONTPATH); Debug.Log("Instantiating HeightmapCont:" + TileX + "," + TileZ); HeightMap = Instantiate(AssetDatabase.LoadAssetAtPath <Texture2D>(hpath)); string outpath = Paths.GetPath(ePATHSPEC.MESHOBJPATH); DRect TileSize = MapTools.TileBoundsInMeters(new DVector3(TileX, 0, TileZ), ZoomLevel); //ExportOBJ.ExportFromHeight(HeightMap, outpath, TileSize); //ExportOBJ.ExportMapZenHeight(HeightMap, outpath, TileSize.Size); DVector3 TileLatLon = MapTools.TileToWorldPos(new DVector3(TileX, 0, TileZ), ZoomLevel); TerrainContainer = new GameObject(); MassiveTile tile = TerrainContainer.AddComponent <MassiveTile>(); ExportOBJ.ExportMapZenHeight(tile, HeightMap, outpath, TileSize.Size, TileLatLon); AssetDatabase.Refresh(); AssetDatabase.ImportAsset(Paths.GetPath(ePATHSPEC.MESHOBJPATH)); GameObject asset = (GameObject)AssetDatabase.LoadMainAssetAtPath(Paths.GetPath(ePATHSPEC.MESHOBJPATH)); GameObject obj = Instantiate(asset); //Swap OBJ for .Asset to preserve modifications Transform tr = obj.transform.Find("default"); MeshFilter mf = tr.GetComponent <MeshFilter>(); Mesh nm = Instantiate(mf.sharedMesh); AssetDatabase.CreateAsset(nm, Paths.GetPath(ePATHSPEC.MESHASSETPATH)); AssetDatabase.ImportAsset(Paths.GetPath(ePATHSPEC.MESHASSETPATH)); AssetDatabase.Refresh(); Mesh masset = (Mesh)AssetDatabase.LoadMainAssetAtPath(Paths.GetPath(ePATHSPEC.MESHASSETPATH)); GameObject ma = new GameObject("terrain"); MeshFilter tmf = ma.AddComponent <MeshFilter>(); tmf.mesh = masset; ma.AddComponent <MeshRenderer>(); ma.transform.parent = TerrainContainer.transform; GameObject.DestroyImmediate(obj); AssetDatabase.Refresh(); //set position Vector3 tm = MapTools.TileToMeters(TileX, TileZ, ZoomLevel).ToVector3(); Vector3 sp = MapTools.TileToMeters((int)StartPostion.x, (int)StartPostion.z, ZoomLevel).ToVector3(); DVector3 dif = new DVector3(TileX, 0, TileZ) - StartPostion; TerrainContainer.transform.position = new Vector3(tm.x - sp.x, 0, sp.z - tm.z); TerrainContainer.name = TileX + "_" + "0" + "_" + TileZ + "_" + ZoomLevel; GameObject TerGo = TerrainContainer.transform.Find("terrain").gameObject; MeshRenderer mr = TerGo.GetComponent <MeshRenderer>(); TerGo.AddComponent <MeshCollider>(); TerGo.layer = LayerMask.NameToLayer("Terrain"); tile.ZoomLevel = ZoomLevel; tile.SetTileIndex(new Vector3(TileX, 0, TileZ), ZoomLevel); Material[] temp = new Material[1]; //temp[0] = Instantiate((Material)AssetDatabase.LoadAssetAtPath<Material>(path + ".mat")); temp[0] = (Material)AssetDatabase.LoadAssetAtPath <Material>(Paths.GetPath(ePATHSPEC.MATERIALPATH)); temp[0].name = "mat_" + TileX + "_" + TileZ; //TextureTools.Bilinear(t2, 512, 512); temp[0].mainTexture = t2; //temp[1] = Instantiate((Material)AssetDatabase.LoadAssetAtPath<Material>(path + ".mat")); //temp[1].name = "hello"; mr.sharedMaterials = temp; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("Generated Mesh Terrain"); Done--; }
public static void ExportMapZenHeight(MassiveTile tile, Texture2D t, string Path, DVector3 TileSize, DVector3 TileLatLon) { ExportFromMapZenHeight(tile, t, Path, SaveResolution.Half, SaveFormat.Triangles, TileSize); //ExportZenHeight(Container, t, Path, TileSize, TileLatLon); }
//NOTE: expects a continuity Heightmap, not a regular heightmap. The cont. map contains edge pixels from adjacent maps. static void ExportFromMapZenHeight(MassiveTile tile, Texture2D HeightMap, string fileName, SaveResolution saveResolution, SaveFormat saveFormat, DVector3 TileSize) { EditorUtility.ClearProgressBar(); //TerrainData td = new TerrainData(); //td.baseMapResolution = 256; //td.heightmapResolution = 256; int w = HeightMap.width; int h = HeightMap.height; DVector3 size = new DVector3(TileSize.x, 1, TileSize.z); tile.dHeights = new double[w, h]; for (int xx = 0; xx < h; xx++) { for (int zz = 0; zz < w; zz++) { ////repeat the edge pixels. Stitcher will join adjacent tiles when more tiles are loaded // int xxx = xx < h-1 ? xx : xx-1; //int zzz = zz < w-1 ? zz : zz - 1; Color c = HeightMap.GetPixel(xx, zz); //double height = BitmapUtils.MassivePixelToDouble(c) - EditorGlobals.HeightOffset; double height = TextureTools.GetAbsoluteHeightFromColor(c); //if (height < EditorGlobals.HeightOffset) height = -20; //range 0 - 1 double fh = (float)(height); //float fh = (float)(height); tile.dHeights[xx, zz] = fh; //height values are reversed in unity terrain } } //w = (int)TileSize.x; //h = (int)TileSize.z; Vector3 meshScale = TileSize.ToVector3(); int tRes = (int)Mathf.Pow(2, (int)saveResolution); meshScale = new Vector3(meshScale.x / (w - 1) * tRes, (float)size.y, meshScale.z / (h - 1) * tRes); Vector2 uvScale = new Vector2(1.0f / (w - 1), 1.0f / (h - 1)); w = (w - 1) / tRes + 1; h = (h - 1) / tRes + 1; Vector3[] tVertices = new Vector3[w * h]; Vector2[] tUV = new Vector2[w * h]; int[] tPolys; if (saveFormat == SaveFormat.Triangles) { tPolys = new int[(w - 1) * (h - 1) * 6]; } else { tPolys = new int[(w - 1) * (h - 1) * 4]; } // Build vertices and UVs for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { tVertices[y * w + x] = Vector3.Scale(meshScale, new Vector3(-y, (float)tile.dHeights[y * tRes, x * tRes], x)) + terrainPos; tUV[y * w + x] = Vector2.Scale(new Vector2(x * tRes, y * tRes), uvScale); } } int index = 0; if (saveFormat == SaveFormat.Triangles) { // Build triangle indices: 3 indices into vertex array for each triangle for (int y = 0; y < h - 1; y++) { for (int x = 0; x < w - 1; x++) { // For each grid cell output two triangles tPolys[index++] = (y * w) + x; tPolys[index++] = ((y + 1) * w) + x; tPolys[index++] = (y * w) + x + 1; tPolys[index++] = ((y + 1) * w) + x; tPolys[index++] = ((y + 1) * w) + x + 1; tPolys[index++] = (y * w) + x + 1; } } } else { // Build quad indices: 4 indices into vertex array for each quad for (int y = 0; y < h - 1; y++) { for (int x = 0; x < w - 1; x++) { // For each grid cell output one quad tPolys[index++] = (y * w) + x; tPolys[index++] = ((y + 1) * w) + x; tPolys[index++] = ((y + 1) * w) + x + 1; tPolys[index++] = (y * w) + x + 1; } } } // Export to .obj StreamWriter sw = new StreamWriter(fileName); try { sw.WriteLine("# Unity terrain OBJ File"); // Write vertices System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-US"); counter = tCount = 0; totalCount = (tVertices.Length * 2 + (saveFormat == SaveFormat.Triangles ? tPolys.Length / 3 : tPolys.Length / 4)) / progressUpdateInterval; for (int i = 0; i < tVertices.Length; i++) { UpdateProgress(); StringBuilder sb = new StringBuilder("v ", 20); // StringBuilder stuff is done this way because it's faster than using the "{0} {1} {2}"etc. format // Which is important when you're exporting huge terrains. sb.Append(tVertices[i].x.ToString()).Append(" "). Append(tVertices[i].y.ToString()).Append(" "). Append(tVertices[i].z.ToString()); sw.WriteLine(sb); } // Write UVs for (int i = 0; i < tUV.Length; i++) { UpdateProgress(); StringBuilder sb = new StringBuilder("vt ", 22); sb.Append(tUV[i].y.ToString()).Append(" "). Append(tUV[i].x.ToString()); sw.WriteLine(sb); } if (saveFormat == SaveFormat.Triangles) { // Write triangles for (int i = 0; i < tPolys.Length; i += 3) { UpdateProgress(); StringBuilder sb = new StringBuilder("f ", 43); sb.Append(tPolys[i] + 1).Append("/").Append(tPolys[i] + 1).Append(" "). Append(tPolys[i + 1] + 1).Append("/").Append(tPolys[i + 1] + 1).Append(" "). Append(tPolys[i + 2] + 1).Append("/").Append(tPolys[i + 2] + 1); sw.WriteLine(sb); } } else { // Write quads for (int i = 0; i < tPolys.Length; i += 4) { UpdateProgress(); StringBuilder sb = new StringBuilder("f ", 57); sb.Append(tPolys[i] + 1).Append("/").Append(tPolys[i] + 1).Append(" "). Append(tPolys[i + 1] + 1).Append("/").Append(tPolys[i + 1] + 1).Append(" "). Append(tPolys[i + 2] + 1).Append("/").Append(tPolys[i + 2] + 1).Append(" "). Append(tPolys[i + 3] + 1).Append("/").Append(tPolys[i + 3] + 1); sw.WriteLine(sb); } } } catch (Exception err) { Debug.Log("Error saving file: " + err.Message); } sw.Close(); terrain = null; }