minerender 2.1.0-alpha.142 → 2.1.0-alpha.144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/browser/esm/index.browser.d.mts +21 -4
- package/dist/browser/esm/util/util.mjs +0 -2
- package/dist/browser/esm/util/util.mjs.map +1 -1
- package/dist/browser/esm/world/Chunk.mjs +62 -33
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +98 -13
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/SectionModels.mjs +21 -15
- package/dist/browser/esm/world/SectionModels.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +109 -15
- package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
- package/dist/browser/index.d.ts +21 -4
- package/dist/browser/index.js +289 -78
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +289 -78
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +21 -4
- package/dist/node/index.d.ts +21 -4
- package/dist/node/index.js +289 -78
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +289 -78
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -34068,8 +34068,6 @@ void main() {
|
|
|
34068
34068
|
});
|
|
34069
34069
|
}
|
|
34070
34070
|
function yieldToEventLoop() {
|
|
34071
|
-
const scheduler = globalThis.scheduler;
|
|
34072
|
-
if (scheduler?.yield) return scheduler.yield();
|
|
34073
34071
|
return new Promise((resolve) => {
|
|
34074
34072
|
if (typeof MessageChannel !== "undefined") {
|
|
34075
34073
|
const channel = new MessageChannel();
|
|
@@ -103239,6 +103237,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103239
103237
|
init_dirname();
|
|
103240
103238
|
init_buffer2();
|
|
103241
103239
|
init_process2();
|
|
103240
|
+
init_BlockObject();
|
|
103242
103241
|
init_three_module();
|
|
103243
103242
|
init_BlockStates();
|
|
103244
103243
|
init_AssetKey();
|
|
@@ -103252,6 +103251,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103252
103251
|
init_util();
|
|
103253
103252
|
init_AssetKey();
|
|
103254
103253
|
init_BlockStates();
|
|
103254
|
+
init_BlockEntities();
|
|
103255
103255
|
init_CubeFace();
|
|
103256
103256
|
|
|
103257
103257
|
// src/world/SectionModels.ts
|
|
@@ -103352,6 +103352,10 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103352
103352
|
biomeTint: source ? [...templates.values()].some((template) => template.biomeTint?.some((value) => value === 1)) || void 0 : void 0
|
|
103353
103353
|
};
|
|
103354
103354
|
}
|
|
103355
|
+
/** Starts loading the state's models and atlases so a later `prepareState` with the same properties finds them loaded. */
|
|
103356
|
+
async preload(blockState3, properties = {}) {
|
|
103357
|
+
await this.state(blockState3, properties);
|
|
103358
|
+
}
|
|
103355
103359
|
async state(blockState3, properties) {
|
|
103356
103360
|
let states = this.states.get(blockState3);
|
|
103357
103361
|
if (!states) this.states.set(blockState3, states = /* @__PURE__ */ new Map());
|
|
@@ -103374,22 +103378,24 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103374
103378
|
async prepare(blockState3, properties) {
|
|
103375
103379
|
const state = { ...await BlockStateResolver.defaults(blockState3), ...properties };
|
|
103376
103380
|
const groups = BlockStateResolver.matching(blockState3, state);
|
|
103377
|
-
if (!groups.length) return void 0;
|
|
103381
|
+
if (!groups.length || groups.some((group) => Array.isArray(group) && !group.length)) return void 0;
|
|
103382
|
+
const variants = groups.flatMap((group) => Array.isArray(group) ? group : [group]);
|
|
103383
|
+
if (variants.some((variant) => !variant.model)) return void 0;
|
|
103384
|
+
const settled = await Promise.allSettled(variants.map(async (variant) => {
|
|
103385
|
+
const modelKey = AssetKey.parse("models", variant.model);
|
|
103386
|
+
modelKey.root = blockState3.key?.root;
|
|
103387
|
+
const model = await Models.getMerged(modelKey);
|
|
103388
|
+
if (!model?.elements?.length) return void 0;
|
|
103389
|
+
const atlas = await UVMapper.getAtlas(model);
|
|
103390
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
103391
|
+
if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
|
|
103392
|
+
return { model, atlas, rotation };
|
|
103393
|
+
}));
|
|
103378
103394
|
const prepared = /* @__PURE__ */ new Map();
|
|
103379
|
-
for (const
|
|
103380
|
-
|
|
103381
|
-
if (!
|
|
103382
|
-
|
|
103383
|
-
if (!variant.model) return void 0;
|
|
103384
|
-
const modelKey = AssetKey.parse("models", variant.model);
|
|
103385
|
-
modelKey.root = blockState3.key?.root;
|
|
103386
|
-
const model = await Models.getMerged(modelKey);
|
|
103387
|
-
if (!model?.elements?.length) return void 0;
|
|
103388
|
-
const atlas = await UVMapper.getAtlas(model);
|
|
103389
|
-
const rotation = BlockStateResolver.rotation(variant);
|
|
103390
|
-
if (!atlas || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize) return void 0;
|
|
103391
|
-
prepared.set(variant, { model, atlas, rotation });
|
|
103392
|
-
}
|
|
103395
|
+
for (const [i4, result] of settled.entries()) {
|
|
103396
|
+
if (result.status === "rejected") throw result.reason;
|
|
103397
|
+
if (!result.value) return void 0;
|
|
103398
|
+
prepared.set(variants[i4], result.value);
|
|
103393
103399
|
}
|
|
103394
103400
|
return { state, groups, choices: prepared };
|
|
103395
103401
|
}
|
|
@@ -103867,6 +103873,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103867
103873
|
// src/world/MineRenderWorld.ts
|
|
103868
103874
|
init_log();
|
|
103869
103875
|
var log21 = logger("MineRenderWorld");
|
|
103876
|
+
var YIELD_INTERVAL_MS = 8;
|
|
103870
103877
|
var MineRenderWorld = class {
|
|
103871
103878
|
constructor(scene, options = {}) {
|
|
103872
103879
|
this._chunks = /* @__PURE__ */ new Map();
|
|
@@ -103980,7 +103987,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103980
103987
|
failures.set(chunk, error2);
|
|
103981
103988
|
if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) === chunk) this.pendingBiomes.set(chunk, void 0);
|
|
103982
103989
|
}
|
|
103983
|
-
if (performance.now() - sliceStart >
|
|
103990
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
103984
103991
|
await yieldToEventLoop();
|
|
103985
103992
|
sliceStart = performance.now();
|
|
103986
103993
|
}
|
|
@@ -104081,15 +104088,18 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104081
104088
|
const key = AssetKey.parse("blockstates", block.type);
|
|
104082
104089
|
keys.set(key.serialize(), key);
|
|
104083
104090
|
}
|
|
104084
|
-
await BlockStates.getAll(keys.values());
|
|
104091
|
+
const loaded = await BlockStates.getAll(keys.values());
|
|
104092
|
+
const states = new Map([...keys.keys()].map((key, i4) => [key, loaded[i4]]));
|
|
104085
104093
|
if (!useBatches) {
|
|
104086
104094
|
for (const block of multiblock.blocks) await place(block);
|
|
104087
104095
|
return;
|
|
104088
104096
|
}
|
|
104089
104097
|
if (!executor) {
|
|
104090
104098
|
const groups2 = /* @__PURE__ */ new Map();
|
|
104099
|
+
const distinct = /* @__PURE__ */ new Map();
|
|
104091
104100
|
const position = new Vector3();
|
|
104092
104101
|
for (const block of multiblock.blocks) {
|
|
104102
|
+
if (this.sectionModels && !Chunk.isAir(block)) distinct.set(ChunkData.paletteKey(block), block);
|
|
104093
104103
|
const [x4, y5, z4] = block.position;
|
|
104094
104104
|
this.validatePosBounds(position.set(x4, y5, z4));
|
|
104095
104105
|
const cx = Math.floor(x4 / 16), cy = Math.floor(y5 / 16), cz = Math.floor(z4 / 16);
|
|
@@ -104100,6 +104110,16 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104100
104110
|
if (!group) groups2.set(chunk, group = []);
|
|
104101
104111
|
group.push({ index: (y5 - cy * 16) * 256 + (z4 - cz * 16) * 16 + x4 - cx * 16, block });
|
|
104102
104112
|
}
|
|
104113
|
+
if (this.sectionModels) {
|
|
104114
|
+
for (const block of distinct.values()) {
|
|
104115
|
+
const state = states.get(AssetKey.parse("blockstates", block.type).serialize());
|
|
104116
|
+
if (!state) continue;
|
|
104117
|
+
void (async () => {
|
|
104118
|
+
if (state.key && BlockEntities.entry(await BlockEntities.getIndex(state.key.root), state.key.toNamespacedString())) return;
|
|
104119
|
+
await this.sectionModels.preload(state, block.properties);
|
|
104120
|
+
})().catch(() => void 0);
|
|
104121
|
+
}
|
|
104122
|
+
}
|
|
104103
104123
|
await this.placeChunkGroups(groups2, changes);
|
|
104104
104124
|
return;
|
|
104105
104125
|
}
|
|
@@ -104135,7 +104155,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104135
104155
|
)));
|
|
104136
104156
|
for (const pos of positions) changes.set(`${pos.x},${pos.y},${pos.z}`, pos);
|
|
104137
104157
|
}
|
|
104138
|
-
if (performance.now() - sliceStart >
|
|
104158
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104139
104159
|
await yieldToEventLoop();
|
|
104140
104160
|
sliceStart = performance.now();
|
|
104141
104161
|
}
|
|
@@ -104143,6 +104163,62 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104143
104163
|
}
|
|
104144
104164
|
/** Replaces a chunk column's blocks, biomes, and saved light and, with `renderEntities`, its supported saved mobs. */
|
|
104145
104165
|
async placeChunk(chunk, executor) {
|
|
104166
|
+
return this.placeColumn(chunk, executor);
|
|
104167
|
+
}
|
|
104168
|
+
/**
|
|
104169
|
+
* Replaces parsed columns in input order, then refreshes neighboring geometry once.
|
|
104170
|
+
* Duplicate coordinates retain their order. A failed column stops placement; queued refreshes finish before rejection.
|
|
104171
|
+
*/
|
|
104172
|
+
async placeChunks(chunks) {
|
|
104173
|
+
const columns = [];
|
|
104174
|
+
for (const chunk of chunks) {
|
|
104175
|
+
const { x: x4, z: z4 } = chunk ?? {};
|
|
104176
|
+
if (![x4, z4].every(Number.isSafeInteger)) {
|
|
104177
|
+
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
104178
|
+
}
|
|
104179
|
+
const sections = Array.from(chunk.sections, (section) => {
|
|
104180
|
+
const { y: y5 } = section ?? {};
|
|
104181
|
+
if (!Number.isSafeInteger(y5)) throw new RangeError("Chunk section coordinates must be safe integers");
|
|
104182
|
+
return { ...section, y: y5 };
|
|
104183
|
+
});
|
|
104184
|
+
columns.push({ ...chunk, x: x4, z: z4, sections });
|
|
104185
|
+
}
|
|
104186
|
+
if (!columns.length) return;
|
|
104187
|
+
await this.culling;
|
|
104188
|
+
let failed = false, failure, sliceStart = performance.now();
|
|
104189
|
+
try {
|
|
104190
|
+
for (const column of columns) {
|
|
104191
|
+
await this.placeColumn(column, void 0, true);
|
|
104192
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104193
|
+
await yieldToEventLoop();
|
|
104194
|
+
sliceStart = performance.now();
|
|
104195
|
+
}
|
|
104196
|
+
}
|
|
104197
|
+
} catch (error2) {
|
|
104198
|
+
failed = true;
|
|
104199
|
+
failure = error2;
|
|
104200
|
+
} finally {
|
|
104201
|
+
try {
|
|
104202
|
+
const failures = await this.refreshBiomes(true);
|
|
104203
|
+
if (failures.size) log21.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
104204
|
+
} catch (error2) {
|
|
104205
|
+
if (!failed) {
|
|
104206
|
+
failed = true;
|
|
104207
|
+
failure = error2;
|
|
104208
|
+
}
|
|
104209
|
+
}
|
|
104210
|
+
try {
|
|
104211
|
+
await this.updateCulling([]);
|
|
104212
|
+
} catch (error2) {
|
|
104213
|
+
if (!failed) {
|
|
104214
|
+
failed = true;
|
|
104215
|
+
failure = error2;
|
|
104216
|
+
}
|
|
104217
|
+
}
|
|
104218
|
+
}
|
|
104219
|
+
if (failed) throw failure;
|
|
104220
|
+
}
|
|
104221
|
+
async placeColumn(chunk, executor, deferCulling = false) {
|
|
104146
104222
|
if (![chunk.x, chunk.z].every(Number.isSafeInteger)) {
|
|
104147
104223
|
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
104148
104224
|
}
|
|
@@ -104204,7 +104280,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104204
104280
|
} finally {
|
|
104205
104281
|
this.markSectionChanged(target);
|
|
104206
104282
|
}
|
|
104207
|
-
if (performance.now() - sliceStart >
|
|
104283
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104208
104284
|
await yieldToEventLoop();
|
|
104209
104285
|
sliceStart = performance.now();
|
|
104210
104286
|
}
|
|
@@ -104227,9 +104303,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104227
104303
|
await placeEntities?.();
|
|
104228
104304
|
} finally {
|
|
104229
104305
|
this.markBiomesChanged(chunk.x, chunk.z, void 0, false);
|
|
104230
|
-
|
|
104231
|
-
|
|
104232
|
-
|
|
104306
|
+
if (deferCulling) await this.updateCulling([...changes.values()], true);
|
|
104307
|
+
else {
|
|
104308
|
+
const failures = await this.refreshBiomes();
|
|
104309
|
+
if (failures.size) log21.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
104310
|
+
await this.updateCulling([...changes.values()]);
|
|
104311
|
+
}
|
|
104233
104312
|
}
|
|
104234
104313
|
}
|
|
104235
104314
|
/**
|
|
@@ -104259,7 +104338,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104259
104338
|
for (const { x: x4, z: z4 } of columns.values()) {
|
|
104260
104339
|
this.entities?.clearColumn(x4, z4);
|
|
104261
104340
|
await this.clearChunkColumn(x4, z4);
|
|
104262
|
-
if (performance.now() - sliceStart >
|
|
104341
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104263
104342
|
await yieldToEventLoop();
|
|
104264
104343
|
sliceStart = performance.now();
|
|
104265
104344
|
}
|
|
@@ -104398,15 +104477,25 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104398
104477
|
for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
|
|
104399
104478
|
await chunk.refreshLight(indices === "all" ? void 0 : indices);
|
|
104400
104479
|
chunk.refreshAmbientOcclusion(this._ambientOcclusion);
|
|
104401
|
-
if (
|
|
104480
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104402
104481
|
await yieldToEventLoop();
|
|
104403
104482
|
sliceStart = performance.now();
|
|
104404
104483
|
}
|
|
104405
104484
|
}
|
|
104406
|
-
const
|
|
104407
|
-
|
|
104408
|
-
|
|
104409
|
-
|
|
104485
|
+
const pending = [];
|
|
104486
|
+
for (const chunk of [...batch.keys()]) {
|
|
104487
|
+
const build = (async () => {
|
|
104488
|
+
await chunk.rebuildSectionMesh();
|
|
104489
|
+
batch.delete(chunk);
|
|
104490
|
+
})();
|
|
104491
|
+
void build.catch(() => void 0);
|
|
104492
|
+
pending.push(build);
|
|
104493
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104494
|
+
await yieldToEventLoop();
|
|
104495
|
+
sliceStart = performance.now();
|
|
104496
|
+
}
|
|
104497
|
+
}
|
|
104498
|
+
const builds = await Promise.allSettled(pending);
|
|
104410
104499
|
const failure = builds.find((result) => result.status === "rejected");
|
|
104411
104500
|
if (failure?.status === "rejected") throw failure.reason;
|
|
104412
104501
|
} catch (error2) {
|
|
@@ -105372,8 +105461,10 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105372
105461
|
if (rejected?.status === "rejected") throw rejected.reason;
|
|
105373
105462
|
}
|
|
105374
105463
|
const positions = [];
|
|
105375
|
-
|
|
105376
|
-
|
|
105464
|
+
const jobs = /* @__PURE__ */ new Map();
|
|
105465
|
+
let failureOrder = Infinity, failure;
|
|
105466
|
+
for (const [order, { index, key, block }] of placements.entries()) {
|
|
105467
|
+
jobs.delete(index);
|
|
105377
105468
|
this.hiddenBlocks.delete(index);
|
|
105378
105469
|
this.data.assign(index, this.data.intern(block), block?.nbt);
|
|
105379
105470
|
const readBlock = this.data.snapshot(index);
|
|
@@ -105389,7 +105480,6 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105389
105480
|
this.z * 16 + Math.floor(index / 16) % 16
|
|
105390
105481
|
);
|
|
105391
105482
|
positions.push(worldPos);
|
|
105392
|
-
let object4;
|
|
105393
105483
|
try {
|
|
105394
105484
|
if (!readBlock) continue;
|
|
105395
105485
|
const resolved = resolutions.get(key);
|
|
@@ -105411,7 +105501,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105411
105501
|
this.sectionBlocks.set(index, templates.map((template) => ({ index, template, cullMask: 0, biomeTint: context?.tint })));
|
|
105412
105502
|
this.meshDirty = true;
|
|
105413
105503
|
} else {
|
|
105414
|
-
|
|
105504
|
+
jobs.set(index, { order, readBlock, blockState: blockState3, position: MineRenderWorld.worldToScenePosition(worldPos), options: {
|
|
105415
105505
|
mergeMeshes: true,
|
|
105416
105506
|
instanceMeshes: true,
|
|
105417
105507
|
maxInstanceCount: 2e3,
|
|
@@ -105419,13 +105509,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105419
105509
|
variantPosition,
|
|
105420
105510
|
biome: context?.biome,
|
|
105421
105511
|
biomePosition: this.biomePosition(index, blockState3, stored)
|
|
105422
|
-
});
|
|
105423
|
-
|
|
105512
|
+
} });
|
|
105513
|
+
continue;
|
|
105424
105514
|
}
|
|
105425
105515
|
this.renderedBlocks.set(index, { get block() {
|
|
105426
105516
|
return readBlock();
|
|
105427
|
-
}, object:
|
|
105428
|
-
if (object4) this.objectBlocks.add(index);
|
|
105517
|
+
}, object: void 0 });
|
|
105429
105518
|
} catch (error2) {
|
|
105430
105519
|
if (preserveDataOnFailure && readBlock) {
|
|
105431
105520
|
this.renderedBlocks.set(index, { get block() {
|
|
@@ -105433,12 +105522,35 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105433
105522
|
}, object: void 0 });
|
|
105434
105523
|
} else this.data.assign(index, 0);
|
|
105435
105524
|
this.fluidCells[index] = 0;
|
|
105436
|
-
|
|
105437
|
-
|
|
105438
|
-
|
|
105525
|
+
if (order < failureOrder) {
|
|
105526
|
+
failureOrder = order;
|
|
105527
|
+
failure = error2;
|
|
105528
|
+
}
|
|
105439
105529
|
}
|
|
105440
105530
|
}
|
|
105441
|
-
|
|
105531
|
+
const pending = [...jobs];
|
|
105532
|
+
const objects = await Promise.allSettled(pending.map(([, job]) => this.createBlockObject(job.blockState, job.position, job.options)));
|
|
105533
|
+
for (const [i4, [index, { order, readBlock }]] of pending.entries()) {
|
|
105534
|
+
const result = objects[i4];
|
|
105535
|
+
if (result.status === "fulfilled") {
|
|
105536
|
+
this.renderedBlocks.set(index, { get block() {
|
|
105537
|
+
return readBlock();
|
|
105538
|
+
}, object: result.value });
|
|
105539
|
+
this.objectBlocks.add(index);
|
|
105540
|
+
} else {
|
|
105541
|
+
if (preserveDataOnFailure) {
|
|
105542
|
+
this.renderedBlocks.set(index, { get block() {
|
|
105543
|
+
return readBlock();
|
|
105544
|
+
}, object: void 0 });
|
|
105545
|
+
} else this.data.assign(index, 0);
|
|
105546
|
+
this.fluidCells[index] = 0;
|
|
105547
|
+
if (order < failureOrder) {
|
|
105548
|
+
failureOrder = order;
|
|
105549
|
+
failure = result.reason;
|
|
105550
|
+
}
|
|
105551
|
+
}
|
|
105552
|
+
}
|
|
105553
|
+
if (failureOrder < Infinity) throw failure;
|
|
105442
105554
|
return positions;
|
|
105443
105555
|
}
|
|
105444
105556
|
/** Replaces every cell from parsed section data. The caller refreshes neighbor culling. */
|
|
@@ -105509,37 +105621,42 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105509
105621
|
failed = true;
|
|
105510
105622
|
}
|
|
105511
105623
|
}
|
|
105512
|
-
|
|
105513
|
-
|
|
105514
|
-
|
|
105515
|
-
|
|
105516
|
-
|
|
105517
|
-
|
|
105518
|
-
|
|
105519
|
-
|
|
105520
|
-
|
|
105521
|
-
|
|
105522
|
-
|
|
105523
|
-
|
|
105524
|
-
|
|
105525
|
-
|
|
105526
|
-
|
|
105527
|
-
|
|
105528
|
-
)
|
|
105529
|
-
this.renderedBlocks.get(index).object = object4;
|
|
105624
|
+
const objects = await Promise.allSettled(perBlocks.map(({ index, blockState: blockState3, biome }) => this.createBlockObject(blockState3, new Vector3(
|
|
105625
|
+
this.x * 256 + index % 16 * 16,
|
|
105626
|
+
this.y * 256 + Math.floor(index / 256) * 16,
|
|
105627
|
+
this.z * 256 + Math.floor(index / 16) % 16 * 16
|
|
105628
|
+
), {
|
|
105629
|
+
mergeMeshes: true,
|
|
105630
|
+
instanceMeshes: true,
|
|
105631
|
+
maxInstanceCount: 2e3,
|
|
105632
|
+
initialState: this.data.stateAt(this.data.idAt(index)).properties,
|
|
105633
|
+
variantPosition: this.positionAt(index),
|
|
105634
|
+
biome,
|
|
105635
|
+
biomePosition: this.biomePosition(index, blockState3, this.data.stateAt(this.data.idAt(index)))
|
|
105636
|
+
})));
|
|
105637
|
+
for (const [i4, { index }] of perBlocks.entries()) {
|
|
105638
|
+
const result = objects[i4];
|
|
105639
|
+
if (result.status === "fulfilled") {
|
|
105640
|
+
this.renderedBlocks.get(index).object = result.value;
|
|
105530
105641
|
this.objectBlocks.add(index);
|
|
105531
|
-
}
|
|
105642
|
+
} else {
|
|
105532
105643
|
this.data.assign(index, 0);
|
|
105533
105644
|
this.fluidCells[index] = 0;
|
|
105534
105645
|
this.renderedBlocks.delete(index);
|
|
105535
105646
|
this.objectBlocks.delete(index);
|
|
105536
|
-
|
|
105537
|
-
if (!failed) failure = error2;
|
|
105647
|
+
if (!failed) failure = result.reason;
|
|
105538
105648
|
failed = true;
|
|
105539
105649
|
}
|
|
105540
105650
|
}
|
|
105541
105651
|
if (failed) throw failure;
|
|
105542
105652
|
}
|
|
105653
|
+
createBlockObject(blockState3, position, options) {
|
|
105654
|
+
return this.scene.addSceneObject(blockState3, () => {
|
|
105655
|
+
const object4 = new BlockObject(blockState3, options);
|
|
105656
|
+
object4.position.copy(position);
|
|
105657
|
+
return object4;
|
|
105658
|
+
}, options);
|
|
105659
|
+
}
|
|
105543
105660
|
positionAt(index) {
|
|
105544
105661
|
return [this.x * 16 + index % 16, this.y * 16 + Math.floor(index / 256), this.z * 16 + Math.floor(index / 16) % 16];
|
|
105545
105662
|
}
|
|
@@ -105898,6 +106015,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105898
106015
|
init_dirname();
|
|
105899
106016
|
init_buffer2();
|
|
105900
106017
|
init_process2();
|
|
106018
|
+
var MAX_PREFETCHED_COLUMNS = 4;
|
|
105901
106019
|
var WorldStreamer = class {
|
|
105902
106020
|
constructor(world, source, options = {}) {
|
|
105903
106021
|
this.world = world;
|
|
@@ -105907,6 +106025,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105907
106025
|
this.missing = /* @__PURE__ */ new Map();
|
|
105908
106026
|
this.failed = /* @__PURE__ */ new Map();
|
|
105909
106027
|
this.desired = [];
|
|
106028
|
+
this.reads = /* @__PURE__ */ new Map();
|
|
105910
106029
|
this.disposed = false;
|
|
105911
106030
|
this.loadRadius = options.loadRadius ?? 2;
|
|
105912
106031
|
this.unloadRadius = options.unloadRadius ?? Math.min(32, this.loadRadius + 1);
|
|
@@ -105951,6 +106070,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105951
106070
|
if (this.loading && !this.within(this.loading.position, this.loadRadius)) {
|
|
105952
106071
|
this.loading.controller.abort();
|
|
105953
106072
|
}
|
|
106073
|
+
for (const [key, read] of this.reads) {
|
|
106074
|
+
if (!this.within(read.position, this.loadRadius)) {
|
|
106075
|
+
read.controller.abort();
|
|
106076
|
+
if (read.ready) this.reads.delete(key);
|
|
106077
|
+
}
|
|
106078
|
+
}
|
|
105954
106079
|
}
|
|
105955
106080
|
return this.running ?? (this.running = Promise.resolve().then(() => this.drain()));
|
|
105956
106081
|
}
|
|
@@ -105971,8 +106096,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105971
106096
|
this.desired = [];
|
|
105972
106097
|
this.center = void 0;
|
|
105973
106098
|
this.loading?.controller.abort();
|
|
106099
|
+
for (const read of this.reads.values()) read.controller.abort();
|
|
105974
106100
|
return this.disposal ?? (this.disposal = Promise.resolve().then(async () => {
|
|
105975
106101
|
await this.running?.catch(() => void 0);
|
|
106102
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
106103
|
+
this.reads.clear();
|
|
105976
106104
|
try {
|
|
105977
106105
|
await this.unloadMany([...this.owned.values()]);
|
|
105978
106106
|
} finally {
|
|
@@ -105998,6 +106126,10 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105998
106126
|
await this.unloadMany(obsolete);
|
|
105999
106127
|
continue;
|
|
106000
106128
|
}
|
|
106129
|
+
if (this.world.placeChunks) {
|
|
106130
|
+
if (await this.placeReadyChunks()) continue;
|
|
106131
|
+
return;
|
|
106132
|
+
}
|
|
106001
106133
|
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
106002
106134
|
if (!position) return;
|
|
106003
106135
|
let chunk;
|
|
@@ -106020,26 +106152,105 @@ gl_FragDepth=readDepth(vUv);
|
|
|
106020
106152
|
continue;
|
|
106021
106153
|
}
|
|
106022
106154
|
this.owned.set(this.key(position), position);
|
|
106155
|
+
await this.placeOwnedColumns([position], () => this.world.placeChunk(chunk));
|
|
106156
|
+
}
|
|
106157
|
+
} finally {
|
|
106158
|
+
for (const [key, read] of this.reads) {
|
|
106159
|
+
read.controller.abort();
|
|
106160
|
+
if (read.ready) this.reads.delete(key);
|
|
106161
|
+
}
|
|
106162
|
+
this.running = void 0;
|
|
106163
|
+
}
|
|
106164
|
+
}
|
|
106165
|
+
fillReadSlots() {
|
|
106166
|
+
while (!this.disposed && this.reads.size < MAX_PREFETCHED_COLUMNS) {
|
|
106167
|
+
const position = this.desired.find((position2) => this.needsLoad(position2) && !this.reads.has(this.key(position2)));
|
|
106168
|
+
if (!position) return;
|
|
106169
|
+
const key = this.key(position);
|
|
106170
|
+
const read = {
|
|
106171
|
+
position,
|
|
106172
|
+
controller: new AbortController(),
|
|
106173
|
+
promise: Promise.resolve(),
|
|
106174
|
+
ready: false,
|
|
106175
|
+
failed: false
|
|
106176
|
+
};
|
|
106177
|
+
this.reads.set(key, read);
|
|
106178
|
+
read.promise = (async () => {
|
|
106023
106179
|
try {
|
|
106024
|
-
await this.
|
|
106025
|
-
this.
|
|
106180
|
+
read.chunk = await this.source.getChunk(position.x, position.z, read.controller.signal);
|
|
106181
|
+
if (read.chunk) this.validateChunk(read.chunk, position);
|
|
106026
106182
|
} catch (error2) {
|
|
106027
|
-
|
|
106028
|
-
|
|
106029
|
-
|
|
106030
|
-
|
|
106031
|
-
|
|
106032
|
-
|
|
106033
|
-
} catch {
|
|
106034
|
-
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
106035
|
-
}
|
|
106036
|
-
throw failure;
|
|
106183
|
+
read.failed = true;
|
|
106184
|
+
read.error = error2;
|
|
106185
|
+
} finally {
|
|
106186
|
+
read.ready = true;
|
|
106187
|
+
if (read.controller.signal.aborted || this.disposed || !this.within(position, this.loadRadius)) {
|
|
106188
|
+
this.reads.delete(key);
|
|
106037
106189
|
}
|
|
106038
|
-
|
|
106190
|
+
}
|
|
106191
|
+
})();
|
|
106192
|
+
}
|
|
106193
|
+
}
|
|
106194
|
+
/** Places only the ready prefix, so later source reads cannot delay the nearest ready column. */
|
|
106195
|
+
async placeReadyChunks() {
|
|
106196
|
+
this.fillReadSlots();
|
|
106197
|
+
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
106198
|
+
if (!position) {
|
|
106199
|
+
if (!this.reads.size) return false;
|
|
106200
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
106201
|
+
return true;
|
|
106202
|
+
}
|
|
106203
|
+
const head = this.reads.get(this.key(position));
|
|
106204
|
+
if (!head) {
|
|
106205
|
+
for (let index = this.desired.length - 1; index >= 0; index--) {
|
|
106206
|
+
const key = this.key(this.desired[index]);
|
|
106207
|
+
if (this.reads.get(key)?.ready) {
|
|
106208
|
+
this.reads.delete(key);
|
|
106209
|
+
return true;
|
|
106039
106210
|
}
|
|
106040
106211
|
}
|
|
106041
|
-
|
|
106042
|
-
|
|
106212
|
+
await Promise.race([...this.reads.values()].map((read) => read.promise));
|
|
106213
|
+
return true;
|
|
106214
|
+
}
|
|
106215
|
+
if (!head.ready) {
|
|
106216
|
+
await head.promise;
|
|
106217
|
+
return true;
|
|
106218
|
+
}
|
|
106219
|
+
const chunks = [], positions = [];
|
|
106220
|
+
for (const desired of this.desired) {
|
|
106221
|
+
if (!this.needsLoad(desired)) continue;
|
|
106222
|
+
const key = this.key(desired), read = this.reads.get(key);
|
|
106223
|
+
if (!read?.ready) break;
|
|
106224
|
+
this.reads.delete(key);
|
|
106225
|
+
if (read.failed) this.failed.set(key, { ...desired, error: read.error });
|
|
106226
|
+
else if (!read.chunk) this.missing.set(key, desired);
|
|
106227
|
+
else {
|
|
106228
|
+
chunks.push(read.chunk);
|
|
106229
|
+
positions.push(desired);
|
|
106230
|
+
}
|
|
106231
|
+
}
|
|
106232
|
+
if (!chunks.length) return true;
|
|
106233
|
+
for (const position2 of positions) this.owned.set(this.key(position2), position2);
|
|
106234
|
+
await this.placeOwnedColumns(positions, () => this.world.placeChunks(chunks));
|
|
106235
|
+
return true;
|
|
106236
|
+
}
|
|
106237
|
+
async placeOwnedColumns(positions, place) {
|
|
106238
|
+
try {
|
|
106239
|
+
await place();
|
|
106240
|
+
for (const position of positions) this.loaded.set(this.key(position), position);
|
|
106241
|
+
} catch (error2) {
|
|
106242
|
+
try {
|
|
106243
|
+
await this.unloadMany(positions);
|
|
106244
|
+
} catch (cleanupError) {
|
|
106245
|
+
const failure = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
106246
|
+
try {
|
|
106247
|
+
Object.defineProperty(failure, "cause", { value: cleanupError, configurable: true });
|
|
106248
|
+
} catch {
|
|
106249
|
+
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
106250
|
+
}
|
|
106251
|
+
throw failure;
|
|
106252
|
+
}
|
|
106253
|
+
throw error2;
|
|
106043
106254
|
}
|
|
106044
106255
|
}
|
|
106045
106256
|
needsLoad(position) {
|