public TerrainValidator(string file) : base(file) { try { var parsed = new TerrainFile(File); if (File.Contains("\\lo_tiles\\")) { Equal(TraceEventType.Warning, 64, parsed.Terrain.Samples.SampleCount, "terrain_nsamples"); Equal(TraceEventType.Warning, 256, parsed.Terrain.Samples.SampleSize, "terrain_sample_size"); } else { Equal(TraceEventType.Warning, 256, parsed.Terrain.Samples.SampleCount, "terrain_nsamples"); Equal(TraceEventType.Warning, 8, parsed.Terrain.Samples.SampleSize, "terrain_sample_size"); } Equal(TraceEventType.Warning, 0, parsed.Terrain.Samples.SampleRotation, "terrain_sample_rotation"); ValidFileRef(TraceEventType.Error, parsed.Terrain.Samples.SampleBufferE, "terrain_sample_ebuffer"); ValidFileRef(TraceEventType.Error, parsed.Terrain.Samples.SampleBufferN, "terrain_sample_nbuffer"); ValidFileRef(TraceEventType.Error, parsed.Terrain.Samples.SampleBufferY, "terrain_sample_ybuffer"); } catch (Exception error) { Trace.WriteLine(error); } }
public static float[,] CalculateHeightMap(this TerrainFile @this) { var heightMapWidth = @this.Chunks[0].HeightMap.Width; var heightMapHeight = @this.Chunks[0].HeightMap.Height; var heights = new float[heightMapWidth * @this.Chunks.Count, heightMapHeight * @this.Chunks.Count]; // // Render HeightMap // for (var chunkY = 0; chunkY < @this.Height; ++chunkY) { for (var chunkX = 0; chunkX < @this.Weight; ++chunkX) { var chunk = @this.Chunks[chunkY * @this.Weight + chunkX]; for (var y = 0; y < chunk.HeightMap.Height; ++y) { for (var x = 0; x < chunk.HeightMap.Width; ++x) { var value = chunk.HeightMap.Data[y * chunk.HeightMap.Width + x]; var pixelX = chunkX * heightMapWidth + x; var pixelY = chunkY * heightMapHeight + y; heights[pixelX, pixelY] = value; } } } } return(heights); }
public static async Task <TerrainEditor> OpenEmptyAsync(TerrainSettings setting) { var file = new TerrainFile(); var chunks = new List <Chunk>(); var index = 0; var center = setting.Size / 2; for (var x = 0; x < setting.Size; x++) { for (var y = 0; y < setting.Size; y++) { var chunk = GenerateEmptyChunk(index++, setting); chunk.HeightMap.PositionX = (x - center) * setting.ChunkSpacing; chunk.HeightMap.PositionY = (y - center) * setting.ChunkSpacing; chunks.Add(chunk); } } file.Weight = setting.Size; file.Height = setting.Size; file.ChunkTotalCount = setting.Size * setting.Size; file.Chunks = chunks; return(new TerrainEditor(file) { ChunkSize = setting.ChunkSize }); }
public static Vector3[,] GenerateRealMap(this TerrainFile @this) { const float scale = 3.2f; //3.125f; var heightMap = @this.GenerateHeightMap(); var centerX = (heightMap.GetLength(0) - 1) / 2; var centerY = (heightMap.GetLength(1) - 1) / 2; var weight = heightMap.GetLength(0); var height = heightMap.GetLength(1); var inGameValues = new Vector3[weight, height]; for (var x = 0; x < weight; x++) { for (var y = 0; y < height; y++) { var value = heightMap[x, y]; var realX = x - centerX; var realY = y - centerY; var inGame = new Vector2(realX, realY); inGame *= scale; inGameValues[x, y] = new Vector3(inGame.X, value, inGame.Y); } } return(inGameValues); }
public static string ExportAsObj(this TerrainFile @this, int offset, out int newOffset) { var triangles = @this.Triangulate(); var obj = new StringBuilder(); foreach (var triangle in triangles.SelectMany(t => t.ToArray)) { obj.AppendLine($"v {triangle.X.ToString(CultureInfo.InvariantCulture)}" + $" {triangle.Y.ToString(CultureInfo.InvariantCulture)}" + $" {triangle.Z.ToString(CultureInfo.InvariantCulture)}" ); } for (var i = 0; i < triangles.Length; i++) { var index = i * 3 + 1 + offset; obj.AppendLine($"f {index}//{index} {index + 1}//{index + 1} {index + 2}//{index + 2}"); } newOffset = offset + triangles.Length * 3; return(obj.ToString()); }
public TerrainConverterPatch(TerrainFile tFile, TerrainAltitudeFile yFile, int patchX, int patchZ) { TFile = tFile; YFile = yFile; PatchX = patchX; PatchZ = patchZ; PatchSize = tFile.terrain.terrain_samples.terrain_nsamples / tFile.terrain.terrain_patchsets[0].terrain_patchset_npatches; }
public TerrainEditor(TerrainFile file) { Source = file; HeightLayer = new HeightLayer(this); ColorLayer = new ColorLayer(this, false); SecondColorLayer = new ColorLayer(this, true); }
public TerrainConverterPatch(TerrainFile tFile, TerrainAltitudeFile yFile, int patchX, int patchZ) { TFile = tFile; YFile = yFile; PatchX = patchX; PatchZ = patchZ; PatchSize = tFile.Terrain.Samples.SampleCount / tFile.Terrain.Patchsets[0].PatchSize; }
public static GameObject Import(string workingFile) { using var stream = File.OpenRead(workingFile); using var reader = new BitReader(stream); var terrain = new TerrainFile(); terrain.Deserialize(reader); return(Import(terrain)); }
public static async Task <TerrainEditor> OpenAsync(string path) { await using var stream = File.OpenRead(path); using var reader = new BitReader(stream); var file = new TerrainFile(); file.Deserialize(reader); return(new TerrainEditor(file)); }
private void DrawSettingGroup() { EditorGUILayout.BeginVertical(); GUILayout.Label("Setting"); groupsRefObject.chunk.ChunkLenght = EditorGUILayout.IntField("Chunk Lenght", groupsRefObject.chunk.ChunkLenght); groupsRefObject.chunk.ChunkWidth = EditorGUILayout.IntField("Chunk Width", groupsRefObject.chunk.ChunkWidth); groupsRefObject.chunk.uvReslution = EditorGUILayout.Vector2Field("UV Reslution", groupsRefObject.chunk.uvReslution); groupsRefObject.chunk.LayerHeight = EditorGUILayout.FloatField("Layer Height", groupsRefObject.chunk.LayerHeight); for (int idx = 0; idx < groupsRefObject.datas.Count; ++idx) { EditorGUILayout.LabelField("--------------------------------------------------------------------------------------------"); EditorGUILayout.Space(); EditorGUILayout.Space(); GUILayout.Label("Index:" + idx.ToString()); TerrainFile FileRef = groupsRefObject.datas[idx]; EditorGUI.BeginChangeCheck(); FileRef.name = EditorGUILayout.TextField("name", FileRef.name); FileRef.terrainWidth = EditorGUILayout.IntField("TerrainWidth", FileRef.terrainWidth); FileRef.terrainLength = EditorGUILayout.IntField("TerrainLenght", FileRef.terrainLength); if (EditorGUI.EndChangeCheck()) { EditorGUILayout.HelpBox("修改尺寸,会重置地图数据", MessageType.Warning, true); } FileRef.worldPositon = EditorGUILayout.Vector3Field("worldPositon", FileRef.worldPositon); FileRef.worldSize = EditorGUILayout.Vector3Field("worldSize", FileRef.worldSize); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button(delIcon)) { if (groupsRefObject.datas.Count <= 0) { return; } DelGroupWindows.OpenWindow(groupsRefObject.datas); } if (GUILayout.Button(addIcon)) { AddGroupWindows.OpenWindow(objRef, groupsRefObject.datas); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); }
public Tile(string filePath, int tileX, int tileZ, TileName.Zoom zoom, bool visible) { TileX = tileX; TileZ = tileZ; Size = 1 << (15 - (int)zoom); var fileName = filePath + TileName.FromTileXZ(tileX, tileZ, zoom); if (!File.Exists(fileName + ".t")) { // Many tiles adjacent to the visible tile may not be modelled, so a warning is not helpful; // ignore a missing .t file unless it is the currently visible tile. if (visible) { Trace.TraceWarning("Ignoring missing tile {0}.t", fileName); } return; } // T and Y files are expected to exist; F files are optional. try { TFile = new TerrainFile(fileName + ".t"); } catch (Exception error) { Trace.WriteLine(new FileLoadException(fileName + ".t", error)); } try { YFile = new TerrainAltitudeFile(fileName + "_y.raw", SampleCount); } catch (Exception error) { Trace.WriteLine(new FileLoadException(fileName + "_y.raw", error)); } try { if (File.Exists(fileName + "_f.raw")) { FFile = new TerrainFlagsFile(fileName + "_f.raw", SampleCount); } } catch (Exception error) { Trace.WriteLine(new FileLoadException(fileName + "_f.raw", error)); } }
public async Task LoadZoneDataAsync(int seek) { Zones.Clear(); Logger.Information("Parsing zone info..."); var zone = await ClientCache.FindAsync <ZoneTable>(seek); if (zone == default) { Logger.Error($"Cannot find zone {seek}"); return; } ; var luzFile = Path.Combine("maps", zone.ZoneName.ToLower()); if (!luzFile.EndsWith(".luz")) { return; } Logger.Information($"Parsing: {luzFile}"); try { var luz = new LuzFile(); await using var stream = _resources.GetStream(luzFile); var reader = new BitReader(stream); luz.Deserialize(reader); var path = Path.GetDirectoryName(luzFile); var lvlFiles = new List <LvlFile>(); foreach (var scene in luz.Scenes) { await using var sceneStream = _resources.GetStream(Path.Combine(path, scene.FileName)); using var sceneReader = new BitReader(sceneStream); Logger.Information($"Parsing: {scene.FileName}"); var lvl = new LvlFile(); lvl.Deserialize(sceneReader); lvlFiles.Add(lvl); if (lvl.LevelObjects?.Templates == default) { continue; } foreach (var template in lvl.LevelObjects.Templates) { template.ObjectId |= 70368744177664; } } var terrainStream = _resources.GetStream(Path.Combine(path, luz.TerrainFileName)); using var terrainReader = new BitReader(terrainStream); var terrain = new TerrainFile(); terrain.Deserialize(terrainReader); var triggers = await TriggerDictionary.FromDirectoryAsync(Path.Combine(_resources.RootPath, path)); Logger.Information($"Parsed: {seek}"); Zones[seek] = new ZoneInfo { LuzFile = luz, LvlFiles = lvlFiles, TriggerDictionary = triggers, TerrainFile = terrain }; } catch (Exception e) { Logger.Error($"Failed to parse {luzFile}: {e.Message}\n{e.StackTrace}"); } }
public static Triangle[] Triangulate(this TerrainFile @this) { var heightMap = @this.GenerateRealMap(); var weight = heightMap.GetLength(0); var height = heightMap.GetLength(1); bool TryGetValue(int x, int y, out Vector3 value) { try { value = heightMap[x, y]; return(true); } catch { value = Vector3.Zero; return(false); } } var triangles = new List <Triangle>(); for (var y = 0; y < height; y += 1) { for (var x = 0; x < weight; x += 1) { { if (!TryGetValue(x, y, out var source)) { continue; } if (!TryGetValue(x + 1, y, out var next)) { continue; } if (!TryGetValue(x, y + 1, out var top)) { continue; } var triangle = new Triangle { Position1 = top, Position2 = next, Position3 = source }; triangles.Add(triangle); } { if (!TryGetValue(x, y + 1, out var source)) { continue; } if (!TryGetValue(x + 1, y + 1, out var next)) { continue; } if (!TryGetValue(x + 1, y, out var top)) { continue; } var triangle = new Triangle { Position1 = source, Position2 = next, Position3 = top }; triangles.Add(triangle); } } } return(triangles.ToArray()); }
/// <summary> /// Try to load the file. /// Possibly this might raise an exception. That exception is not caught here /// </summary> /// <param name="file">The file that needs to be loaded</param> public override void TryLoading(string file) { loadedFile = file; tFile = new TerrainFile(file); }
public static async Task ExportToWavefrontAsync(this LuzFile @this, AccessDatabase database, string source, string resources, string result) { TerrainFile terrain; await using (var stream = File.OpenRead(Path.Combine(source, @this.TerrainFileName))) { using var reader = new BitReader(stream); terrain = new TerrainFile(); terrain.Deserialize(reader); } var levels = new LvlFile[@this.Scenes.Length]; for (var i = 0; i < @this.Scenes.Length; i++) { var scene = @this.Scenes[i]; await using var stream = File.OpenRead(Path.Combine(source, scene.FileName)); using var reader = new BitReader(stream); var level = new LvlFile(); level.Deserialize(reader); levels[i] = level; } var objects = new List <LevelObjectTemplate>(); foreach (var level in levels) { if (level.LevelObjects?.Templates == default) { continue; } foreach (var template in level.LevelObjects.Templates) { if (!template.LegoInfo.TryGetValue("add_to_navmesh", out var add)) { continue; } if (!(bool)add) { continue; } objects.Add(template); } } foreach (var template in objects) { var instance = database.LoadObject(template.Lot); var renderer = instance.GetComponent <RenderComponentTable>(); if (renderer == default) { continue; } Console.WriteLine(renderer.render_asset); } }
public async Task LoadZoneDataAsync(int seek) { Zones.Clear(); Logger.Information("Parsing zone info..."); var luzFiles = _resources.GetAllFilesWithExtension("luz"); foreach (var luzFile in luzFiles) { Logger.Information($"Parsing: {luzFile}"); try { var luz = new LuzFile(); await using var stream = _resources.GetStream(luzFile); var reader = new BitReader(stream); luz.Deserialize(reader); if (luz.WorldId != seek) { continue; } var path = Path.GetDirectoryName(luzFile); var lvlFiles = new List <LvlFile>(); foreach (var scene in luz.Scenes) { await using var sceneStream = _resources.GetStream(Path.Combine(path, scene.FileName)); using var sceneReader = new BitReader(sceneStream); Logger.Information($"Parsing: {scene.FileName}"); var lvl = new LvlFile(); lvl.Deserialize(sceneReader); lvlFiles.Add(lvl); if (lvl.LevelObjects?.Templates == default) { continue; } foreach (var template in lvl.LevelObjects.Templates) { template.ObjectId |= 70368744177664; } } var terrainStream = _resources.GetStream(Path.Combine(path, luz.TerrainFileName)); using var terrainReader = new BitReader(terrainStream); var terrain = new TerrainFile(); terrain.Deserialize(terrainReader); var triggers = await TriggerDictionary.FromDirectoryAsync(Path.Combine(_resources.RootPath, path)); Logger.Information($"Parsed: {(ZoneId) luz.WorldId}"); Zones[(int)luz.WorldId] = new ZoneInfo { LuzFile = luz, LvlFiles = lvlFiles, TriggerDictionary = triggers, TerrainFile = terrain }; break; } catch (Exception e) { Logger.Error($"Failed to parse {luzFile}: {e.Message}\n{e.StackTrace}"); } } }
public static GameObject Import(TerrainFile terrain) { const float scale = 3.2f; //3.125f; var terrainInstance = new GameObject($"Terrain"); var centerX = 204.8f / 2; var centerY = -204.8f / 2; for (var x = 0; x < terrain.Weight; x++) { for (var y = 0; y < terrain.Height; y++) { var chunk = terrain.Chunks[x + y * terrain.Height]; if (Directory.Exists("lightmap/")) { File.WriteAllBytes($"lightmap/lightmap_{x}_{y}.dds", chunk.Lightmap.Data); } if (Directory.Exists("blendmap/")) { File.WriteAllBytes($"blendmap/blendmap_{x}_{y}.dds", chunk.Blendmap.Data); } var triangles = chunk.Triangulate(); var instance = new GameObject($"Chunk ({x}, {y})"); instance.transform.parent = terrainInstance.transform; var mesh = new Mesh(); mesh.vertices = triangles.SelectMany(t => t.ToArray.Select(v => new Vector3(v.X, v.Y, v.Z)).ToArray()).ToArray(); /* * var colors = new Color[mesh.vertices.Length]; * * for (var i = 0; i < mesh.vertices.Length; i++) * { * colors[i] = Color.green; * } */ mesh.colors = Enumerable.Repeat(new Color(0, 1, 0), mesh.vertices.Length).ToArray(); //chunk.GenerateColorArray(ref colors, true); mesh.triangles = Enumerable.Range(0, triangles.Length * 3).ToArray(); mesh.RecalculateNormals(); /* * if (colors.Length == mesh.vertices.Length) * { * mesh.colors = colors.Select(c => ).ToArray(); * } * else * { * Debug.Log($"{chunk.Colormap0.Size}/{chunk.Colormap0.Size} vs {chunk.HeightMap.Height}/{chunk.HeightMap.Width}"); * mesh.colors = Enumerable.Repeat(new Color(0, 1 - UnityEngine.Random.value * 0.1f, 0), mesh.vertices.Length).ToArray(); * } */ //mesh.colors = colors; var filter = instance.AddComponent <MeshFilter>(); filter.mesh = mesh; var render = instance.AddComponent <MeshRenderer>(); render.material = WorkspaceControl.CurrentWorkspace.TerrainMaterial; instance.transform.position += new Vector3(centerX + x * 204.8f + 3.2f / 4, 0, centerY + y * 204.8f); for (var index = 0; index < chunk.Foliage.Count; index++) { var foliage = chunk.Foliage[index]; var foliageObject = new GameObject($"Foliage {foliage.Type} ({index})"); foliageObject.transform.position = new Vector3(foliage.Position.X, foliage.Position.Y, foliage.Position.Z); foliageObject.transform.rotation = new Quaternion(foliage.Rotation.X, foliage.Rotation.Y, foliage.Rotation.Z, foliage.Rotation.W); foliageObject.transform.parent = instance.transform; } } } terrainInstance.transform.position = new Vector3(0, 0, 0); //-new Vector3(centerX, 0, centerY) * scale; return(terrainInstance); }
public bool DoConversion(DataConversion conversion) { // We can convert from .t or .w files. if (Path.GetExtension(conversion.Input) != ".t" && Path.GetExtension(conversion.Input) != ".w") { return(false); } // We can convert to .dae files. if (conversion.Output.Any(output => Path.GetExtension(output) != ".dae")) { return(false); } if (!File.Exists(conversion.Input)) { throw new FileNotFoundException("", conversion.Input); } if (Path.GetExtension(conversion.Input) == ".w") { // Convert from world file to tile file, by parsing the X, Z coordinates from filename. var filename = Path.GetFileNameWithoutExtension(conversion.Input); int tileX, tileZ; if (filename.Length != 15 || filename[0] != 'w' || (filename[1] != '+' && filename[1] != '-') || (filename[8] != '+' && filename[8] != '-') || !int.TryParse(filename.Substring(1, 7), out tileX) || !int.TryParse(filename.Substring(8, 7), out tileZ)) { throw new InvalidCommandLineException("Unable to parse tile coordinates from world filename: " + filename); } var tilesDirectory = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(conversion.Input)), "Tiles"); var tileName = TileName.FromTileXZ(tileX, tileZ, TileName.Zoom.Small); conversion.SetInput(Path.Combine(tilesDirectory, tileName + ".t")); } var baseFileName = Path.Combine(Path.GetDirectoryName(conversion.Input), Path.GetFileNameWithoutExtension(conversion.Input)); var tFile = new TerrainFile(baseFileName + ".t"); var sampleCount = tFile.terrain.terrain_samples.terrain_nsamples; var yFile = new TerrainAltitudeFile(baseFileName + "_y.raw", sampleCount); TerrainFlagsFile fFile; if (File.Exists(baseFileName + "_f.raw")) { fFile = new TerrainFlagsFile(baseFileName + "_f.raw", sampleCount); } var patchCount = tFile.terrain.terrain_patchsets[0].terrain_patchset_npatches; for (var x = 0; x < patchCount; x++) { for (var z = 0; z < patchCount; z++) { var patch = new TerrainConverterPatch(tFile, yFile, x, z); XNamespace cNS = "http://www.collada.org/2005/11/COLLADASchema"; var colladaDocument = new XDocument( new XDeclaration("1.0", "UTF-8", "false"), new XElement(cNS + "COLLADA", new XAttribute("version", "1.4.1"), new XElement(cNS + "asset", new XElement(cNS + "created", DateTime.UtcNow.ToString("o")), new XElement(cNS + "modified", DateTime.UtcNow.ToString("o")) ), new XElement(cNS + "library_effects", new XElement(cNS + "effect", new XAttribute("id", "Library-Effect-GreenPhong"), new XElement(cNS + "profile_COMMON", new XElement(cNS + "technique", new XAttribute("sid", "phong"), new XElement(cNS + "phong", new XElement(cNS + "emission", new XElement(cNS + "color", "1.0 1.0 1.0 1.0") ), new XElement(cNS + "ambient", new XElement(cNS + "color", "1.0 1.0 1.0 1.0") ), new XElement(cNS + "diffuse", new XElement(cNS + "color", "0.0 1.0 0.0 1.0") ), new XElement(cNS + "specular", new XElement(cNS + "color", "1.0 1.0 1.0 1.0") ), new XElement(cNS + "shininess", new XElement(cNS + "float", "20.0") ), new XElement(cNS + "reflective", new XElement(cNS + "color", "1.0 1.0 1.0 1.0") ), new XElement(cNS + "reflectivity", new XElement(cNS + "float", "0.5") ), new XElement(cNS + "transparent", new XElement(cNS + "color", "1.0 1.0 1.0 1.0") ), new XElement(cNS + "transparency", new XElement(cNS + "float", "1.0") ) ) ) ) ) ), new XElement(cNS + "library_materials", new XElement(cNS + "material", new XAttribute("id", "Library-Material-Terrain"), new XAttribute("name", "Terrain material"), new XElement(cNS + "instance_effect", new XAttribute("url", "#Library-Effect-GreenPhong") ) ) ), new XElement(cNS + "library_geometries", new XElement(cNS + "geometry", new XAttribute("id", "Library-Geometry-Terrain"), new XAttribute("name", "Terrain geometry"), new XElement(cNS + "mesh", new XElement(cNS + "source", new XAttribute("id", "Library-Geometry-Terrain-Position"), new XElement(cNS + "float_array", new XAttribute("id", "Library-Geometry-Terrain-Position-Array"), new XAttribute("count", patch.GetVertexArrayLength()), patch.GetVertexArray() ), new XElement(cNS + "technique_common", new XElement(cNS + "accessor", new XAttribute("source", "#Library-Geometry-Terrain-Position-Array"), new XAttribute("count", patch.GetVertexLength()), new XAttribute("stride", 3), new XElement(cNS + "param", new XAttribute("name", "X"), new XAttribute("type", "float") ), new XElement(cNS + "param", new XAttribute("name", "Y"), new XAttribute("type", "float") ), new XElement(cNS + "param", new XAttribute("name", "Z"), new XAttribute("type", "float") ) ) ) ), new XElement(cNS + "vertices", new XAttribute("id", "Library-Geometry-Terrain-Vertex"), new XElement(cNS + "input", new XAttribute("semantic", "POSITION"), new XAttribute("source", "#Library-Geometry-Terrain-Position") ) ), new XElement(cNS + "polygons", new XObject[] { new XAttribute("count", patch.GetPolygonLength()), new XAttribute("material", "MATERIAL"), new XElement(cNS + "input", new XAttribute("semantic", "VERTEX"), new XAttribute("source", "#Library-Geometry-Terrain-Vertex"), new XAttribute("offset", 0) ) }.Concat(patch.GetPolygonArray().Select(polygon => (XObject) new XElement(cNS + "p", polygon))) ) ) ) ), // Move nodes into <library_nodes/> to make them individual components in SketchUp. //new XElement(cNS + "library_nodes", //), new XElement(cNS + "library_visual_scenes", new XElement(cNS + "visual_scene", new XAttribute("id", "VisualScene-Default"), new XElement(cNS + "node", new XAttribute("id", "Node-Terrain"), new XAttribute("name", "Terrain"), new XElement(cNS + "instance_geometry", new XAttribute("url", "#Library-Geometry-Terrain"), new XElement(cNS + "bind_material", new XElement(cNS + "technique_common", new XElement(cNS + "instance_material", new XAttribute("symbol", "MATERIAL"), new XAttribute("target", "#Library-Material-Terrain") ) ) ) ) ) ) ), new XElement(cNS + "scene", new XElement(cNS + "instance_visual_scene", new XAttribute("url", "#VisualScene-Default") ) ) ) ); foreach (var output in conversion.Output) { var fileName = Path.ChangeExtension(output, string.Format("{0:00}-{1:00}.dae", x, z)); colladaDocument.Save(fileName); } } } return(true); }
static void CollectTileTerrtex(string[] args) { var summary = new List <TileTerrtexDirectory>(); foreach (var arg in args) { if (Directory.Exists(arg)) { Console.WriteLine("Scanning {0}...", arg); foreach (var path in Directory.GetDirectories(arg, "Tiles", SearchOption.AllDirectories)) { Console.WriteLine("Scanning {0}...", path); var data = new TileTerrtexDirectory(path); foreach (var file in Directory.GetFiles(path, "*.t")) { try { var t = new TerrainFile(file); if (t.terrain.terrain_patchsets.Length != 1) { throw new InvalidDataException(String.Format("Tile has {0} patch sets; expected 1.", t.terrain.terrain_patchsets.Length)); } if (t.terrain.terrain_patchsets[0].terrain_patchset_npatches != 16) { throw new InvalidDataException(String.Format("Tile has {0} patches; expected 16.", t.terrain.terrain_patchsets[0].terrain_patchset_npatches)); } if (t.terrain.terrain_patchsets[0].terrain_patchset_patches.Length != 256) { throw new InvalidDataException(String.Format("Tile has {0} patches; expected 256.", t.terrain.terrain_patchsets[0].terrain_patchset_patches.Length)); } data.TileCount++; var patchset = t.terrain.terrain_patchsets[0]; var textures = new List <string>(patchset.terrain_patchset_npatches * patchset.terrain_patchset_npatches); foreach (var patch in patchset.terrain_patchset_patches) { textures.Add(String.Join("|", (from ts in t.terrain.terrain_shaders[patch.ShaderIndex].terrain_texslots select ts.Filename).ToArray())); } // 1th if (textures.Distinct().Count() == 1) { data.Tile1Count++; } // 4th var textures4 = new List <string> [4]; for (var i = 0; i < textures4.Length; i++) { textures4[i] = new List <string>(); } for (var x = 0; x < 16; x++) { for (var y = 0; y < 16; y++) { var tx = (int)(x / 8); var ty = (int)(y / 8); textures4[tx + ty * 2].Add(textures[x + y * 16]); } } for (var i = 0; i < textures4.Length; i++) { if (textures4[i].Distinct().Count() == 1) { data.Tile4Count++; } } // 16th var textures16 = new List <string> [16]; for (var i = 0; i < textures16.Length; i++) { textures16[i] = new List <string>(); } for (var x = 0; x < 16; x++) { for (var y = 0; y < 16; y++) { var tx = (int)(x / 4); var ty = (int)(y / 4); textures16[tx + ty * 4].Add(textures[x + y * 16]); } } for (var i = 0; i < textures16.Length; i++) { if (textures16[i].Distinct().Count() == 1) { data.Tile16Count++; } } // 64th var textures64 = new List <string> [64]; for (var i = 0; i < textures64.Length; i++) { textures64[i] = new List <string>(); } for (var x = 0; x < 16; x++) { for (var y = 0; y < 16; y++) { var tx = (int)(x / 2); var ty = (int)(y / 2); textures64[tx + ty * 8].Add(textures[x + y * 16]); } } for (var i = 0; i < textures64.Length; i++) { if (textures64[i].Distinct().Count() == 1) { data.Tile64Count++; } } } catch (Exception error) { Console.WriteLine("Error reading tile {0}: {1}", file, error); } } if (data.TileCount > 0) { summary.Add(data); } } } } Console.WriteLine(); foreach (var data in from data in summary orderby data.Path select data) { Console.WriteLine("{0,30} / {1,-4} / 1th {2,5:P0} / 4th {3,5:P0} / 16th {4,5:P0} / 64th {5,5:P0}", data.Path, data.TileCount, data.Tile1Count / data.TileCount, data.Tile4Count / 4 / data.TileCount, data.Tile16Count / 16 / data.TileCount, data.Tile64Count / 64 / data.TileCount); } }
private static void CollectTileTerrtex(string[] args) { List <TileTerrtexDirectory> summary = new List <TileTerrtexDirectory>(); foreach (string arg in args) { if (Directory.Exists(arg)) { Trace.WriteLine($"Scanning {args}..."); foreach (string path in Directory.GetDirectories(arg, "Tiles", SearchOption.AllDirectories)) { Trace.WriteLine($"Scanning {path}..."); TileTerrtexDirectory data = new TileTerrtexDirectory(path); foreach (string file in Directory.GetFiles(path, "*.t")) { try { TerrainFile t = new TerrainFile(file); if (t.Terrain.Patchsets.Length != 1) { throw new InvalidDataException($"Tile has {t.Terrain.Patchsets.Length} patch sets; expected 1."); } if (t.Terrain.Patchsets[0].PatchSize != 16) { throw new InvalidDataException($"Tile has {t.Terrain.Patchsets[0].PatchSize} patches; expected 16."); } if (t.Terrain.Patchsets[0].Patches.Length != 256) { throw new InvalidDataException($"Tile has {t.Terrain.Patchsets[0].Patches.Length} patches; expected 256."); } data.TileCount++; Formats.Msts.Models.PatchSet patchset = t.Terrain.Patchsets[0]; List <string> textures = new List <string>(patchset.PatchSize * patchset.PatchSize); foreach (Formats.Msts.Models.Patch patch in patchset.Patches) { textures.Add(string.Join("|", (from ts in t.Terrain.Shaders[patch.ShaderIndex].Textureslots select ts.FileName).ToArray())); } // 1th if (textures.Distinct().Count() == 1) { data.Tile1Count++; } // 4th List <string>[] textures4 = new List <string> [4]; for (int i = 0; i < textures4.Length; i++) { textures4[i] = new List <string>(); } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { int tx = x / 8; int ty = y / 8; textures4[tx + ty * 2].Add(textures[x + y * 16]); } } for (int i = 0; i < textures4.Length; i++) { if (textures4[i].Distinct().Count() == 1) { data.Tile4Count++; } } // 16th List <string>[] textures16 = new List <string> [16]; for (int i = 0; i < textures16.Length; i++) { textures16[i] = new List <string>(); } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { int tx = x / 4; int ty = y / 4; textures16[tx + ty * 4].Add(textures[x + y * 16]); } } for (int i = 0; i < textures16.Length; i++) { if (textures16[i].Distinct().Count() == 1) { data.Tile16Count++; } } // 64th List <string>[] textures64 = new List <string> [64]; for (int i = 0; i < textures64.Length; i++) { textures64[i] = new List <string>(); } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { int tx = x / 2; int ty = y / 2; textures64[tx + ty * 8].Add(textures[x + y * 16]); } } for (int i = 0; i < textures64.Length; i++) { if (textures64[i].Distinct().Count() == 1) { data.Tile64Count++; } } } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception error) #pragma warning restore CA1031 // Do not catch general exception types { Trace.WriteLine($"Error reading tile {file}: {error}"); } } if (data.TileCount > 0) { summary.Add(data); } } } } Trace.WriteLine(string.Empty); foreach (TileTerrtexDirectory data in from data in summary orderby data.Path select data) { Trace.WriteLine($"{data.Path,30} / {data.TileCount,-4} / 1th {data.Tile1Count / data.TileCount,5:P0} / 4th {data.Tile4Count / 4 / data.TileCount,5:P0} / 16th {data.Tile16Count / 16 / data.TileCount,5:P0} / 64th {data.Tile64Count / 64 / data.TileCount,5:P0}"); } }
private void OnEnable() { newFile = new TerrainFile(); }