using AC2RE.Definitions; using ImageMagick; using LandblockExtraction.DatEngine; using LandblockExtraction.Tools; using System.Numerics; namespace LandblockExtraction.AtlasMaker; public class TerrainAtlasManager { private PortalEngine portalEngine; private Dictionary mapTerrain; private TexturesImage texturesImage; public Dictionary textureCoord; public Dictionary terrainTexture; public Dictionary terrains; public Dictionary texturesIndex; public TerrainAtlasManager(PortalEngine portalEngine) { this.portalEngine = portalEngine; mapTerrain = new(); textureCoord = new Dictionary(); terrainTexture = new Dictionary(); terrains = new Dictionary(); texturesImage = new TexturesImage(portalEngine); texturesIndex = new Dictionary(); GenerateDictionaryTexture(); foreach(var img in texturesIndex) { var i = texturesImage.GetImage(img.Key); i.Write($"{img.Value}.jpg"); } InitialiseTerrainDic(); GenerateTerrain(); } private void GenerateDictionaryTexture() { int index = 0; foreach (var surfaces in portalEngine.cSurfaceDesc.surfaces) { foreach (var surface in surfaces.terrainMaterials) { var did = surface.baseMaterials.First().materialDid; if (!texturesIndex.ContainsKey(did)) { texturesIndex.Add(did, index); index++; } } } } public void ExtractTexture() { using (var atlasBuilder = new AtlasBuilder(portalEngine)) { foreach (var terrain in portalEngine.cTerrainDesc.terrains) { foreach (var surface in portalEngine.cSurfaceDesc.surfaces) { if (surface.surfIndex == terrain.surfaceInfo) { atlasBuilder.AddTexture((int)terrain.terrainIndex, surface.terrainMaterials.First().baseMaterials.First().materialDid); //terrains.Add((int)terrain.terrainIndex, GenerateSubTerrain((int)terrain.terrainIndex, surface.terrainMaterials)); } } textureCoord.Add((int)terrain.terrainIndex, Vector2.Zero); } atlasBuilder.GenerateAtlas(); foreach (var img in atlasBuilder.textures) { terrainTexture.Add(img.Key, img.Value); } } } private void GenerateTerrain() { foreach(var terrain in portalEngine.cTerrainDesc.terrains) { Terrain tmpTer = new((int)terrain.terrainIndex); foreach(var surface in portalEngine.cSurfaceDesc.surfaces) { if(terrain.surfaceInfo == surface.surfIndex) { foreach(var mat in surface.terrainMaterials) { tmpTer.subTerrains.Add(new(GetIndex(mat.baseMaterials.First().materialDid), mat.minPitch, mat.maxPitch, MathOperations.RGBAColorToVector4(mat.vertexColor.First().vertexColor), MathOperations.RGBAColorToVector4(mat.vertexColor.First().farVertexColor))); } } } terrains.Add((int)terrain.terrainIndex, tmpTer); Console.WriteLine("Init: " + terrain.terrainIndex); } } private void testGenerateList() { foreach (var terrain in portalEngine.cTerrainDesc.terrains) { foreach (var surfaces in portalEngine.cSurfaceDesc.surfaces) { if (surfaces.surfIndex != terrain.surfaceInfo) continue; foreach (var surface in surfaces.terrainMaterials) { uint test = 0; //foreach(var m in map) { if (m.Key == surface.baseMaterials.First().materialDid) test = m.Value; } Console.Write($"({test})[{terrain.terrainName}]{surfaces.surfIndex} :"); Console.WriteLine($"\t[{surface.minPitch} < {surface.maxPitch}]({surface.baseMaterials.First().materialDid}) - Vec3: {surface.vertexColor.First().vertexColor}"); } Console.WriteLine("--------"); } } } private void InitialiseTerrainDic() { foreach(var terrain in portalEngine.cTerrainDesc.terrains) { foreach (var surface in portalEngine.cSurfaceDesc.surfaces) { if (terrain.surfaceInfo == surface.surfIndex) { var id = surface.terrainMaterials.First().baseMaterials.First().materialDid; mapTerrain.Add((int)terrain.terrainIndex, id); break; } } } } private int GetIndex(DataId id) { foreach(var mat in mapTerrain) { if(mat.Value == id) return mat.Key; } return 0; } public void GenerateUV() { int count = (int)Math.Ceiling(Math.Sqrt(textureCoord.Count)); int atlasSize = (int)64 * count; int index = 0; foreach (var terrain in textureCoord) { int x = (index % count) * (int)64; int y = (index / count) * (int)64; textureCoord[index] = new Vector2(x, y); index++; } } }