minerender 2.1.0-alpha.142 → 2.1.0-alpha.143
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/dist/browser/esm/index.browser.d.mts +16 -2
- package/dist/browser/esm/util/util.mjs +0 -2
- package/dist/browser/esm/util/util.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +82 -12
- package/dist/browser/esm/world/MineRenderWorld.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 +16 -2
- package/dist/browser/index.js +191 -29
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +191 -29
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +16 -2
- package/dist/node/index.d.ts +16 -2
- package/dist/node/index.js +191 -29
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +191 -29
- 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();
|
|
@@ -103867,6 +103865,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103867
103865
|
// src/world/MineRenderWorld.ts
|
|
103868
103866
|
init_log();
|
|
103869
103867
|
var log21 = logger("MineRenderWorld");
|
|
103868
|
+
var YIELD_INTERVAL_MS = 8;
|
|
103870
103869
|
var MineRenderWorld = class {
|
|
103871
103870
|
constructor(scene, options = {}) {
|
|
103872
103871
|
this._chunks = /* @__PURE__ */ new Map();
|
|
@@ -103980,7 +103979,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103980
103979
|
failures.set(chunk, error2);
|
|
103981
103980
|
if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) === chunk) this.pendingBiomes.set(chunk, void 0);
|
|
103982
103981
|
}
|
|
103983
|
-
if (performance.now() - sliceStart >
|
|
103982
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
103984
103983
|
await yieldToEventLoop();
|
|
103985
103984
|
sliceStart = performance.now();
|
|
103986
103985
|
}
|
|
@@ -104135,7 +104134,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104135
104134
|
)));
|
|
104136
104135
|
for (const pos of positions) changes.set(`${pos.x},${pos.y},${pos.z}`, pos);
|
|
104137
104136
|
}
|
|
104138
|
-
if (performance.now() - sliceStart >
|
|
104137
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104139
104138
|
await yieldToEventLoop();
|
|
104140
104139
|
sliceStart = performance.now();
|
|
104141
104140
|
}
|
|
@@ -104143,6 +104142,62 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104143
104142
|
}
|
|
104144
104143
|
/** Replaces a chunk column's blocks, biomes, and saved light and, with `renderEntities`, its supported saved mobs. */
|
|
104145
104144
|
async placeChunk(chunk, executor) {
|
|
104145
|
+
return this.placeColumn(chunk, executor);
|
|
104146
|
+
}
|
|
104147
|
+
/**
|
|
104148
|
+
* Replaces parsed columns in input order, then refreshes neighboring geometry once.
|
|
104149
|
+
* Duplicate coordinates retain their order. A failed column stops placement; queued refreshes finish before rejection.
|
|
104150
|
+
*/
|
|
104151
|
+
async placeChunks(chunks) {
|
|
104152
|
+
const columns = [];
|
|
104153
|
+
for (const chunk of chunks) {
|
|
104154
|
+
const { x: x4, z: z4 } = chunk ?? {};
|
|
104155
|
+
if (![x4, z4].every(Number.isSafeInteger)) {
|
|
104156
|
+
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
104157
|
+
}
|
|
104158
|
+
const sections = Array.from(chunk.sections, (section) => {
|
|
104159
|
+
const { y: y5 } = section ?? {};
|
|
104160
|
+
if (!Number.isSafeInteger(y5)) throw new RangeError("Chunk section coordinates must be safe integers");
|
|
104161
|
+
return { ...section, y: y5 };
|
|
104162
|
+
});
|
|
104163
|
+
columns.push({ ...chunk, x: x4, z: z4, sections });
|
|
104164
|
+
}
|
|
104165
|
+
if (!columns.length) return;
|
|
104166
|
+
await this.culling;
|
|
104167
|
+
let failed = false, failure, sliceStart = performance.now();
|
|
104168
|
+
try {
|
|
104169
|
+
for (const column of columns) {
|
|
104170
|
+
await this.placeColumn(column, void 0, true);
|
|
104171
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104172
|
+
await yieldToEventLoop();
|
|
104173
|
+
sliceStart = performance.now();
|
|
104174
|
+
}
|
|
104175
|
+
}
|
|
104176
|
+
} catch (error2) {
|
|
104177
|
+
failed = true;
|
|
104178
|
+
failure = error2;
|
|
104179
|
+
} finally {
|
|
104180
|
+
try {
|
|
104181
|
+
const failures = await this.refreshBiomes(true);
|
|
104182
|
+
if (failures.size) log21.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
104183
|
+
} catch (error2) {
|
|
104184
|
+
if (!failed) {
|
|
104185
|
+
failed = true;
|
|
104186
|
+
failure = error2;
|
|
104187
|
+
}
|
|
104188
|
+
}
|
|
104189
|
+
try {
|
|
104190
|
+
await this.updateCulling([]);
|
|
104191
|
+
} catch (error2) {
|
|
104192
|
+
if (!failed) {
|
|
104193
|
+
failed = true;
|
|
104194
|
+
failure = error2;
|
|
104195
|
+
}
|
|
104196
|
+
}
|
|
104197
|
+
}
|
|
104198
|
+
if (failed) throw failure;
|
|
104199
|
+
}
|
|
104200
|
+
async placeColumn(chunk, executor, deferCulling = false) {
|
|
104146
104201
|
if (![chunk.x, chunk.z].every(Number.isSafeInteger)) {
|
|
104147
104202
|
throw new RangeError("Chunk column coordinates must be safe integers");
|
|
104148
104203
|
}
|
|
@@ -104204,7 +104259,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104204
104259
|
} finally {
|
|
104205
104260
|
this.markSectionChanged(target);
|
|
104206
104261
|
}
|
|
104207
|
-
if (performance.now() - sliceStart >
|
|
104262
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104208
104263
|
await yieldToEventLoop();
|
|
104209
104264
|
sliceStart = performance.now();
|
|
104210
104265
|
}
|
|
@@ -104227,9 +104282,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104227
104282
|
await placeEntities?.();
|
|
104228
104283
|
} finally {
|
|
104229
104284
|
this.markBiomesChanged(chunk.x, chunk.z, void 0, false);
|
|
104230
|
-
|
|
104231
|
-
|
|
104232
|
-
|
|
104285
|
+
if (deferCulling) await this.updateCulling([...changes.values()], true);
|
|
104286
|
+
else {
|
|
104287
|
+
const failures = await this.refreshBiomes();
|
|
104288
|
+
if (failures.size) log21.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
104289
|
+
await this.updateCulling([...changes.values()]);
|
|
104290
|
+
}
|
|
104233
104291
|
}
|
|
104234
104292
|
}
|
|
104235
104293
|
/**
|
|
@@ -104259,7 +104317,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104259
104317
|
for (const { x: x4, z: z4 } of columns.values()) {
|
|
104260
104318
|
this.entities?.clearColumn(x4, z4);
|
|
104261
104319
|
await this.clearChunkColumn(x4, z4);
|
|
104262
|
-
if (performance.now() - sliceStart >
|
|
104320
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104263
104321
|
await yieldToEventLoop();
|
|
104264
104322
|
sliceStart = performance.now();
|
|
104265
104323
|
}
|
|
@@ -104398,15 +104456,25 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104398
104456
|
for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
|
|
104399
104457
|
await chunk.refreshLight(indices === "all" ? void 0 : indices);
|
|
104400
104458
|
chunk.refreshAmbientOcclusion(this._ambientOcclusion);
|
|
104401
|
-
if (
|
|
104459
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104402
104460
|
await yieldToEventLoop();
|
|
104403
104461
|
sliceStart = performance.now();
|
|
104404
104462
|
}
|
|
104405
104463
|
}
|
|
104406
|
-
const
|
|
104407
|
-
|
|
104408
|
-
|
|
104409
|
-
|
|
104464
|
+
const pending = [];
|
|
104465
|
+
for (const chunk of [...batch.keys()]) {
|
|
104466
|
+
const build = (async () => {
|
|
104467
|
+
await chunk.rebuildSectionMesh();
|
|
104468
|
+
batch.delete(chunk);
|
|
104469
|
+
})();
|
|
104470
|
+
void build.catch(() => void 0);
|
|
104471
|
+
pending.push(build);
|
|
104472
|
+
if (performance.now() - sliceStart > YIELD_INTERVAL_MS) {
|
|
104473
|
+
await yieldToEventLoop();
|
|
104474
|
+
sliceStart = performance.now();
|
|
104475
|
+
}
|
|
104476
|
+
}
|
|
104477
|
+
const builds = await Promise.allSettled(pending);
|
|
104410
104478
|
const failure = builds.find((result) => result.status === "rejected");
|
|
104411
104479
|
if (failure?.status === "rejected") throw failure.reason;
|
|
104412
104480
|
} catch (error2) {
|
|
@@ -105898,6 +105966,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105898
105966
|
init_dirname();
|
|
105899
105967
|
init_buffer2();
|
|
105900
105968
|
init_process2();
|
|
105969
|
+
var MAX_PREFETCHED_COLUMNS = 4;
|
|
105901
105970
|
var WorldStreamer = class {
|
|
105902
105971
|
constructor(world, source, options = {}) {
|
|
105903
105972
|
this.world = world;
|
|
@@ -105907,6 +105976,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105907
105976
|
this.missing = /* @__PURE__ */ new Map();
|
|
105908
105977
|
this.failed = /* @__PURE__ */ new Map();
|
|
105909
105978
|
this.desired = [];
|
|
105979
|
+
this.reads = /* @__PURE__ */ new Map();
|
|
105910
105980
|
this.disposed = false;
|
|
105911
105981
|
this.loadRadius = options.loadRadius ?? 2;
|
|
105912
105982
|
this.unloadRadius = options.unloadRadius ?? Math.min(32, this.loadRadius + 1);
|
|
@@ -105951,6 +106021,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105951
106021
|
if (this.loading && !this.within(this.loading.position, this.loadRadius)) {
|
|
105952
106022
|
this.loading.controller.abort();
|
|
105953
106023
|
}
|
|
106024
|
+
for (const [key, read] of this.reads) {
|
|
106025
|
+
if (!this.within(read.position, this.loadRadius)) {
|
|
106026
|
+
read.controller.abort();
|
|
106027
|
+
if (read.ready) this.reads.delete(key);
|
|
106028
|
+
}
|
|
106029
|
+
}
|
|
105954
106030
|
}
|
|
105955
106031
|
return this.running ?? (this.running = Promise.resolve().then(() => this.drain()));
|
|
105956
106032
|
}
|
|
@@ -105971,8 +106047,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105971
106047
|
this.desired = [];
|
|
105972
106048
|
this.center = void 0;
|
|
105973
106049
|
this.loading?.controller.abort();
|
|
106050
|
+
for (const read of this.reads.values()) read.controller.abort();
|
|
105974
106051
|
return this.disposal ?? (this.disposal = Promise.resolve().then(async () => {
|
|
105975
106052
|
await this.running?.catch(() => void 0);
|
|
106053
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
106054
|
+
this.reads.clear();
|
|
105976
106055
|
try {
|
|
105977
106056
|
await this.unloadMany([...this.owned.values()]);
|
|
105978
106057
|
} finally {
|
|
@@ -105998,6 +106077,10 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105998
106077
|
await this.unloadMany(obsolete);
|
|
105999
106078
|
continue;
|
|
106000
106079
|
}
|
|
106080
|
+
if (this.world.placeChunks) {
|
|
106081
|
+
if (await this.placeReadyChunks()) continue;
|
|
106082
|
+
return;
|
|
106083
|
+
}
|
|
106001
106084
|
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
106002
106085
|
if (!position) return;
|
|
106003
106086
|
let chunk;
|
|
@@ -106020,26 +106103,105 @@ gl_FragDepth=readDepth(vUv);
|
|
|
106020
106103
|
continue;
|
|
106021
106104
|
}
|
|
106022
106105
|
this.owned.set(this.key(position), position);
|
|
106106
|
+
await this.placeOwnedColumns([position], () => this.world.placeChunk(chunk));
|
|
106107
|
+
}
|
|
106108
|
+
} finally {
|
|
106109
|
+
for (const [key, read] of this.reads) {
|
|
106110
|
+
read.controller.abort();
|
|
106111
|
+
if (read.ready) this.reads.delete(key);
|
|
106112
|
+
}
|
|
106113
|
+
this.running = void 0;
|
|
106114
|
+
}
|
|
106115
|
+
}
|
|
106116
|
+
fillReadSlots() {
|
|
106117
|
+
while (!this.disposed && this.reads.size < MAX_PREFETCHED_COLUMNS) {
|
|
106118
|
+
const position = this.desired.find((position2) => this.needsLoad(position2) && !this.reads.has(this.key(position2)));
|
|
106119
|
+
if (!position) return;
|
|
106120
|
+
const key = this.key(position);
|
|
106121
|
+
const read = {
|
|
106122
|
+
position,
|
|
106123
|
+
controller: new AbortController(),
|
|
106124
|
+
promise: Promise.resolve(),
|
|
106125
|
+
ready: false,
|
|
106126
|
+
failed: false
|
|
106127
|
+
};
|
|
106128
|
+
this.reads.set(key, read);
|
|
106129
|
+
read.promise = (async () => {
|
|
106023
106130
|
try {
|
|
106024
|
-
await this.
|
|
106025
|
-
this.
|
|
106131
|
+
read.chunk = await this.source.getChunk(position.x, position.z, read.controller.signal);
|
|
106132
|
+
if (read.chunk) this.validateChunk(read.chunk, position);
|
|
106026
106133
|
} catch (error2) {
|
|
106027
|
-
|
|
106028
|
-
|
|
106029
|
-
|
|
106030
|
-
|
|
106031
|
-
|
|
106032
|
-
|
|
106033
|
-
} catch {
|
|
106034
|
-
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
106035
|
-
}
|
|
106036
|
-
throw failure;
|
|
106134
|
+
read.failed = true;
|
|
106135
|
+
read.error = error2;
|
|
106136
|
+
} finally {
|
|
106137
|
+
read.ready = true;
|
|
106138
|
+
if (read.controller.signal.aborted || this.disposed || !this.within(position, this.loadRadius)) {
|
|
106139
|
+
this.reads.delete(key);
|
|
106037
106140
|
}
|
|
106038
|
-
|
|
106141
|
+
}
|
|
106142
|
+
})();
|
|
106143
|
+
}
|
|
106144
|
+
}
|
|
106145
|
+
/** Places only the ready prefix, so later source reads cannot delay the nearest ready column. */
|
|
106146
|
+
async placeReadyChunks() {
|
|
106147
|
+
this.fillReadSlots();
|
|
106148
|
+
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
106149
|
+
if (!position) {
|
|
106150
|
+
if (!this.reads.size) return false;
|
|
106151
|
+
await Promise.all([...this.reads.values()].map((read) => read.promise));
|
|
106152
|
+
return true;
|
|
106153
|
+
}
|
|
106154
|
+
const head = this.reads.get(this.key(position));
|
|
106155
|
+
if (!head) {
|
|
106156
|
+
for (let index = this.desired.length - 1; index >= 0; index--) {
|
|
106157
|
+
const key = this.key(this.desired[index]);
|
|
106158
|
+
if (this.reads.get(key)?.ready) {
|
|
106159
|
+
this.reads.delete(key);
|
|
106160
|
+
return true;
|
|
106039
106161
|
}
|
|
106040
106162
|
}
|
|
106041
|
-
|
|
106042
|
-
|
|
106163
|
+
await Promise.race([...this.reads.values()].map((read) => read.promise));
|
|
106164
|
+
return true;
|
|
106165
|
+
}
|
|
106166
|
+
if (!head.ready) {
|
|
106167
|
+
await head.promise;
|
|
106168
|
+
return true;
|
|
106169
|
+
}
|
|
106170
|
+
const chunks = [], positions = [];
|
|
106171
|
+
for (const desired of this.desired) {
|
|
106172
|
+
if (!this.needsLoad(desired)) continue;
|
|
106173
|
+
const key = this.key(desired), read = this.reads.get(key);
|
|
106174
|
+
if (!read?.ready) break;
|
|
106175
|
+
this.reads.delete(key);
|
|
106176
|
+
if (read.failed) this.failed.set(key, { ...desired, error: read.error });
|
|
106177
|
+
else if (!read.chunk) this.missing.set(key, desired);
|
|
106178
|
+
else {
|
|
106179
|
+
chunks.push(read.chunk);
|
|
106180
|
+
positions.push(desired);
|
|
106181
|
+
}
|
|
106182
|
+
}
|
|
106183
|
+
if (!chunks.length) return true;
|
|
106184
|
+
for (const position2 of positions) this.owned.set(this.key(position2), position2);
|
|
106185
|
+
await this.placeOwnedColumns(positions, () => this.world.placeChunks(chunks));
|
|
106186
|
+
return true;
|
|
106187
|
+
}
|
|
106188
|
+
async placeOwnedColumns(positions, place) {
|
|
106189
|
+
try {
|
|
106190
|
+
await place();
|
|
106191
|
+
for (const position of positions) this.loaded.set(this.key(position), position);
|
|
106192
|
+
} catch (error2) {
|
|
106193
|
+
try {
|
|
106194
|
+
await this.unloadMany(positions);
|
|
106195
|
+
} catch (cleanupError) {
|
|
106196
|
+
const failure = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
106197
|
+
try {
|
|
106198
|
+
Object.defineProperty(failure, "cause", { value: cleanupError, configurable: true });
|
|
106199
|
+
} catch {
|
|
106200
|
+
throw Object.assign(new Error(failure.message), { cause: cleanupError });
|
|
106201
|
+
}
|
|
106202
|
+
throw failure;
|
|
106203
|
+
}
|
|
106204
|
+
throw error2;
|
|
106043
106205
|
}
|
|
106044
106206
|
}
|
|
106045
106207
|
needsLoad(position) {
|