minerender 2.1.0-alpha.137 → 2.1.0-alpha.139
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 +29 -8
- package/dist/browser/esm/model/multiblock/StructureParser.mjs +7 -4
- package/dist/browser/esm/model/multiblock/StructureParser.mjs.map +1 -1
- package/dist/browser/esm/world/Chunk.mjs +8 -5
- package/dist/browser/esm/world/Chunk.mjs.map +1 -1
- package/dist/browser/esm/world/MineRenderWorld.mjs +92 -52
- package/dist/browser/esm/world/MineRenderWorld.mjs.map +1 -1
- package/dist/browser/esm/world/WorldStreamer.mjs +21 -20
- package/dist/browser/esm/world/WorldStreamer.mjs.map +1 -1
- package/dist/browser/index.d.ts +29 -8
- package/dist/browser/index.js +128 -81
- package/dist/browser/index.js.map +1 -1
- package/dist/bundle.js +128 -81
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +29 -8
- package/dist/node/index.d.ts +29 -8
- package/dist/node/index.js +128 -81
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +128 -81
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -97035,13 +97035,16 @@ property list uchar int vertex_index
|
|
|
97035
97035
|
const blocks = nbt.blocks.value.value.map((block) => {
|
|
97036
97036
|
const state = palette.value.value[block.state.value];
|
|
97037
97037
|
if (!state) throw new MineRenderError(`Structure palette index ${block.state.value} does not exist`);
|
|
97038
|
-
|
|
97038
|
+
const name2 = (state.Name ?? state.id)?.value;
|
|
97039
|
+
if (!name2) throw new MineRenderError(`Structure palette entry ${block.state.value} has no block name`);
|
|
97040
|
+
if (["minecraft:air", "minecraft:cave_air", "minecraft:void_air"].includes(name2)) return void 0;
|
|
97039
97041
|
const props = {};
|
|
97040
|
-
|
|
97041
|
-
|
|
97042
|
+
const properties = (state.Properties ?? state.properties)?.value;
|
|
97043
|
+
for (let k4 in properties) {
|
|
97044
|
+
props[k4] = properties[k4].value;
|
|
97042
97045
|
}
|
|
97043
97046
|
return {
|
|
97044
|
-
type:
|
|
97047
|
+
type: name2,
|
|
97045
97048
|
properties: props,
|
|
97046
97049
|
position: block.pos.value.value,
|
|
97047
97050
|
nbt: block.nbt
|
|
@@ -103880,8 +103883,14 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103880
103883
|
}
|
|
103881
103884
|
return queued;
|
|
103882
103885
|
}
|
|
103883
|
-
async refreshBiomes() {
|
|
103884
|
-
if (this.biomeRefreshing)
|
|
103886
|
+
async refreshBiomes(deferCulling = false) {
|
|
103887
|
+
if (this.biomeRefreshing) {
|
|
103888
|
+
await this.biomeRefreshing;
|
|
103889
|
+
if (!deferCulling) {
|
|
103890
|
+
if (this.pendingCulling.size) await this.updateCulling([]);
|
|
103891
|
+
else await this.culling;
|
|
103892
|
+
}
|
|
103893
|
+
}
|
|
103885
103894
|
if (!this.pendingBiomes.size) return /* @__PURE__ */ new Map();
|
|
103886
103895
|
return this.biomeRefreshing ?? (this.biomeRefreshing = Promise.resolve().then(async () => {
|
|
103887
103896
|
const failures = /* @__PURE__ */ new Map();
|
|
@@ -103893,7 +103902,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
103893
103902
|
this.pendingBiomes.delete(chunk);
|
|
103894
103903
|
if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) !== chunk) continue;
|
|
103895
103904
|
try {
|
|
103896
|
-
await chunk.refreshBiomes(columns);
|
|
103905
|
+
await chunk.refreshBiomes(columns, deferCulling);
|
|
103897
103906
|
} catch (error2) {
|
|
103898
103907
|
failures.set(chunk, error2);
|
|
103899
103908
|
if (this._chunks.get(`${chunk.x}_${chunk.y}_${chunk.z}`) === chunk) this.pendingBiomes.set(chunk, void 0);
|
|
@@ -104155,15 +104164,35 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104155
104164
|
* Coordinates match AnvilChunk.x/z, not block positions. Missing columns are ignored.
|
|
104156
104165
|
*/
|
|
104157
104166
|
async unloadChunkColumn(x4, z4) {
|
|
104158
|
-
|
|
104159
|
-
|
|
104167
|
+
return this.unloadChunkColumns([{ x: x4, z: z4 }]);
|
|
104168
|
+
}
|
|
104169
|
+
/**
|
|
104170
|
+
* Removes chunk columns together and refreshes surviving neighbors once.
|
|
104171
|
+
* Coordinates are absolute chunk columns. Duplicate and missing columns are ignored.
|
|
104172
|
+
*/
|
|
104173
|
+
async unloadChunkColumns(positions) {
|
|
104174
|
+
const columns = /* @__PURE__ */ new Map();
|
|
104175
|
+
for (const position of positions) {
|
|
104176
|
+
const { x: x4, z: z4 } = position ?? {};
|
|
104177
|
+
if (!Number.isInteger(x4) || !Number.isInteger(z4)) {
|
|
104178
|
+
throw new RangeError("Chunk column coordinates must be integers");
|
|
104179
|
+
}
|
|
104180
|
+
columns.set(`${x4}_${z4}`, { x: x4, z: z4 });
|
|
104160
104181
|
}
|
|
104161
|
-
|
|
104182
|
+
if (!columns.size) return;
|
|
104162
104183
|
await this.culling;
|
|
104184
|
+
let sliceStart = performance.now();
|
|
104163
104185
|
try {
|
|
104164
|
-
|
|
104186
|
+
for (const { x: x4, z: z4 } of columns.values()) {
|
|
104187
|
+
this.entities?.clearColumn(x4, z4);
|
|
104188
|
+
await this.clearChunkColumn(x4, z4);
|
|
104189
|
+
if (performance.now() - sliceStart > 8) {
|
|
104190
|
+
await yieldToEventLoop();
|
|
104191
|
+
sliceStart = performance.now();
|
|
104192
|
+
}
|
|
104193
|
+
}
|
|
104165
104194
|
} finally {
|
|
104166
|
-
const failures = await this.refreshBiomes();
|
|
104195
|
+
const failures = await this.refreshBiomes(true);
|
|
104167
104196
|
if (failures.size) log21.warn("Failed to refresh biome colors", failures.values().next().value);
|
|
104168
104197
|
await this.updateCulling([]);
|
|
104169
104198
|
}
|
|
@@ -104226,7 +104255,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104226
104255
|
}
|
|
104227
104256
|
this.sectionModels?.clear();
|
|
104228
104257
|
}
|
|
104229
|
-
updateCulling(positions) {
|
|
104258
|
+
updateCulling(positions, defer = false) {
|
|
104230
104259
|
const neighbor = new Vector3();
|
|
104231
104260
|
for (const pos of positions) {
|
|
104232
104261
|
const cx = Math.floor(pos.x / 16), cy = Math.floor(pos.y / 16), cz = Math.floor(pos.z / 16);
|
|
@@ -104248,58 +104277,72 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104248
104277
|
}
|
|
104249
104278
|
}
|
|
104250
104279
|
}
|
|
104280
|
+
if (defer) return Promise.resolve();
|
|
104251
104281
|
return this.culling ?? (this.culling = Promise.resolve().then(async () => {
|
|
104252
104282
|
let sliceStart = performance.now();
|
|
104253
104283
|
try {
|
|
104254
104284
|
const culling = await loadBlockCulling();
|
|
104255
104285
|
while (this.pendingCulling.size) {
|
|
104256
|
-
const batch =
|
|
104286
|
+
const batch = new Map(this.pendingCulling);
|
|
104257
104287
|
this.pendingCulling.clear();
|
|
104258
|
-
|
|
104259
|
-
const
|
|
104260
|
-
|
|
104261
|
-
const
|
|
104262
|
-
|
|
104263
|
-
|
|
104264
|
-
|
|
104265
|
-
|
|
104266
|
-
const
|
|
104267
|
-
|
|
104268
|
-
|
|
104269
|
-
|
|
104270
|
-
|
|
104271
|
-
|
|
104272
|
-
|
|
104273
|
-
|
|
104274
|
-
|
|
104275
|
-
|
|
104276
|
-
|
|
104277
|
-
|
|
104278
|
-
|
|
104279
|
-
|
|
104280
|
-
|
|
104281
|
-
|
|
104282
|
-
|
|
104283
|
-
|
|
104284
|
-
|
|
104285
|
-
|
|
104286
|
-
|
|
104287
|
-
|
|
104288
|
-
|
|
104289
|
-
|
|
104290
|
-
|
|
104291
|
-
|
|
104288
|
+
try {
|
|
104289
|
+
for (const [chunk, indices] of batch) {
|
|
104290
|
+
const neighbors = CUBE_FACE_OFFSETS.map(([x4, y5, z4]) => this._chunks.get(`${chunk.x + x4}_${chunk.y + y5}_${chunk.z + z4}`));
|
|
104291
|
+
const neighborAt = (x4, y5, z4) => {
|
|
104292
|
+
const lx = x4 - chunk.x * 16, ly = y5 - chunk.y * 16, lz = z4 - chunk.z * 16;
|
|
104293
|
+
const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
|
|
104294
|
+
return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
|
|
104295
|
+
};
|
|
104296
|
+
const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x4, y5, z4) => {
|
|
104297
|
+
const [section, i4] = neighborAt(x4, y5, z4);
|
|
104298
|
+
return section?.isOccludingIndex(i4) ?? false;
|
|
104299
|
+
}, culling, (x4, y5, z4) => {
|
|
104300
|
+
const [section, i4] = neighborAt(x4, y5, z4);
|
|
104301
|
+
return section?.visibleBlockIndex(i4);
|
|
104302
|
+
});
|
|
104303
|
+
const fluidIndices = indices === "all" ? function* () {
|
|
104304
|
+
for (let index = 0; index < 4096; index++) yield index;
|
|
104305
|
+
}() : indices;
|
|
104306
|
+
for (const index of fluidIndices) {
|
|
104307
|
+
if (!chunk.fluidByteIndex(index) || !chunk.isBlockVisibleIndex(index)) continue;
|
|
104308
|
+
const lx = index % 16, ly = Math.floor(index / 256), lz = Math.floor(index / 16) % 16;
|
|
104309
|
+
const wx = chunk.x * 16 + lx, wy = chunk.y * 16 + ly, wz = chunk.z * 16 + lz;
|
|
104310
|
+
const block = chunk.getBlockAt(neighbor.set(wx, wy, wz));
|
|
104311
|
+
if (block.object?.fluidKind) {
|
|
104312
|
+
await block.object.updateFluid((x4, y5, z4) => {
|
|
104313
|
+
const nx = lx + x4, ny = ly + y5, nz = lz + z4;
|
|
104314
|
+
const section = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16 ? chunk : this._chunks.get(`${chunk.x + Math.floor(nx / 16)}_${chunk.y + Math.floor(ny / 16)}_${chunk.z + Math.floor(nz / 16)}`);
|
|
104315
|
+
const neighborIndex = (ny & 15) * 256 + (nz & 15) * 16 + (nx & 15);
|
|
104316
|
+
const byte = section?.fluidByteIndex(neighborIndex) ?? 0;
|
|
104317
|
+
return {
|
|
104318
|
+
fluid: fluidKindOf(byte),
|
|
104319
|
+
level: byte & 15,
|
|
104320
|
+
solid: section?.isOccludingIndex(neighborIndex) ?? false
|
|
104321
|
+
};
|
|
104322
|
+
});
|
|
104323
|
+
}
|
|
104324
|
+
}
|
|
104325
|
+
for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
|
|
104326
|
+
await chunk.refreshLight(indices === "all" ? void 0 : indices);
|
|
104327
|
+
chunk.refreshAmbientOcclusion(this._ambientOcclusion);
|
|
104328
|
+
if ((this._ambientOcclusion || this.ambientOcclusionPending) && performance.now() - sliceStart > 8) {
|
|
104329
|
+
await yieldToEventLoop();
|
|
104330
|
+
sliceStart = performance.now();
|
|
104292
104331
|
}
|
|
104293
104332
|
}
|
|
104294
|
-
|
|
104295
|
-
|
|
104296
|
-
|
|
104297
|
-
|
|
104298
|
-
|
|
104299
|
-
|
|
104333
|
+
const builds = await Promise.allSettled([...batch.keys()].map(async (chunk) => {
|
|
104334
|
+
await chunk.rebuildSectionMesh();
|
|
104335
|
+
batch.delete(chunk);
|
|
104336
|
+
}));
|
|
104337
|
+
const failure = builds.find((result) => result.status === "rejected");
|
|
104338
|
+
if (failure?.status === "rejected") throw failure.reason;
|
|
104339
|
+
} catch (error2) {
|
|
104340
|
+
for (const [chunk, indices] of batch) {
|
|
104341
|
+
const pending = this.pendingCulling.get(chunk);
|
|
104342
|
+
this.pendingCulling.set(chunk, indices === "all" || pending === "all" ? "all" : /* @__PURE__ */ new Set([...indices, ...pending ?? []]));
|
|
104300
104343
|
}
|
|
104344
|
+
throw error2;
|
|
104301
104345
|
}
|
|
104302
|
-
await Promise.all(batch.map(([chunk]) => chunk.rebuildSectionMesh()));
|
|
104303
104346
|
}
|
|
104304
104347
|
} finally {
|
|
104305
104348
|
this.culling = void 0;
|
|
@@ -104316,7 +104359,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
104316
104359
|
x4,
|
|
104317
104360
|
y5,
|
|
104318
104361
|
z4,
|
|
104319
|
-
(positions) => this.updateCulling(positions),
|
|
104362
|
+
(positions, defer) => this.updateCulling(positions, defer),
|
|
104320
104363
|
this.sectionModels,
|
|
104321
104364
|
(x5, y6, z5) => {
|
|
104322
104365
|
const cx = Math.floor(x5 / 16), cy = Math.floor(y6 / 16), cz = Math.floor(z5 / 16);
|
|
@@ -105065,11 +105108,14 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105065
105108
|
this.biomes = copy;
|
|
105066
105109
|
return this.refreshBiomes();
|
|
105067
105110
|
}
|
|
105068
|
-
/**
|
|
105069
|
-
|
|
105070
|
-
|
|
105111
|
+
/**
|
|
105112
|
+
* Rebuilds biome-tinted blocks while preserving hidden blocks and unrelated render objects.
|
|
105113
|
+
* The owning world can defer neighbor culling until all affected chunks are refreshed.
|
|
105114
|
+
*/
|
|
105115
|
+
refreshBiomes(columns, deferCulling = false) {
|
|
105116
|
+
return this.changeBlocks(() => this.refreshBiomeBlocks(columns, deferCulling), true);
|
|
105071
105117
|
}
|
|
105072
|
-
async refreshBiomeBlocks(columns) {
|
|
105118
|
+
async refreshBiomeBlocks(columns, deferCulling = false) {
|
|
105073
105119
|
const blend = columns && this.biomeBlend?.();
|
|
105074
105120
|
const ownColumn = columns?.some((column) => column.x === this.x && column.z === this.z);
|
|
105075
105121
|
const affected = /* @__PURE__ */ new Map();
|
|
@@ -105126,7 +105172,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105126
105172
|
this.renderedBlocks.get(index)?.object?.setVisible(false);
|
|
105127
105173
|
}
|
|
105128
105174
|
const positions = blocks.map(({ index }) => new Vector3(...this.positionAt(index)));
|
|
105129
|
-
if (this.onBlocksChanged) await this.onBlocksChanged(positions);
|
|
105175
|
+
if (this.onBlocksChanged) await this.onBlocksChanged(positions, deferCulling);
|
|
105130
105176
|
else await this.rebuildSectionMesh();
|
|
105131
105177
|
}
|
|
105132
105178
|
}
|
|
@@ -105798,19 +105844,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105798
105844
|
this.loading?.controller.abort();
|
|
105799
105845
|
return this.disposal ?? (this.disposal = Promise.resolve().then(async () => {
|
|
105800
105846
|
await this.running?.catch(() => void 0);
|
|
105801
|
-
|
|
105802
|
-
|
|
105803
|
-
|
|
105804
|
-
|
|
105805
|
-
|
|
105806
|
-
} catch (error2) {
|
|
105807
|
-
failed = true;
|
|
105808
|
-
failure ?? (failure = error2);
|
|
105809
|
-
}
|
|
105847
|
+
try {
|
|
105848
|
+
await this.unloadMany([...this.owned.values()]);
|
|
105849
|
+
} finally {
|
|
105850
|
+
this.missing.clear();
|
|
105851
|
+
this.failed.clear();
|
|
105810
105852
|
}
|
|
105811
|
-
this.missing.clear();
|
|
105812
|
-
this.failed.clear();
|
|
105813
|
-
if (failed) throw failure;
|
|
105814
105853
|
}).catch((error2) => {
|
|
105815
105854
|
this.disposal = void 0;
|
|
105816
105855
|
throw error2;
|
|
@@ -105825,9 +105864,9 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105825
105864
|
for (const [key, position2] of this.failed) {
|
|
105826
105865
|
if (!this.within(position2, this.unloadRadius)) this.failed.delete(key);
|
|
105827
105866
|
}
|
|
105828
|
-
const obsolete = [...this.owned.values()].
|
|
105829
|
-
if (obsolete) {
|
|
105830
|
-
await this.
|
|
105867
|
+
const obsolete = [...this.owned.values()].filter((position2) => !this.loaded.has(this.key(position2)) || !this.within(position2, this.unloadRadius));
|
|
105868
|
+
if (obsolete.length) {
|
|
105869
|
+
await this.unloadMany(obsolete);
|
|
105831
105870
|
continue;
|
|
105832
105871
|
}
|
|
105833
105872
|
const position = this.desired.find((position2) => this.needsLoad(position2));
|
|
@@ -105857,7 +105896,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105857
105896
|
this.loaded.set(this.key(position), position);
|
|
105858
105897
|
} catch (error2) {
|
|
105859
105898
|
try {
|
|
105860
|
-
await this.
|
|
105899
|
+
await this.unloadMany([position]);
|
|
105861
105900
|
} catch (cleanupError) {
|
|
105862
105901
|
const failure = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
105863
105902
|
try {
|
|
@@ -105878,10 +105917,18 @@ gl_FragDepth=readDepth(vUv);
|
|
|
105878
105917
|
const key = this.key(position);
|
|
105879
105918
|
return !this.loaded.has(key) && !this.missing.has(key) && !this.failed.has(key);
|
|
105880
105919
|
}
|
|
105881
|
-
async
|
|
105882
|
-
|
|
105883
|
-
|
|
105884
|
-
|
|
105920
|
+
async unloadMany(positions) {
|
|
105921
|
+
if (!positions.length) return;
|
|
105922
|
+
try {
|
|
105923
|
+
await this.world.unloadChunkColumns(positions.map(({ x: x4, z: z4 }) => ({ x: x4, z: z4 })));
|
|
105924
|
+
} catch (error2) {
|
|
105925
|
+
for (const position of positions) this.loaded.delete(this.key(position));
|
|
105926
|
+
throw error2;
|
|
105927
|
+
}
|
|
105928
|
+
for (const position of positions) {
|
|
105929
|
+
this.owned.delete(this.key(position));
|
|
105930
|
+
this.loaded.delete(this.key(position));
|
|
105931
|
+
}
|
|
105885
105932
|
}
|
|
105886
105933
|
validateChunk(chunk, position) {
|
|
105887
105934
|
if (chunk.x !== position.x || chunk.z !== position.z) {
|