// Update terrain data private void UpdateTerrainHeights(TerrainDesc terrainDesc) { //System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); //long startTime = stopwatch.ElapsedMilliseconds; // Instantiate Daggerfall terrain DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent <DaggerfallTerrain>(); if (dfTerrain) { dfTerrain.TerrainScale = TerrainScale; dfTerrain.MapPixelX = terrainDesc.mapPixelX; dfTerrain.MapPixelY = terrainDesc.mapPixelY; dfTerrain.InstantiateTerrain(); } // Update data for terrain dfTerrain.UpdateMapPixelData(terrainTexturing); // This is most expensive single operation, ~20ms on dev pc dfTerrain.UpdateTileMapData(); dfTerrain.UpdateHeightData(); // Promote data to live terrain dfTerrain.UpdateClimateMaterial(); dfTerrain.PromoteTerrainData(); // Only set active again once complete terrainDesc.terrainObject.SetActive(true); //long totalTime = stopwatch.ElapsedMilliseconds - startTime; //DaggerfallUnity.LogMessage(string.Format("Time to update terrain heights: {0}ms", totalTime), true); }
// Update terrain nature private void UpdateTerrainNature(TerrainDesc terrainDesc) { //System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); //long startTime = stopwatch.ElapsedMilliseconds; // Setup billboards DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent <DaggerfallTerrain>(); DaggerfallBillboardBatch dfBillboardBatch = terrainDesc.billboardBatchObject.GetComponent <DaggerfallBillboardBatch>(); if (dfTerrain && dfBillboardBatch) { // Get current climate and nature archive DFLocation.ClimateSettings climate = MapsFile.GetWorldClimateSettings(dfTerrain.MapData.worldClimate); int natureArchive = climate.NatureArchive; if (dfUnity.WorldTime.SeasonValue == WorldTime.Seasons.Winter) { // Offset to snow textures natureArchive++; } dfBillboardBatch.SetMaterial(natureArchive); TerrainHelper.LayoutNatureBillboards(dfTerrain, dfBillboardBatch, TerrainScale); } // Only set active again once complete terrainDesc.billboardBatchObject.SetActive(true); //long totalTime = stopwatch.ElapsedMilliseconds - startTime; //DaggerfallUnity.LogMessage(string.Format("Time to update terrain nature: {0}ms", totalTime), true); }
public static RegionDesc ReadFromDat() { // Check the FileCache so we don't need to hit the FileSystem repeatedly if (DatManager.PortalDat.FileCache.ContainsKey(REGION_ID)) { return((RegionDesc)DatManager.PortalDat.FileCache[REGION_ID]); } else { DatReader datReader = DatManager.PortalDat.GetReaderForFile(REGION_ID); RegionDesc region = new RegionDesc(); region.FileId = datReader.ReadUInt32(); region.BLoaded = datReader.ReadUInt32(); region.TimeStamp = datReader.ReadUInt32(); region.RegionName = datReader.ReadPString(); // "Dereth" datReader.AlignBoundary(); region.PartsMask = datReader.ReadUInt32(); // There are 7 x 4 byte entries here that are "unknown". We will just skip them. datReader.Offset += (7 * 4); region.LandDefs = LandDefs.Read(datReader); region.GameTime = GameTime.Read(datReader); region.PNext = datReader.ReadUInt32(); if ((region.PNext & 0x10) > 0) { region.SkyInfo = SkyDesc.Read(datReader); } if ((region.PNext & 0x01) > 0) { region.SoundInfo = SoundDesc.Read(datReader); } if ((region.PNext & 0x02) > 0) { region.SceneInfo = SceneDesc.Read(datReader); } region.TerrainInfo = TerrainDesc.Read(datReader); if ((region.PNext & 0x0200) > 0) { region.RegionMisc = RegionMisc.Read(datReader); } DatManager.PortalDat.FileCache[REGION_ID] = region; return(region); } }
// Update terrain nature private void UpdateTerrainNature(TerrainDesc terrainDesc) { // Setup billboards DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent <DaggerfallTerrain>(); DaggerfallBillboardBatch dfBillboardBatch = terrainDesc.billboardBatchObject.GetComponent <DaggerfallBillboardBatch>(); if (dfTerrain && dfBillboardBatch) { // Get current climate and nature archive int natureArchive = ClimateSwaps.GetNatureArchive(LocalPlayerGPS.ClimateSettings.NatureSet, dfUnity.WorldTime.Now.SeasonValue); dfBillboardBatch.SetMaterial(natureArchive); TerrainHelper.LayoutNatureBillboards(dfTerrain, dfBillboardBatch, TerrainScale); } // Only set active again once complete terrainDesc.billboardBatchObject.SetActive(true); }
// Update terrain nature private void UpdateTerrainNature(TerrainDesc terrainDesc) { //System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); //long startTime = stopwatch.ElapsedMilliseconds; // Setup billboards DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent <DaggerfallTerrain>(); DaggerfallBillboardBatch dfBillboardBatch = terrainDesc.billboardBatchObject.GetComponent <DaggerfallBillboardBatch>(); if (dfTerrain && dfBillboardBatch) { // Get current climate and nature archive int natureArchive = ClimateSwaps.GetNatureArchive(LocalPlayerGPS.ClimateSettings.NatureSet, dfUnity.WorldTime.Now.SeasonValue); dfBillboardBatch.SetMaterial(natureArchive); TerrainHelper.LayoutNatureBillboards(dfTerrain, dfBillboardBatch, TerrainScale); } // Only set active again once complete terrainDesc.billboardBatchObject.SetActive(true); //long totalTime = stopwatch.ElapsedMilliseconds - startTime; //DaggerfallUnity.LogMessage(string.Format("Time to update terrain nature: {0}ms", totalTime), true); }
public static TerrainDesc Read(StreamReader data, StreamWriter outputData, bool write = true) { TerrainDesc obj = new TerrainDesc(); uint num_terrain_types = Utils.readAndWriteUInt32(data, outputData, write); obj.TerrainTypes = new List <TerrainType>(); for (uint i = 0; i < num_terrain_types; i++) { obj.TerrainTypes.Add(TerrainType.Read(data, outputData, write)); } //TerrainType BarrenRock = TerrainType.Read(data, outputData, false); //TerrainType Grassland = TerrainType.Read(data, outputData, false); //TerrainType Ice = TerrainType.Read(data, outputData, false); //TerrainType LushGrass = TerrainType.Read(data, outputData, false); //TerrainType MarshSparseSwamp = TerrainType.Read(data, outputData, false); //TerrainType MudRichDirt = TerrainType.Read(data, outputData, false); //TerrainType ObsidianPlain = TerrainType.Read(data, outputData, false); //TerrainType PackedDirt = TerrainType.Read(data, outputData, false); //TerrainType PatchyDirt = TerrainType.Read(data, outputData, false); //TerrainType PatchyGrassland = TerrainType.Read(data, outputData, false); //TerrainType SandYellow = TerrainType.Read(data, outputData, false); //TerrainType SandGrey = TerrainType.Read(data, outputData, false); //TerrainType SandRockStrewn = TerrainType.Read(data, outputData, false); //TerrainType SedimentaryRock = TerrainType.Read(data, outputData, false); //TerrainType SemiBarrenRock = TerrainType.Read(data, outputData, false); //TerrainType Snow = TerrainType.Read(data, outputData, false); //TerrainType WaterRunning = TerrainType.Read(data, outputData, false); //TerrainType WaterStandingFresh = TerrainType.Read(data, outputData, false); //TerrainType WaterShallowSea = TerrainType.Read(data, outputData, false); //TerrainType WaterShallowStillSea = TerrainType.Read(data, outputData, false); //TerrainType WaterDeepSea = TerrainType.Read(data, outputData, false); //TerrainType Forestfloor = TerrainType.Read(data, outputData, false); //TerrainType FauxWaterRunning = TerrainType.Read(data, outputData, false); //TerrainType SeaSlime = TerrainType.Read(data, outputData, false); //TerrainType Argila = TerrainType.Read(data, outputData, false); //TerrainType Volcano1 = TerrainType.Read(data, outputData, false); //TerrainType Volcano2 = TerrainType.Read(data, outputData, false); //TerrainType BlueIce = TerrainType.Read(data, outputData, false); //TerrainType Moss = TerrainType.Read(data, outputData, false); //TerrainType DarkMoss = TerrainType.Read(data, outputData, false); //TerrainType olthoi = TerrainType.Read(data, outputData, false); //TerrainType DesolateLands = TerrainType.Read(data, outputData, false); ////BarrenRock = Snow; ////Grassland = Snow; ////LushGrass = Snow; ////PatchyDirt = Snow; ////PatchyGrassland = Snow; ////Forestfloor = Snow; //BarrenRock.Write(outputData); //Grassland.Write(outputData); //Ice.Write(outputData); //LushGrass.Write(outputData); //MarshSparseSwamp.Write(outputData); //MudRichDirt.Write(outputData); //ObsidianPlain.Write(outputData); //PackedDirt.Write(outputData); //PatchyDirt.Write(outputData); //PatchyGrassland.Write(outputData); //SandYellow.Write(outputData); //SandGrey.Write(outputData); //SandRockStrewn.Write(outputData); //SedimentaryRock.Write(outputData); //SemiBarrenRock.Write(outputData); //Snow.Write(outputData); //WaterRunning.Write(outputData); //WaterStandingFresh.Write(outputData); //WaterShallowSea.Write(outputData); //WaterShallowStillSea.Write(outputData); //WaterDeepSea.Write(outputData); //Forestfloor.Write(outputData); //FauxWaterRunning.Write(outputData); //SeaSlime.Write(outputData); //Argila.Write(outputData); //Volcano1.Write(outputData); //Volcano2.Write(outputData); //BlueIce.Write(outputData); //Moss.Write(outputData); //DarkMoss.Write(outputData); //olthoi.Write(outputData); //DesolateLands.Write(outputData); obj.LandSurfaces = LandSurf.Read(data, outputData, write); return(obj); }
static public void convert(string filename) { StreamReader inputFile = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read)); if (inputFile == null) { Console.WriteLine("Unable to open {0}", filename); return; } StreamWriter outputFile = new StreamWriter(new FileStream("./Region/13000000 - World Info - Winter.bin", FileMode.Create, FileAccess.Write)); if (outputFile == null) { Console.WriteLine("Unable to open 13000000 - World Info - Winter.bin"); return; } Console.WriteLine("Converting region file to winter..."); uint fileHeader; uint loaded; uint timeStamp; string regionName; uint partsMask; uint unknown1; uint unknown2; uint unknown3; uint unknown4; uint unknown5; uint unknown6; uint unknown7; LandDefs landDef; GameTime gameTime; uint next; SkyDesc skyInfo; SoundDesc soundInfo; SceneDesc sceneInfo; TerrainDesc terrainInfo; RegionMisc regionMisc; fileHeader = Utils.readAndWriteUInt32(inputFile, outputFile); if (fileHeader != 0x13000000) { Console.WriteLine("Invalid header, aborting."); return; } loaded = Utils.readAndWriteUInt32(inputFile, outputFile); timeStamp = Utils.readAndWriteUInt32(inputFile, outputFile); regionName = Utils.readAndWriteString(inputFile, outputFile); partsMask = Utils.readAndWriteUInt32(inputFile, outputFile); unknown1 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown2 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown3 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown4 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown5 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown6 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown7 = Utils.readAndWriteUInt32(inputFile, outputFile); landDef = LandDefs.Read(inputFile, outputFile); gameTime = GameTime.Read(inputFile, outputFile); next = Utils.readAndWriteUInt32(inputFile, outputFile); if ((next & 0x10) > 0) { skyInfo = SkyDesc.Read(inputFile, outputFile); } if ((next & 0x01) > 0) { soundInfo = SoundDesc.Read(inputFile, outputFile); } if ((next & 0x02) > 0) { sceneInfo = SceneDesc.Read(inputFile, outputFile); } terrainInfo = TerrainDesc.Read(inputFile, outputFile); if ((next & 0x0200) > 0) { regionMisc = RegionMisc.Read(inputFile, outputFile); } //StreamWriter outputFile2 = new StreamWriter(new FileStream("./13000000 - Terrain Textures -ToD.txt", FileMode.Create, FileAccess.Write)); //if (outputFile2 == null) //{ // Console.WriteLine("Unable to open 13000000 - Terrain Textures - ToD.txt"); // return; //} //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.CornerTerrainMaps.Count; i++) //{ // TerrainAlphaMap cornerTerrainMap = terrainInfo.LandSurfaces.texMerge.CornerTerrainMaps[i]; // outputFile2.WriteLine("{0}", cornerTerrainMap.TexGID.ToString("x8")); // outputFile2.Flush(); //} //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.SideTerrainMaps.Count; i++) //{ // TerrainAlphaMap sideTerrainMap = terrainInfo.LandSurfaces.texMerge.SideTerrainMaps[i]; // outputFile2.WriteLine("{0}", sideTerrainMap.TexGID.ToString("x8")); // outputFile2.Flush(); //} //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.RoadMaps.Count; i++) //{ // RoadAlphaMap roadMap = terrainInfo.LandSurfaces.texMerge.RoadMaps[i]; // outputFile2.WriteLine("{0}", roadMap.RoadTexGID.ToString("x8")); // outputFile2.Flush(); //} //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.TerrainDescription.Count; i++)//ignore first entry as it's a repeat of the second //{ // TMTerrainDesc desc = terrainInfo.LandSurfaces.texMerge.TerrainDescription[i]; // string terrainName = "Unknown"; // uint terrainColor = 0; // if (i < terrainInfo.TerrainTypes.Count) // { // terrainName = terrainInfo.TerrainTypes[(int)desc.terrainType].TerrainName; // terrainColor = terrainInfo.TerrainTypes[(int)desc.terrainType].TerrainColor; // } // else if (i == 32) // { // terrainName = "Road"; // terrainColor = 0; // } // terrainName = terrainName.PadLeft(20); // outputFile2.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}", desc.terrainType, terrainName, desc.terrainTex.TexGID.ToString("x8"), desc.terrainTex.TexTiling, desc.terrainTex.DetailTexGID.ToString("x8"), // desc.terrainTex.DetailTexTiling, desc.terrainTex.MaxVertBright, desc.terrainTex.MaxVertHue, desc.terrainTex.MaxVertSaturate, desc.terrainTex.MinVertBright, // desc.terrainTex.MinVertHue, desc.terrainTex.MinVertSaturate); // //outputFile2.WriteLine("TextureConverter.toBin(\"Landscape Texture Conversion/DM/Textures/Upscaled/xxx.png\", 0x{0}, 21);//{1}",desc.terrainTex.TexGID.ToString("x8"),terrainName); // //outputFile2.WriteLine("writedat client_portal.dat -f {0}={0}.bin", desc.terrainTex.TexGID.ToString("x8")); // outputFile2.Flush(); //} //outputFile2.Close(); inputFile.Close(); outputFile.Flush(); outputFile.Close(); Console.WriteLine("Done"); }
//In DM the 130F0000 is the equivalent of ToD 13000000 and the DM's 13000000 is possibly used for software rendering static public void convert(string filename) { StreamReader inputFile = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.Read)); if (inputFile == null) { Console.WriteLine("Unable to open {0}", filename); return; } StreamWriter outputFile = new StreamWriter(new FileStream("./130F0000 - World Info - DM.bin", FileMode.Create, FileAccess.Write)); if (outputFile == null) { Console.WriteLine("Unable to open 130F0000 - World Info - Winter.bin"); return; } Console.WriteLine("Converting region file to winter..."); byte[] buffer = new byte[1024]; uint fileHeader; uint loaded; uint timeStamp; string regionName; uint partsMask; uint unknown1; uint unknown2; uint unknown3; uint unknown4; uint unknown5; uint unknown6; uint unknown7; LandDefs landDef; GameTime gameTime; uint next; SkyDesc skyInfo; SoundDesc soundInfo; SceneDesc sceneInfo; TerrainDesc terrainInfo; RegionMisc regionMisc; fileHeader = Utils.readAndWriteUInt32(inputFile, outputFile); if (fileHeader != 0x13000000 && fileHeader != 0x130F0000) { Console.WriteLine("Invalid header, aborting."); return; } loaded = Utils.readAndWriteUInt32(inputFile, outputFile); timeStamp = Utils.readAndWriteUInt32(inputFile, outputFile); regionName = Utils.readAndWriteString(inputFile, outputFile); partsMask = Utils.readAndWriteUInt32(inputFile, outputFile); unknown1 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown2 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown3 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown4 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown5 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown6 = Utils.readAndWriteUInt32(inputFile, outputFile); unknown7 = Utils.readAndWriteUInt32(inputFile, outputFile); landDef = LandDefs.Read(inputFile, outputFile); gameTime = GameTime.Read(inputFile, outputFile); next = Utils.readAndWriteUInt32(inputFile, outputFile); if ((next & 0x10) > 0) { skyInfo = SkyDesc.Read(inputFile, outputFile); } if ((next & 0x01) > 0) { soundInfo = SoundDesc.Read(inputFile, outputFile); } if ((next & 0x02) > 0) { sceneInfo = SceneDesc.Read(inputFile, outputFile); } terrainInfo = TerrainDesc.Read(inputFile, outputFile); if ((next & 0x0200) > 0) { regionMisc = RegionMisc.Read(inputFile, outputFile); } StreamWriter outputFile2 = new StreamWriter(new FileStream("./130F0000 - Terrain Textures - DM.txt", FileMode.Create, FileAccess.Write)); if (outputFile2 == null) { Console.WriteLine("Unable to open 130F0000 - Terrain Textures - DM.txt"); return; } //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.CornerTerrainMaps.Count; i++) //{ // TerrainAlphaMap cornerTerrainMap = terrainInfo.LandSurfaces.texMerge.CornerTerrainMaps[i]; // outputFile2.WriteLine("{0}", cornerTerrainMap.TexGID.ToString("x")); // outputFile2.Flush(); //} //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.SideTerrainMaps.Count; i++) //{ // TerrainAlphaMap sideTerrainMap = terrainInfo.LandSurfaces.texMerge.SideTerrainMaps[i]; // outputFile2.WriteLine("{0}", sideTerrainMap.TexGID.ToString("x")); // outputFile2.Flush(); //} //for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.RoadMaps.Count; i++) //{ // RoadAlphaMap roadMap = terrainInfo.LandSurfaces.texMerge.RoadMaps[i]; // outputFile2.WriteLine("{0}", roadMap.RoadTexGID.ToString("x")); // outputFile2.Flush(); //} for (int i = 0; i < terrainInfo.LandSurfaces.texMerge.TerrainDescription.Count; i++) { TMTerrainDesc desc = terrainInfo.LandSurfaces.texMerge.TerrainDescription[i]; string terrainName = "Unknown"; uint terrainColor = 0; if (i < terrainInfo.TerrainTypes.Count) { terrainName = terrainInfo.TerrainTypes[(int)desc.terrainType].TerrainName; terrainColor = terrainInfo.TerrainTypes[(int)desc.terrainType].TerrainColor; } else if (i == 31) { terrainName = "Unused"; terrainColor = 0; } else if (i == 32) { terrainName = "Road"; terrainColor = 0; } terrainName = terrainName.PadLeft(20); outputFile2.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}", desc.terrainType, terrainName, desc.terrainTex.TexGID.ToString("x8"), desc.terrainTex.TexTiling, desc.terrainTex.DetailTexGID.ToString("x8"), desc.terrainTex.DetailTexTiling, desc.terrainTex.MaxVertBright, desc.terrainTex.MaxVertHue, desc.terrainTex.MaxVertSaturate, desc.terrainTex.MinVertBright, desc.terrainTex.MinVertHue, desc.terrainTex.MinVertSaturate); //outputFile2.WriteLine("{0}\t{1}", terrainName, desc.terrainTex.TexGID.ToString("x8")); outputFile2.Flush(); } outputFile2.Close(); inputFile.Close(); outputFile.Flush(); outputFile.Close(); Console.WriteLine("Done"); }
// Update terrain nature private void UpdateTerrainNature(TerrainDesc terrainDesc) { // Setup billboards DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent<DaggerfallTerrain>(); DaggerfallBillboardBatch dfBillboardBatch = terrainDesc.billboardBatchObject.GetComponent<DaggerfallBillboardBatch>(); if (dfTerrain && dfBillboardBatch) { // Get current climate and nature archive int natureArchive = ClimateSwaps.GetNatureArchive(LocalPlayerGPS.ClimateSettings.NatureSet, dfUnity.WorldTime.Now.SeasonValue); dfBillboardBatch.SetMaterial(natureArchive); TerrainHelper.LayoutNatureBillboards(dfTerrain, dfBillboardBatch, TerrainScale); } // Only set active again once complete terrainDesc.billboardBatchObject.SetActive(true); }
// Update terrain data private void UpdateTerrainData(TerrainDesc terrainDesc) { // Instantiate Daggerfall terrain DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent<DaggerfallTerrain>(); if (dfTerrain) { dfTerrain.TerrainScale = TerrainScale; dfTerrain.MapPixelX = terrainDesc.mapPixelX; dfTerrain.MapPixelY = terrainDesc.mapPixelY; dfTerrain.InstantiateTerrain(); } // Update data for terrain dfTerrain.UpdateMapPixelData(terrainTexturing); dfTerrain.UpdateTileMapData(); // Promote data to live terrain dfTerrain.UpdateClimateMaterial(); dfTerrain.PromoteTerrainData(); // Only set active again once complete terrainDesc.terrainObject.SetActive(true); terrainDesc.terrainObject.name = GetTerrainName(dfTerrain.MapPixelX, dfTerrain.MapPixelY); }
// Update terrain data private void UpdateTerrainData(TerrainDesc terrainDesc) { //System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); //long startTime = stopwatch.ElapsedMilliseconds; // Instantiate Daggerfall terrain DaggerfallTerrain dfTerrain = terrainDesc.terrainObject.GetComponent<DaggerfallTerrain>(); if (dfTerrain) { dfTerrain.TerrainScale = TerrainScale; dfTerrain.MapPixelX = terrainDesc.mapPixelX; dfTerrain.MapPixelY = terrainDesc.mapPixelY; dfTerrain.InstantiateTerrain(); } // Update data for terrain dfTerrain.UpdateMapPixelData(terrainTexturing); // This is most expensive single operation, ~20ms on dev pc dfTerrain.UpdateTileMapData(); dfTerrain.UpdateHeightData(); // Promote data to live terrain dfTerrain.UpdateClimateMaterial(); dfTerrain.PromoteTerrainData(); // Only set active again once complete terrainDesc.terrainObject.SetActive(true); //long totalTime = stopwatch.ElapsedMilliseconds - startTime; //DaggerfallUnity.LogMessage(string.Format("Time to update terrain heights: {0}ms", totalTime), true); }