Files
bworld/client/workers/chunk_messages.ts
T
2026-09-26 11:38:32 -03:00

107 lines
3.3 KiB
TypeScript

import type { BlockRegistry } from "$/common/everything_registry.ts";
import type { SpriteRegion } from "$/common/constants.ts";
import type { OreJson } from "$/common/mod_data.ts";
import type { ModelJson } from "$/common/block_models.ts";
import type { SortType } from "./translucent_sort.ts";
// messages between the main thread and the chunk workers
// a terrain vertex, 24 bytes: position as float32x3, atlas uv as unorm16x2, directional shade times ambient occlusion
// and alpha as unorm8x4 (shade repeated in rgb), and lightmap coordinates as unorm8x2 plus two unused bytes
export const TERRAIN_VERTEX_BYTES = 24;
export const TERRAIN_QUAD_BYTES = 4 * TERRAIN_VERTEX_BYTES;
// solid and cutout quads are grouped by the way they face, so groups facing away from the camera can be skipped, like
// sodium's block face culling. the groups follow FACE_NORMALS' order, then the quads that aren't axis aligned
export const FACE_GROUPS = 7;
export const UNALIGNED_GROUP = 6;
export interface FaceGroup {
first: number;
count: number;
// the lowest and highest plane the group's quads lie on, along its axis
min: number;
max: number;
}
export type ToChunkWorker =
| {
type: "init";
// the blocks registry without its functions, indexed by numeric id
blocks_registry: BlockRegistry[];
block_ids: Record<string, number>;
// mods' block models by id, the engine's are built in
models: Record<string, ModelJson>;
textures_info: Record<string, SpriteRegion>;
image: { width: number; height: number };
// mods' worldgen scripts and ores, so generation matches the server
worldgen_scripts: { mod: string; url: string }[];
ores: OreJson[];
}
| { type: "generate"; chunk_x: number; chunk_z: number; seed: string }
| {
type: "mesh";
chunk_x: number;
chunk_z: number;
version: number;
// copies of the blocks of the 3x3 chunks around it, going +x then +z from -x -z, for lighting
chunks: (Uint32Array | null)[];
// where the camera is, to sort the translucent quads
camera: number[];
}
| {
type: "sort";
chunk_x: number;
chunk_z: number;
version: number;
sort_version: number;
centers: Float32Array;
camera: number[];
};
// 4 vertices per quad, TERRAIN_VERTEX_BYTES each
export interface LayerMesh {
vertices: Uint8Array<ArrayBuffer>;
quad_count: number;
// solid and cutout only, see FACE_GROUPS. the quads are stored group after group
groups?: FaceGroup[];
}
export type FromChunkWorker =
| {
type: "generated";
chunk_x: number;
chunk_z: number;
blocks: Uint32Array;
// blocks that landed in other chunks (from features like a mod's trees), flattened as x, y, z, numeric id
spills: Int32Array;
}
| {
type: "meshed";
chunk_x: number;
chunk_z: number;
version: number;
// the lowest and highest y of the chunk's quads, for frustum culling
min_y: number;
max_y: number;
solid: LayerMesh;
cutout: LayerMesh;
translucent: LayerMesh & {
// sorted back to front for the camera the mesh was requested with
indices: Uint32Array;
sort_type: SortType;
// what resorting needs, see translucent_sort.ts
centers: Float32Array;
planes: [Float32Array, Float32Array, Float32Array];
};
camera: number[];
}
| {
type: "sorted";
chunk_x: number;
chunk_z: number;
version: number;
sort_version: number;
indices: Uint32Array;
};