using AC2RE.Definitions; using LandblockExtraction.AtlasMaker; using LandblockExtraction.DatEngine; using LandblockExtraction.Tools; using System.Numerics; namespace LandblockExtraction.WorldMap; public class WorldMap { private readonly int NumberLandBlocks = 254; private readonly int BlockSize = 17; private readonly int cellSize = 8; private PortalEngine portalEngine; private CellEngine cellEngine; private TerrainAtlasManager terrainAtlasManager; private VertexMap[,] vertexMaps; public WorldMap(PortalEngine portalEngine, CellEngine cellEngine) { this.portalEngine = portalEngine; this.cellEngine = cellEngine; terrainAtlasManager = new TerrainAtlasManager(portalEngine); int globalSize = NumberLandBlocks * (BlockSize - 1); vertexMaps = new VertexMap[globalSize, globalSize]; } private void InitializeBaseMap() { for (int landY = 0; landY <= NumberLandBlocks; landY++) { for (int landX = 0; landX <= NumberLandBlocks; landX++) { InitializeCellMap(landY, landX); } } } public void LoadRegion(int start, int end) { for (int landY = start; landY <= end; landY++) { for (int landX = start; landX <= end; landX++) { InitializeCellMap(landY, landX); } } } private void InitializeCellMap(int landx, int landy) { CellId landBlockId = new CellId((byte)landx, (byte)landy, 0xFF, 0xFF); var landBlock = cellEngine.GetLandBlockData(landBlockId.id); for (int y = 0; y < BlockSize; y++) { for (int x = 0; x < BlockSize; x++) { float height = 0; Vector4 color = Vector4.Zero; // Calculer les indices globaux en prenant en compte la position du land int indiceX = landx * (BlockSize - 1) + y; int indiceY = landy * (BlockSize - 1) + x; if (landBlock != null) { height = GetHeightInLandBlock(landBlock, x, y); color = GetColorVertex(landBlock, x, y); } // Vérifier si les indices ne dépassent pas la taille globale de la grille if (indiceX < NumberLandBlocks * (BlockSize - 1) && indiceY < NumberLandBlocks * (BlockSize - 1)) { vertexMaps[indiceX, indiceY] = new VertexMap() { Position = GenerateVertexPosition(landx, landy, x, y, height), Color = color }; } } } } private float GetHeightInLandBlock(CLandBlockData block, int x, int y) { var indice = y * BlockSize + x; return block.heights[indice]; } private Vector4 GetColorVertex(CLandBlockData block, int x, int y) { var indice = y * BlockSize + x; var terrain = MathOperations.GetTerrainInCellInfo(block.cellInfos[indice]); return terrainAtlasManager.terrains[(int)terrain].subTerrains.First().Color; } public float[] GetAllVertices() { List verticesList = new List(); int rowLength = NumberLandBlocks * (BlockSize - 1); for (int y = 0; y < rowLength; y++) { for (int x = 0; x < rowLength; x++) { // Ajouter la position du vertex à la liste verticesList.Add(vertexMaps[x, y].Position.X); verticesList.Add(vertexMaps[x, y].Position.Y); verticesList.Add(vertexMaps[x, y].Position.Z); // Ajouter la couleur si nécessaire verticesList.Add(vertexMaps[x, y].Color.X); verticesList.Add(vertexMaps[x, y].Color.Y); verticesList.Add(vertexMaps[x, y].Color.Z); verticesList.Add(vertexMaps[x, y].Color.W); } } return verticesList.ToArray(); } public int[] GenerateRegionIndices(int start, int end) { List indices = new List(); // Calcul de la longueur de la ligne pour la région spécifiée int rowLength = (end - start) * (BlockSize - 1); // Parcours de chaque "cellule" de la grille pour la région spécifiée for (int y = 0; y < rowLength; y++) { for (int x = 0; x < rowLength; x++) { int baseX = start * (BlockSize - 1); int baseY = start * (BlockSize - 1); int topLeft = (y + baseY) * (NumberLandBlocks * (BlockSize - 1)) + (x + baseX); int topRight = topLeft + 1; int bottomLeft = topLeft + (NumberLandBlocks * (BlockSize - 1)); int bottomRight = bottomLeft + 1; indices.Add(topLeft); indices.Add(bottomLeft); indices.Add(bottomRight); indices.Add(bottomLeft); indices.Add(bottomRight); indices.Add(topRight); } } return indices.ToArray(); } public int[] GenerateIndices() { List indices = new List(); int rowLength = NumberLandBlocks * (BlockSize - 1); // Parcourir chaque "cellule" de la grille, sauf la dernière colonne et la dernière ligne for (int y = 0; y < rowLength - 1; y++) { for (int x = 0; x < rowLength - 1; x++) { // Calculer les indices des 4 sommets du carré courant int topLeft = y * rowLength + x; int topRight = topLeft + 1; int bottomLeft = topLeft + rowLength; int bottomRight = bottomLeft + 1; // Ajouter les indices pour former les deux triangles indices.Add(topLeft); indices.Add(bottomLeft); indices.Add(bottomRight); indices.Add(bottomLeft); indices.Add(bottomRight); indices.Add(topRight); } } return indices.ToArray(); } private Vector3 GenerateVertexPosition(int landx, int landy, int x, int y, float height) { int tmpx = (landx * BlockSize + y) * cellSize; int tmpy = (BlockSize * NumberLandBlocks * cellSize) - ((landy * BlockSize + x) * cellSize) - 1; var newX = (tmpx - (NumberLandBlocks * BlockSize * cellSize / 2)) - landx * cellSize;// (tmpx - (NumberLandBlocks * BlockSize * cellSize / 2)); var newY = (tmpy - ((NumberLandBlocks * BlockSize * cellSize) - (NumberLandBlocks * BlockSize * cellSize / 2) - 1)) + landy * cellSize; //(tmpy - ((NumberLandBlocks * BlockSize * cellSize) - (NumberLandBlocks * BlockSize * cellSize / 2) - 1)); return new Vector3(newX + 1020, height, newY - 1020); } }