237 lines
11 KiB
C#
237 lines
11 KiB
C#
using AC2RE.Definitions;
|
|
using LandblockExtraction.AtlasMaker;
|
|
using LandblockExtraction.DatEngine;
|
|
using LandblockExtraction.Tools;
|
|
using System;
|
|
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;
|
|
|
|
private int[] indiceBase;
|
|
|
|
public LandBlockExtrator(PortalEngine portalEngine, CellEngine cellEngine) {
|
|
this.portalEngine = portalEngine;
|
|
this.cellEngine = cellEngine;
|
|
|
|
terrainAtlasManager = new TerrainAtlasManager(portalEngine);
|
|
|
|
indiceBase = GenerateBasicIndices();
|
|
}
|
|
|
|
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.indices = indiceBase;
|
|
//blockStruct.verticesStruct.color[indice] = GenerateVertexColor(blockData.cellInfos[indice]);
|
|
//blockStruct.verticesStruct.farcolor[indice] = GenerateVertexFarColor(blockData.cellInfos[indice]);
|
|
blockStruct.verticesStruct.terraintype[indice] = GenerateVertexTerrainType(blockData.cellInfos[indice]);
|
|
}
|
|
}
|
|
|
|
GenerateBasicNormalandRighTexture(blockStruct);
|
|
DoubleEdgeVertices(blockStruct);
|
|
|
|
return blockStruct;
|
|
}
|
|
private void GenerateBasicNormalandRighTexture(BlockStruct blockStruct) {
|
|
for (int i = 0; i < blockStruct.indices.Length; i += 6) {
|
|
int index1 = blockStruct.indices[i];
|
|
int index2 = blockStruct.indices[i + 1];
|
|
int index3 = blockStruct.indices[i + 2];
|
|
int index4 = blockStruct.indices[i + 5];
|
|
|
|
Vector3 vertex1 = blockStruct.verticesStruct.position[index1];
|
|
Vector3 vertex2 = blockStruct.verticesStruct.position[index2];
|
|
Vector3 vertex3 = blockStruct.verticesStruct.position[index3];
|
|
Vector3 vertex4 = blockStruct.verticesStruct.position[index4];
|
|
|
|
var normal = MathOperations.CalculateQuadNormal(vertex1, vertex2, vertex3, vertex4);
|
|
var test = MathOperations.CalculateInclination(normal);
|
|
|
|
var sub1 = terrainAtlasManager.terrains[(int)blockStruct.verticesStruct.terraintype[index1].X].DetermineSubTerrain(test);
|
|
var sub2 = terrainAtlasManager.terrains[(int)blockStruct.verticesStruct.terraintype[index2].X].DetermineSubTerrain(test);
|
|
var sub3 = terrainAtlasManager.terrains[(int)blockStruct.verticesStruct.terraintype[index3].X].DetermineSubTerrain(test);
|
|
var sub4 = terrainAtlasManager.terrains[(int)blockStruct.verticesStruct.terraintype[index4].X].DetermineSubTerrain(test);
|
|
|
|
InitColorFarColorTerrain(index1, normal, sub1, blockStruct);
|
|
InitColorFarColorTerrain(index2, normal, sub2, blockStruct);
|
|
InitColorFarColorTerrain(index3, normal, sub3, blockStruct);
|
|
InitColorFarColorTerrain(index4, normal, sub4, blockStruct);
|
|
}
|
|
}
|
|
|
|
private void InitColorFarColorTerrain(int index, Vector3 normal, SubTerrain terrain, BlockStruct blockStruct) {
|
|
blockStruct.verticesStruct.terraintype[index].X = terrain.terrainIndex;
|
|
blockStruct.verticesStruct.color[index] = terrain.Color;
|
|
blockStruct.verticesStruct.farcolor[index] = terrain.farColor;
|
|
blockStruct.verticesStruct.normal[index] = normal;
|
|
}
|
|
|
|
|
|
private int[] GenerateBasicIndices() {
|
|
List<int> indices = new List<int>();
|
|
|
|
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)) - 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, portalEngine.landScapeDefs.landHeightTable[height], newY - 1020);
|
|
}
|
|
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<Vector3> newPositions = new List<Vector3>();
|
|
List<Vector3> newNormals = new List<Vector3>();
|
|
List<Vector4> newColors = new List<Vector4>();
|
|
List<Vector4> newFarColors = new List<Vector4>();
|
|
List<Vector2> newTexCoord = new List<Vector2>();
|
|
List<Vector4> newTerrainTypes = new List<Vector4>();
|
|
|
|
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];
|
|
Vector4 terrainType = new Vector4(blockStruct.verticesStruct.terraintype[one].X,
|
|
blockStruct.verticesStruct.terraintype[two].X,
|
|
blockStruct.verticesStruct.terraintype[three].X,
|
|
blockStruct.verticesStruct.terraintype[foor].X);
|
|
|
|
|
|
newPositions.Add(blockStruct.verticesStruct.position[one]);
|
|
newColors.Add(blockStruct.verticesStruct.color[one]);
|
|
newFarColors.Add(blockStruct.verticesStruct.farcolor[one]);
|
|
newNormals.Add(blockStruct.verticesStruct.normal[one]);
|
|
newTerrainTypes.Add(terrainType);
|
|
|
|
newPositions.Add(blockStruct.verticesStruct.position[two]);
|
|
newColors.Add(blockStruct.verticesStruct.color[two]);
|
|
newFarColors.Add(blockStruct.verticesStruct.farcolor[two]);
|
|
newNormals.Add(blockStruct.verticesStruct.normal[two]);
|
|
newTerrainTypes.Add(terrainType);
|
|
|
|
newPositions.Add(blockStruct.verticesStruct.position[three]);
|
|
newColors.Add(blockStruct.verticesStruct.color[three]);
|
|
newFarColors.Add(blockStruct.verticesStruct.farcolor[three]);
|
|
newNormals.Add(blockStruct.verticesStruct.normal[three]);
|
|
newTerrainTypes.Add(terrainType);
|
|
|
|
|
|
newPositions.Add(blockStruct.verticesStruct.position[foor]);
|
|
newColors.Add(blockStruct.verticesStruct.color[foor]);
|
|
newFarColors.Add(blockStruct.verticesStruct.farcolor[foor]);
|
|
newNormals.Add(blockStruct.verticesStruct.normal[foor]);
|
|
newTerrainTypes.Add(terrainType);
|
|
|
|
newTexCoord.Add(new(0, 0));
|
|
newTexCoord.Add(new(0, 1));
|
|
newTexCoord.Add(new(1, 0));
|
|
newTexCoord.Add(new(1, 1));
|
|
}
|
|
|
|
blockStruct.verticesStruct.position = newPositions.ToArray();
|
|
blockStruct.verticesStruct.normal = newNormals.ToArray();
|
|
blockStruct.verticesStruct.color = newColors.ToArray();
|
|
blockStruct.verticesStruct.farcolor = newFarColors.ToArray();
|
|
blockStruct.verticesStruct.texturecoord = newTexCoord.ToArray();
|
|
blockStruct.verticesStruct.terraintype = newTerrainTypes.ToArray();
|
|
|
|
blockStruct.indices = GenerateNewsIndices(newPositions.Count);
|
|
}
|
|
|
|
private int[] GenerateNewsIndices(int count) {
|
|
List<int> indices = new List<int>();
|
|
for (int i = 0; i < count; i = i + 4) {
|
|
indices.Add(i); //A
|
|
indices.Add(i + 1); //B
|
|
indices.Add(i + 2); //C
|
|
indices.Add(i + 2); //C
|
|
indices.Add(i + 1); //B
|
|
indices.Add(i + 3); //D
|
|
}
|
|
|
|
return indices.ToArray();
|
|
}
|
|
}
|
|
}
|