Tree generation
This commit is contained in:
@@ -38,6 +38,9 @@ export interface Chunk {
|
||||
meshes: Partial<Record<RenderLayer, ChunkMesh>>;
|
||||
// only for translucent meshes that have to be sorted again as the camera moves
|
||||
translucent_sort?: TranslucentSort;
|
||||
// blocks its generation put in neighboring chunks (leaves), as x, y, z, numeric id. kept so a neighbor that
|
||||
// generates later, or unloads and comes back, still gets them
|
||||
spills?: Int32Array;
|
||||
}
|
||||
|
||||
export interface ChunkMesh {
|
||||
@@ -491,7 +494,7 @@ export class ClientLevel {
|
||||
|
||||
let chunk = this.chunks.get(key);
|
||||
if (chunk) {
|
||||
// a placeholder made by a neighbor's feature, keep its blocks where generation left air
|
||||
// blocks placed here before it generated, keep them where generation left air
|
||||
const existing = chunk.blocks;
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
if (blocks[i] !== AIR) {
|
||||
@@ -503,7 +506,16 @@ export class ClientLevel {
|
||||
}
|
||||
chunk.generated = true;
|
||||
chunk.dirty = true;
|
||||
chunk.spills = spills;
|
||||
|
||||
// the same rules as the server (server/game/world.ts): a chunk's own blocks, then what its neighbors'
|
||||
// features put in it, only where it has air. both ways, since the neighbors may have generated first
|
||||
for (const [dx, dz] of ALL_NEIGHBOR_OFFSETS) {
|
||||
const neighbor_spills = this.get_chunk(cx + dx, cz + dz)?.spills;
|
||||
if (neighbor_spills) {
|
||||
this.#apply_spills(neighbor_spills, chunk);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < spills.length; i += 4) {
|
||||
this.#set_block_raw(spills[i], spills[i + 1], spills[i + 2], spills[i + 3]);
|
||||
}
|
||||
@@ -583,7 +595,11 @@ export class ClientLevel {
|
||||
}
|
||||
const chunk_x = Math.floor(x / CHUNK_SIZE);
|
||||
const chunk_z = Math.floor(z / CHUNK_SIZE);
|
||||
const chunk = this.get_chunk(chunk_x, chunk_z) ?? this.add_chunk(chunk_x, chunk_z);
|
||||
const chunk = this.get_chunk(chunk_x, chunk_z);
|
||||
// a chunk that isn't generated yet takes it from our spills when it is
|
||||
if (!chunk?.generated) {
|
||||
return;
|
||||
}
|
||||
const lx = x - chunk_x * CHUNK_SIZE;
|
||||
const lz = z - chunk_z * CHUNK_SIZE;
|
||||
const index = y * CHUNK_AREA + lz * CHUNK_SIZE + lx;
|
||||
@@ -594,6 +610,15 @@ export class ClientLevel {
|
||||
}
|
||||
}
|
||||
|
||||
// the spills that land in chunk
|
||||
#apply_spills(spills: Int32Array, chunk: Chunk) {
|
||||
for (let i = 0; i < spills.length; i += 4) {
|
||||
if (Math.floor(spills[i] / CHUNK_SIZE) === chunk.x && Math.floor(spills[i + 2] / CHUNK_SIZE) === chunk.z) {
|
||||
this.#set_block_raw(spills[i], spills[i + 1], spills[i + 2], spills[i + 3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete_chunk_mesh(chunk: Chunk) {
|
||||
for (const mesh of Object.values(chunk.meshes)) {
|
||||
destroy_buffer(mesh.vertex_buffer);
|
||||
|
||||
Reference in New Issue
Block a user