/**
 * Мешер мира: чанк мешается через world.get, поэтому culled и AO на швах
 * между чанками бесшовны (соседей за границей видно). Чистая математика.
 */
import type { VoxelPalette } from '../voxel/grid';
import { meshRegion } from '../voxel/mesher';
import type { MeshOptions, RegionBounds, VoxelMesh } from '../voxel/mesher';
import type { VoxelWorld } from './world';
import { CHUNK_SX, CHUNK_SZ } from './chunk';

/** Полуинтервал области чанка в мировых координатах. */
export function chunkBounds(cx: number, cz: number, sy: number): RegionBounds {
    return {
        x0: cx * CHUNK_SX, x1: (cx + 1) * CHUNK_SX,
        y0: 0, y1: sy,
        z0: cz * CHUNK_SZ, z1: (cz + 1) * CHUNK_SZ,
    };
}

/** Меш одного чанка; соседи берутся из мира (шов бесшовный). Слой тайлей —
 *  из мира (opts.texAt переопределяет). */
export function meshChunk(world: VoxelWorld, cx: number, cz: number, palette: VoxelPalette, opts: MeshOptions = {}): VoxelMesh {
    return meshRegion(
        (x, y, z) => world.get(x, y, z),
        chunkBounds(cx, cz, world.chunkHeight),
        palette,
        { ...opts, texAt: opts.texAt ?? ((x, y, z) => world.getTex(x, y, z)) },
    );
}