using AC2RE.Definitions; using LandblockExtraction.AtlasMaker; using LandblockExtraction.DatEngine; using LandblockExtraction.Tools; using System.Dynamic; using System.Numerics; namespace LandblockExtraction.LandBlockExtractor { public class LandBlockExtrator { private PortalEngine portalEngine; private CellEngine cellEngine; private TerrainAtlasManager terrainAtlasManager; private readonly int NumberLandBlocks = 255; private readonly int BlockSize = 17; private readonly int cellSize = 8; public LandBlockExtrator(PortalEngine portalEngine, CellEngine cellEngine) { this.portalEngine = portalEngine; this.cellEngine = cellEngine; terrainAtlasManager = new TerrainAtlasManager(portalEngine); terrainAtlasManager.ExtractTexture(); terrainAtlasManager.GenerateUV(); } public BlockStruct? GetBlock(int landX, int landY) { CellId landBlockId = new CellId((byte)landX, (byte)landY, 0xFF, 0xFF); var landBlock = cellEngine.GetLandBlockData(landBlockId.id); if (landBlock == null) return null; return GenerateBlockStructByData(landBlock, landX, landY); } public BlockStruct GenerateBlockStructByData(CLandBlockData blockData, int landX, int landY) { BlockStruct blockStruct = new BlockStruct(); for (int y = 0; y < BlockSize; y++) { for (int x = 0; x < BlockSize; x++) { var indice = y * BlockSize + x; blockStruct.verticesStruct.position[indice] = GenerateVertexPosition(landX, landY, x, y, blockData.heights[indice]); blockStruct.verticesStruct.color[indice] = GenerateVertexColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.farcolor[indice] = GenerateVertexFarColor(blockData.cellInfos[indice]); blockStruct.verticesStruct.terraintype[indice] = GenerateVertexTerrainType(blockData.cellInfos[indice]); blockStruct.indices = GenerateBasicIndices(); } } DoubleEdgeVertices(blockStruct); return blockStruct; } private int[] GenerateBasicIndices() { List indices = new List(); for (int y = 0; y < BlockSize - 1; y++) { for (int x = 0; x < BlockSize - 1; x++) { // Indices des sommets du premier triangle indices.Add(y * BlockSize + x); indices.Add((y + 1) * BlockSize + x); indices.Add(y * BlockSize + x + 1); // Indices des sommets du deuxième triangle indices.Add(y * BlockSize + x + 1); indices.Add((y + 1) * BlockSize + x); indices.Add((y + 1) * BlockSize + x + 1); } } return indices.ToArray(); } private Vector4 GenerateVertexTerrainType(uint cellInfo) { var terrain = MathOperations.GetTerrainInCellInfo(cellInfo); return new(terrain, 0f, 0f, 0f); } private Vector3 GenerateVertexPosition(int landx, int landy, int x, int y, byte height) { int tmpx = (landx * BlockSize + y) * cellSize; int tmpy = (BlockSize * NumberLandBlocks * cellSize) - ((landy * BlockSize + x) * cellSize) - 1; var newX = (tmpx - (NumberLandBlocks * BlockSize * cellSize / 2)); var newY = (tmpy - ((NumberLandBlocks * BlockSize * cellSize) - (NumberLandBlocks * BlockSize * cellSize / 2) - 1)); return new Vector3(newX, portalEngine.landScapeDefs.landHeightTable[height], newY); } private Vector4 GenerateVertexColor(uint cellInfo) { var terrain = MathOperations.GetTerrainInCellInfo(cellInfo); foreach (var terrainType in portalEngine.cTerrainDesc.terrains) { if (terrainType.terrainIndex == terrain) { foreach (var surfaceIndex in portalEngine.cSurfaceDesc.surfaces) { if (surfaceIndex.surfIndex == terrainType.surfaceInfo) { var color = surfaceIndex.terrainMaterials.First().vertexColor.First().vertexColor; return MathOperations.RGBAColorToVector4(color); } } } } return Vector4.One; } private Vector4 GenerateVertexFarColor(uint cellInfo) { var terrain = MathOperations.GetTerrainInCellInfo(cellInfo); foreach (var terrainType in portalEngine.cTerrainDesc.terrains) { if (terrainType.terrainIndex == terrain) { foreach (var surfaceIndex in portalEngine.cSurfaceDesc.surfaces) { if (surfaceIndex.surfIndex == terrainType.surfaceInfo) { var color = surfaceIndex.terrainMaterials.First().vertexColor.First().farVertexColor; return MathOperations.RGBAColorToVector4(color); } } } } return Vector4.One; } //TEST public void DoubleEdgeVertices(BlockStruct blockStruct) { List newPositions = new List(); List newColors = new List(); List newFarColors = new List(); List newTexCoord = new List(); List newTerrainTypes = new List(); List newRealTerrainType = new List(); int originalVertexCount = blockStruct.verticesStruct.position.Length; int originalIndicesCount = blockStruct.indices.Length; // Doubler les sommets sur le bord supérieur et inférieur for(int i = 0; i < originalIndicesCount; i = i + 6) { var one = blockStruct.indices[i + 0]; var two = blockStruct.indices[i + 1]; var three = blockStruct.indices[i + 2]; var foor = blockStruct.indices[i + 5]; newPositions.Add(blockStruct.verticesStruct.position[one]); newColors.Add(blockStruct.verticesStruct.color[one]); newFarColors.Add(blockStruct.verticesStruct.farcolor[one]); newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, blockStruct.verticesStruct.terraintype[two].X, blockStruct.verticesStruct.terraintype[three].X, blockStruct.verticesStruct.terraintype[foor].X)); newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[one].X); newPositions.Add(blockStruct.verticesStruct.position[two]); newColors.Add(blockStruct.verticesStruct.color[two]); newFarColors.Add(blockStruct.verticesStruct.farcolor[two]); newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, blockStruct.verticesStruct.terraintype[two].X, blockStruct.verticesStruct.terraintype[three].X, blockStruct.verticesStruct.terraintype[foor].X)); newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[two].X); newPositions.Add(blockStruct.verticesStruct.position[three]); newColors.Add(blockStruct.verticesStruct.color[three]); newFarColors.Add(blockStruct.verticesStruct.farcolor[three]); newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, blockStruct.verticesStruct.terraintype[two].X, blockStruct.verticesStruct.terraintype[three].X, blockStruct.verticesStruct.terraintype[foor].X)); newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[three].X); newPositions.Add(blockStruct.verticesStruct.position[foor]); newColors.Add(blockStruct.verticesStruct.color[foor]); newFarColors.Add(blockStruct.verticesStruct.farcolor[foor]); newTerrainTypes.Add(new Vector4(blockStruct.verticesStruct.terraintype[one].X, blockStruct.verticesStruct.terraintype[two].X, blockStruct.verticesStruct.terraintype[three].X, blockStruct.verticesStruct.terraintype[foor].X)); newRealTerrainType.Add(blockStruct.verticesStruct.terraintype[foor].X); newTexCoord.Add(new(0, 0)); newTexCoord.Add(new(0, 1)); newTexCoord.Add(new(1, 0)); newTexCoord.Add(new(1, 1)); } // Ajouter les nouveaux sommets à la structure BlockStruct (étape 2) // Vous devez également mettre à jour les indices dans blockStruct.indices blockStruct.verticesStruct.position = newPositions.ToArray(); blockStruct.verticesStruct.color = newColors.ToArray(); blockStruct.verticesStruct.farcolor = newFarColors.ToArray(); blockStruct.verticesStruct.texturecoord = newTexCoord.ToArray(); blockStruct.verticesStruct.terraintype = newTerrainTypes.ToArray(); blockStruct.verticesStruct.realtype = newRealTerrainType.ToArray(); blockStruct.indices = GenerateNewsIndices(newPositions.Count); } private int[] GenerateNewsIndices(int count) { List indices = new List(); for(int i = 0; i < count; i = i + 4) { indices.Add(i); indices.Add(i + 1); indices.Add(i + 2); indices.Add(i + 2); indices.Add(i + 1); indices.Add(i + 3); } return indices.ToArray(); } } }