// W1 —— 一个区块的地形几何(heightmap -> 顶点 / 法线 / 索引),纯数学、无 godot 依赖。 // 三角划分与法线照 GameLib/AreaTerrain.cpp CTerrain::GetHeight / CalculateNormal。 // SHINSOO §9-W1。 // // 129×129 可见顶点,128×128 quad。每个 quad 对角线 = TL->BR(GetHeight 的 h1/h2)。 // 顶点已做 Metin2(cm,Z-up) -> Godot(m,Y-up) 转换(m2_coord),并加了区块原点。 #pragma once #include #include #include "terrain_files.h" namespace fmt { struct TerrainMesh { static constexpr int VERTS_XY = 129; // XSIZE+1 static constexpr int QUADS_XY = 128; // XSIZE std::vector positions; // 3/vert,Godot 空间(米,Y-up),含区块原点 std::vector normals; // 3/vert,Godot 空间,单位向量 std::vector uvs; // 2/vert,区块内 [0,1](用于 splat / 地表贴图) std::vector indices; // 3/tri,6/quad float min_y = 0, max_y = 0; // Godot Y(高度)范围,做 custom_aabb / 相机用 int vertex_count() const { return VERTS_XY * VERTS_XY; } int index_count() const { return QUADS_XY * QUADS_XY * 6; } }; // height_scale 从 MapSetting 取(A1 = 0.5)。tile_x/tile_y 决定区块原点。 // ccw_from_above=true:三角绕序在 Godot 里从上方看为逆时针(默认,若发现背面朝上则传 false)。 void build_terrain_mesh(const HeightMap& hm, int tile_x, int tile_y, double height_scale, TerrainMesh& out, bool ccw_from_above = true); // 与 CTerrain::GetHeight 一致的三角插值。lx/ly = 区块本地厘米([0, 128*200])。 // 返回厘米高度(未转 Godot 单位)。 double terrain_height_at(const HeightMap& hm, double lx_cm, double ly_cm, double height_scale); } // namespace fmt