minerender 2.1.0-alpha.120 → 2.1.0-alpha.122
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/index.d.mts +49 -3
- package/dist/browser/index.d.ts +49 -3
- package/dist/browser/index.js +236 -15
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +237 -16
- package/dist/browser/index.mjs.map +1 -1
- package/dist/browser/section.worker.js +60 -6
- package/dist/browser/section.worker.js.map +1 -1
- package/dist/browser/section.worker.mjs +60 -6
- package/dist/browser/section.worker.mjs.map +1 -1
- package/dist/bundle.js +244 -15
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +49 -3
- package/dist/node/index.d.ts +49 -3
- package/dist/node/index.js +236 -15
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +237 -16
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -100712,6 +100712,10 @@ property list uchar int vertex_index
|
|
|
100712
100712
|
get blockEntities() {
|
|
100713
100713
|
return this._entities;
|
|
100714
100714
|
}
|
|
100715
|
+
/** Model placements drawn for this block, including its fluid surface. */
|
|
100716
|
+
get models() {
|
|
100717
|
+
return this._models;
|
|
100718
|
+
}
|
|
100715
100719
|
/** Sets visibility for this block's model instances and block entities. */
|
|
100716
100720
|
setVisible(visible) {
|
|
100717
100721
|
this.visible = visible;
|
|
@@ -107752,7 +107756,8 @@ gl_FragDepth=readDepth(vUv);
|
|
|
107752
107756
|
atlas,
|
|
107753
107757
|
cullFaces: new Uint8Array(cullFaces),
|
|
107754
107758
|
occludes: ModelCulling.isOpaqueFullCube(atlas) && ModelCulling.toLocalMask(63, rotation) === 63,
|
|
107755
|
-
layer: atlas.hasTranslucency ? 1 : 0
|
|
107759
|
+
layer: atlas.hasTranslucency ? 1 : 0,
|
|
107760
|
+
ambientOcclusion: model.ambientocclusion !== false
|
|
107756
107761
|
};
|
|
107757
107762
|
this.templates.add(template);
|
|
107758
107763
|
return template;
|
|
@@ -107952,17 +107957,45 @@ gl_FragDepth=readDepth(vUv);
|
|
|
107952
107957
|
this.light = /* @__PURE__ */ new Map();
|
|
107953
107958
|
this.lightValidity = /* @__PURE__ */ new Map();
|
|
107954
107959
|
this.highestSkySection = /* @__PURE__ */ new Map();
|
|
107960
|
+
this.ambientOcclusionPending = false;
|
|
107955
107961
|
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
107956
107962
|
if (options.savedLighting && !options.sectionMeshing) throw new TypeError("savedLighting requires sectionMeshing");
|
|
107963
|
+
if (options.ambientOcclusion && !options.sectionMeshing) throw new TypeError("ambientOcclusion requires sectionMeshing");
|
|
107957
107964
|
if (options.ambientLight !== void 0 && (!Number.isFinite(options.ambientLight) || options.ambientLight < 0 || options.ambientLight > 1)) {
|
|
107958
107965
|
throw new RangeError("ambientLight must be a number from 0 to 1");
|
|
107959
107966
|
}
|
|
107960
107967
|
this.scene = scene;
|
|
107961
107968
|
this.savedLighting = options.savedLighting ?? false;
|
|
107962
107969
|
this.ambientLight = options.ambientLight ?? 0;
|
|
107970
|
+
this._ambientOcclusion = options.ambientOcclusion ?? false;
|
|
107963
107971
|
if (options.sectionMeshing) this.sectionModels = new SectionModels(options.maxAtlasSize);
|
|
107964
107972
|
if (options.renderEntities) this.entities = new WorldEntities(scene);
|
|
107965
107973
|
}
|
|
107974
|
+
/**
|
|
107975
|
+
* Returns the nearest visible block geometry hit, respecting the raycaster's layers and near/far range.
|
|
107976
|
+
* Includes fluids and block entities; texture alpha does not change triangle intersections.
|
|
107977
|
+
*/
|
|
107978
|
+
raycast(raycaster) {
|
|
107979
|
+
return Chunk.raycast(this._chunks.values(), raycaster);
|
|
107980
|
+
}
|
|
107981
|
+
/** Whether neighboring opaque cubes shade block-face corners. Defaults to false. */
|
|
107982
|
+
get ambientOcclusion() {
|
|
107983
|
+
return this._ambientOcclusion;
|
|
107984
|
+
}
|
|
107985
|
+
/** Rebuilds loaded blocks with or without corner shading. Block data and saved lighting are preserved. */
|
|
107986
|
+
async setAmbientOcclusion(enabled) {
|
|
107987
|
+
if (typeof enabled !== "boolean") throw new TypeError("Ambient occlusion must be a boolean");
|
|
107988
|
+
if (enabled && !this.sectionModels) throw new TypeError("ambientOcclusion requires sectionMeshing");
|
|
107989
|
+
if (enabled === this._ambientOcclusion && !this.ambientOcclusionPending) {
|
|
107990
|
+
await this.culling;
|
|
107991
|
+
return;
|
|
107992
|
+
}
|
|
107993
|
+
this._ambientOcclusion = enabled;
|
|
107994
|
+
this.ambientOcclusionPending = true;
|
|
107995
|
+
for (const chunk of this._chunks.values()) this.pendingCulling.set(chunk, "all");
|
|
107996
|
+
await this.updateCulling([]);
|
|
107997
|
+
this.ambientOcclusionPending = false;
|
|
107998
|
+
}
|
|
107966
107999
|
getBlockAt(posOrX, y5, z4) {
|
|
107967
108000
|
if (typeof posOrX == "number") {
|
|
107968
108001
|
return this.getBlockAt(new Vector3(posOrX, y5, z4));
|
|
@@ -108286,7 +108319,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108286
108319
|
const index = (ny & 15) * 256 + (nz & 15) * 16 + (nx & 15);
|
|
108287
108320
|
let pending = this.pendingCulling.get(section);
|
|
108288
108321
|
if (pending === "all" || pending?.has(index)) continue;
|
|
108289
|
-
if (Math.abs(x4) + Math.abs(y5) + Math.abs(z4) > 1 && !section.isFluidIndex(index)) continue;
|
|
108322
|
+
if (Math.abs(x4) + Math.abs(y5) + Math.abs(z4) > 1 && !this._ambientOcclusion && !section.isFluidIndex(index)) continue;
|
|
108290
108323
|
if (!pending) this.pendingCulling.set(section, pending = /* @__PURE__ */ new Set());
|
|
108291
108324
|
pending.add(index);
|
|
108292
108325
|
}
|
|
@@ -108294,6 +108327,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108294
108327
|
}
|
|
108295
108328
|
}
|
|
108296
108329
|
return this.culling ?? (this.culling = Promise.resolve().then(async () => {
|
|
108330
|
+
let sliceStart = performance.now();
|
|
108297
108331
|
try {
|
|
108298
108332
|
while (this.pendingCulling.size) {
|
|
108299
108333
|
const batch = [...this.pendingCulling];
|
|
@@ -108329,6 +108363,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108329
108363
|
}
|
|
108330
108364
|
for (const [index, mask] of masks) await chunk.setCullMaskIndex(index, mask);
|
|
108331
108365
|
await chunk.refreshLight(indices === "all" ? void 0 : indices);
|
|
108366
|
+
chunk.refreshAmbientOcclusion(this._ambientOcclusion);
|
|
108367
|
+
if ((this._ambientOcclusion || this.ambientOcclusionPending) && performance.now() - sliceStart > 8) {
|
|
108368
|
+
await yieldToEventLoop();
|
|
108369
|
+
sliceStart = performance.now();
|
|
108370
|
+
}
|
|
108332
108371
|
}
|
|
108333
108372
|
await Promise.all(batch.map(([chunk]) => chunk.rebuildSectionMesh()));
|
|
108334
108373
|
}
|
|
@@ -108441,6 +108480,53 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108441
108480
|
init_process2();
|
|
108442
108481
|
init_FluidQuads();
|
|
108443
108482
|
|
|
108483
|
+
// src/world/_light/AmbientOcclusion.ts
|
|
108484
|
+
init_dirname();
|
|
108485
|
+
init_buffer2();
|
|
108486
|
+
init_process2();
|
|
108487
|
+
var AXIS_STRIDES = [1, 9, 3];
|
|
108488
|
+
function sectionAmbientOcclusionMask(cells, center) {
|
|
108489
|
+
let mask = 0;
|
|
108490
|
+
for (let y5 = -1; y5 <= 1; y5++) for (let z4 = -1; z4 <= 1; z4++) for (let x4 = -1; x4 <= 1; x4++) {
|
|
108491
|
+
if (Math.abs(x4) + Math.abs(y5) + Math.abs(z4) < 2) continue;
|
|
108492
|
+
if (cells[center + y5 * 324 + z4 * 18 + x4]) mask |= 1 << (y5 + 1) * 9 + (z4 + 1) * 3 + x4 + 1;
|
|
108493
|
+
}
|
|
108494
|
+
return mask;
|
|
108495
|
+
}
|
|
108496
|
+
function cornerBrightness(mask, center, u4, v5) {
|
|
108497
|
+
const sideU = mask >>> center + u4 & 1;
|
|
108498
|
+
const sideV = mask >>> center + v5 & 1;
|
|
108499
|
+
const corner = sideU && sideV ? 1 : mask >>> center + u4 + v5 & 1;
|
|
108500
|
+
return 1 - (sideU + sideV + corner) * 0.2;
|
|
108501
|
+
}
|
|
108502
|
+
function quadAmbientOcclusion(positions, normals, quad, mask, output) {
|
|
108503
|
+
output.fill(1);
|
|
108504
|
+
if (!mask) return;
|
|
108505
|
+
const start = quad * 12;
|
|
108506
|
+
let axis = 0;
|
|
108507
|
+
if (Math.abs(normals[start + 1]) > Math.abs(normals[start + axis])) axis = 1;
|
|
108508
|
+
if (Math.abs(normals[start + 2]) > Math.abs(normals[start + axis])) axis = 2;
|
|
108509
|
+
const uAxis = (axis + 1) % 3, vAxis = (axis + 2) % 3;
|
|
108510
|
+
if (Math.abs(Math.abs(normals[start + axis]) - 1) > 1e-6 || Math.abs(normals[start + uAxis]) > 1e-6 || Math.abs(normals[start + vAxis]) > 1e-6) return;
|
|
108511
|
+
const sign = normals[start + axis] > 0 ? 1 : -1;
|
|
108512
|
+
for (let vertex2 = 0; vertex2 < 4; vertex2++) {
|
|
108513
|
+
const offset = start + vertex2 * 3;
|
|
108514
|
+
if (Math.abs(positions[offset + axis] - sign * 8) > 16e-4 || Math.abs(positions[offset + uAxis]) > 8.0016 || Math.abs(positions[offset + vAxis]) > 8.0016) return;
|
|
108515
|
+
}
|
|
108516
|
+
const center = 13 + sign * AXIS_STRIDES[axis];
|
|
108517
|
+
const u4 = AXIS_STRIDES[uAxis], v5 = AXIS_STRIDES[vAxis];
|
|
108518
|
+
const lowLow = cornerBrightness(mask, center, -u4, -v5);
|
|
108519
|
+
const highLow = cornerBrightness(mask, center, u4, -v5);
|
|
108520
|
+
const lowHigh = cornerBrightness(mask, center, -u4, v5);
|
|
108521
|
+
const highHigh = cornerBrightness(mask, center, u4, v5);
|
|
108522
|
+
for (let vertex2 = 0; vertex2 < 4; vertex2++) {
|
|
108523
|
+
const offset = start + vertex2 * 3;
|
|
108524
|
+
const a4 = Math.max(0, Math.min(1, (positions[offset + uAxis] + 8) / 16));
|
|
108525
|
+
const b4 = Math.max(0, Math.min(1, (positions[offset + vAxis] + 8) / 16));
|
|
108526
|
+
output[vertex2] = (lowLow * (1 - a4) + highLow * a4) * (1 - b4) + (lowHigh * (1 - a4) + highHigh * a4) * b4;
|
|
108527
|
+
}
|
|
108528
|
+
}
|
|
108529
|
+
|
|
108444
108530
|
// src/world/_light/FaceLight.ts
|
|
108445
108531
|
init_dirname();
|
|
108446
108532
|
init_buffer2();
|
|
@@ -108469,7 +108555,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108469
108555
|
|
|
108470
108556
|
// src/world/SectionGeometry.ts
|
|
108471
108557
|
function buildSectionGeometry(input) {
|
|
108472
|
-
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight } = input;
|
|
108558
|
+
const { count, indices, templates, cullMasks, templateData, atlases, maxAtlasSize, fluids, light, ambientLight, ambientOcclusion } = input;
|
|
108473
108559
|
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
108474
108560
|
if (count > indices.length || count > templates.length || count > cullMasks.length) throw new RangeError("Section entry count exceeds its arrays");
|
|
108475
108561
|
if (fluids && fluids.cells.length !== 5832) throw new RangeError("Section fluid cells must cover an 18\xD718\xD718 neighborhood");
|
|
@@ -108480,6 +108566,10 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108480
108566
|
if (ambientLight !== void 0 && (!Number.isFinite(ambientLight) || ambientLight < 0 || ambientLight > 1)) {
|
|
108481
108567
|
throw new RangeError("Section ambient light must be a number from 0 to 1");
|
|
108482
108568
|
}
|
|
108569
|
+
if (ambientOcclusion && (ambientOcclusion.length !== 5832 || ambientOcclusion.some((value) => value > 1))) {
|
|
108570
|
+
throw new RangeError("Section ambient occlusion must cover an 18\xD718\xD718 neighborhood with zero or one per cell");
|
|
108571
|
+
}
|
|
108572
|
+
const cornerBrightness2 = ambientOcclusion ? new Float32Array(4) : void 0;
|
|
108483
108573
|
for (const template of templateData) {
|
|
108484
108574
|
const { quads } = template;
|
|
108485
108575
|
if (template.positions.length !== quads * 12 || template.normals.length !== quads * 12 || template.uvs.length !== quads * 8 || template.uvBounds.length !== quads * 16 || template.colors.length !== quads * 12 || template.indices.length !== quads * 6 || template.cullFaces.length !== quads) {
|
|
@@ -108574,6 +108664,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108574
108664
|
const positions = new Float32Array(faces * 12), normals = new Float32Array(faces * 12);
|
|
108575
108665
|
const uvs = new Float32Array(faces * 8), uvBounds = new Float32Array(faces * 16), colors = new Float32Array(faces * 12);
|
|
108576
108666
|
const outputIndices = new Uint32Array(faces * 6);
|
|
108667
|
+
const blockIndices = new Uint16Array(faces);
|
|
108577
108668
|
let vertex2 = 0, indexOffset = 0;
|
|
108578
108669
|
for (const entry of page.entries) {
|
|
108579
108670
|
const template = templateData[templates[entry]];
|
|
@@ -108585,8 +108676,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108585
108676
|
const offsetY = Math.floor(indices[entry] / 256) * 16;
|
|
108586
108677
|
const offsetZ = Math.floor(indices[entry] / 16) % 16 * 16;
|
|
108587
108678
|
const lightIndex = (offsetY / 16 + 1) * 324 + (offsetZ / 16 + 1) * 18 + offsetX / 16 + 1;
|
|
108679
|
+
const ambientMask = ambientOcclusion && template.ambientOcclusion !== false ? sectionAmbientOcclusionMask(ambientOcclusion, lightIndex) : 0;
|
|
108588
108680
|
for (let quad = 0; quad < template.quads; quad++) {
|
|
108589
108681
|
if (cullMasks[entry] & template.cullFaces[quad]) continue;
|
|
108682
|
+
blockIndices[indexOffset / 6] = indices[entry];
|
|
108683
|
+
if (ambientMask) quadAmbientOcclusion(template.positions, template.normals, quad, ambientMask, cornerBrightness2);
|
|
108590
108684
|
const brightness = light ? lightBrightness(light[lightIndex + LIGHT_SAMPLE_OFFSETS[quadLightIndex(template.positions, template.normals, quad)]], ambientLight) : 1;
|
|
108591
108685
|
const start = vertex2;
|
|
108592
108686
|
for (let corner = 0; corner < 4; corner++, vertex2++) {
|
|
@@ -108603,9 +108697,10 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108603
108697
|
uvBounds[vertex2 * 4 + 1] = mapV(template.uvBounds[source * 4 + 1]);
|
|
108604
108698
|
uvBounds[vertex2 * 4 + 2] = mapU(template.uvBounds[source * 4 + 2]);
|
|
108605
108699
|
uvBounds[vertex2 * 4 + 3] = mapV(template.uvBounds[source * 4 + 3]);
|
|
108606
|
-
|
|
108607
|
-
colors[vertex2 * 3
|
|
108608
|
-
colors[vertex2 * 3 +
|
|
108700
|
+
const factor = brightness * (ambientMask ? cornerBrightness2[corner] : 1);
|
|
108701
|
+
colors[vertex2 * 3] = template.colors[source * 3] * factor;
|
|
108702
|
+
colors[vertex2 * 3 + 1] = template.colors[source * 3 + 1] * factor;
|
|
108703
|
+
colors[vertex2 * 3 + 2] = template.colors[source * 3 + 2] * factor;
|
|
108609
108704
|
}
|
|
108610
108705
|
for (let corner = 0; corner < 6; corner++) outputIndices[indexOffset++] = start + template.indices[quad * 6 + corner];
|
|
108611
108706
|
}
|
|
@@ -108617,6 +108712,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108617
108712
|
const mapV = (v5) => 1 - (placement.y + (1 - v5) * atlas.height) / page.height;
|
|
108618
108713
|
const lightIndex = (y5 + 1) * 324 + (z4 + 1) * 18 + x4 + 1;
|
|
108619
108714
|
for (let quad = 0; quad < quads.sprites.length; quad++) {
|
|
108715
|
+
blockIndices[indexOffset / 6] = x4 + z4 * 16 + y5 * 256;
|
|
108620
108716
|
const rect = quads.sprites[quad] === 0 ? data.still : data.flow;
|
|
108621
108717
|
const brightness = light ? lightBrightness(fluidLightLevel(
|
|
108622
108718
|
light[lightIndex],
|
|
@@ -108647,11 +108743,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108647
108743
|
indexOffset += 6;
|
|
108648
108744
|
}
|
|
108649
108745
|
}
|
|
108650
|
-
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices };
|
|
108746
|
+
return { layer: page.layer, width: page.width, height: page.height, placements: page.placements, positions, normals, uvs, uvBounds, colors, indices: outputIndices, blockIndices };
|
|
108651
108747
|
});
|
|
108652
108748
|
}
|
|
108653
108749
|
function sectionGeometryTransferables(pages) {
|
|
108654
|
-
return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer]);
|
|
108750
|
+
return pages.flatMap((page) => [page.positions.buffer, page.normals.buffer, page.uvs.buffer, page.uvBounds.buffer, page.colors.buffer, page.indices.buffer, page.blockIndices.buffer]);
|
|
108655
108751
|
}
|
|
108656
108752
|
|
|
108657
108753
|
// src/world/SectionWorker.ts
|
|
@@ -108756,7 +108852,8 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108756
108852
|
indices: new Uint16Array(quads * 6),
|
|
108757
108853
|
cullFaces: new Uint8Array(template.cullFaces),
|
|
108758
108854
|
atlas: 0,
|
|
108759
|
-
layer: template.layer
|
|
108855
|
+
layer: template.layer,
|
|
108856
|
+
ambientOcclusion: template.ambientOcclusion
|
|
108760
108857
|
};
|
|
108761
108858
|
const normal = template.geometry.getAttribute("normal");
|
|
108762
108859
|
const uv = template.geometry.getAttribute("uv");
|
|
@@ -108811,6 +108908,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108811
108908
|
constructor() {
|
|
108812
108909
|
super(...arguments);
|
|
108813
108910
|
this.ownedMeshes = [];
|
|
108911
|
+
this.blockIndices = /* @__PURE__ */ new Map();
|
|
108912
|
+
}
|
|
108913
|
+
/** Returns the owning section cell for a triangle hit on this mesh's merged geometry. */
|
|
108914
|
+
getBlockIndex(hit) {
|
|
108915
|
+
if (hit.faceIndex === void 0 || hit.faceIndex === null) return void 0;
|
|
108916
|
+
return this.blockIndices.get(hit.object)?.[Math.floor(hit.faceIndex / 2)];
|
|
108814
108917
|
}
|
|
108815
108918
|
/** Builds section-local meshes from visible quads. `maxAtlasSize` limits each atlas dimension in pixels. */
|
|
108816
108919
|
static build(entries, maxAtlasSize = 2048, fluids, lighting) {
|
|
@@ -108853,6 +108956,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108853
108956
|
const texture = material.uniforms?.map?.value ?? material.map;
|
|
108854
108957
|
const mesh = new Mesh(geometry, material);
|
|
108855
108958
|
section.add(mesh);
|
|
108959
|
+
section.blockIndices.set(mesh, page.blockIndices);
|
|
108856
108960
|
const unsubscribe = [];
|
|
108857
108961
|
for (const { atlas: id, x: x4, y: y5 } of page.placements) {
|
|
108858
108962
|
const atlas = atlases[id];
|
|
@@ -108878,6 +108982,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108878
108982
|
mesh.material.dispose();
|
|
108879
108983
|
texture?.dispose();
|
|
108880
108984
|
}
|
|
108985
|
+
this.blockIndices.clear();
|
|
108881
108986
|
this.removeFromParent();
|
|
108882
108987
|
super.dispose();
|
|
108883
108988
|
}
|
|
@@ -108887,6 +108992,8 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108887
108992
|
init_FluidGeometry();
|
|
108888
108993
|
init_FluidQuads();
|
|
108889
108994
|
init_CubeFace();
|
|
108995
|
+
init_InstanceReference();
|
|
108996
|
+
init_three();
|
|
108890
108997
|
var WATER_TINT2 = new Color(4159204).toArray();
|
|
108891
108998
|
var Chunk = class _Chunk {
|
|
108892
108999
|
constructor(scene, x4, y5, z4, onBlocksChanged, sectionModels, neighborCell, biomeAt, onBiomesChanged, lightAt, onLightCleared, ambientLight = 0) {
|
|
@@ -108900,6 +109007,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108900
109007
|
this.ambientLight = ambientLight;
|
|
108901
109008
|
this.data = new ChunkData();
|
|
108902
109009
|
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
109010
|
+
this.objectBlocks = /* @__PURE__ */ new Set();
|
|
108903
109011
|
this.sectionBlocks = /* @__PURE__ */ new Map();
|
|
108904
109012
|
this.hiddenBlocks = /* @__PURE__ */ new Set();
|
|
108905
109013
|
this.fluidCells = new Uint8Array(4096);
|
|
@@ -108911,6 +109019,89 @@ gl_FragDepth=readDepth(vUv);
|
|
|
108911
109019
|
this.y = y5;
|
|
108912
109020
|
this.z = z4;
|
|
108913
109021
|
}
|
|
109022
|
+
/** Finds the nearest owned block hit across sections, testing each shared mesh once. */
|
|
109023
|
+
static raycast(chunks, raycaster) {
|
|
109024
|
+
const roots = /* @__PURE__ */ new Map();
|
|
109025
|
+
const targets = /* @__PURE__ */ new Map();
|
|
109026
|
+
const meshes = (root, scene) => {
|
|
109027
|
+
const cached2 = roots.get(root);
|
|
109028
|
+
if (cached2) return cached2;
|
|
109029
|
+
const result = [];
|
|
109030
|
+
roots.set(root, result);
|
|
109031
|
+
let attached = false;
|
|
109032
|
+
for (let parent = root; parent; parent = parent.parent) {
|
|
109033
|
+
if (!parent.visible) return result;
|
|
109034
|
+
if (parent === scene) attached = true;
|
|
109035
|
+
}
|
|
109036
|
+
if (!attached) return result;
|
|
109037
|
+
root.updateWorldMatrix(true, true);
|
|
109038
|
+
root.traverseVisible((object4) => {
|
|
109039
|
+
if (isMesh(object4) && raycaster.layers.test(object4.layers)) result.push(object4);
|
|
109040
|
+
});
|
|
109041
|
+
return result;
|
|
109042
|
+
};
|
|
109043
|
+
const add = (root, owner, reference) => {
|
|
109044
|
+
for (const mesh of meshes(root, owner.chunk.scene)) {
|
|
109045
|
+
if (reference && reference.instanceable.getInstanceReference(mesh, reference.index) !== reference) continue;
|
|
109046
|
+
let entry = targets.get(mesh);
|
|
109047
|
+
if (!entry) targets.set(mesh, entry = { owners: /* @__PURE__ */ new Map() });
|
|
109048
|
+
entry.owners.set(reference?.index, owner);
|
|
109049
|
+
}
|
|
109050
|
+
};
|
|
109051
|
+
for (const chunk of chunks) {
|
|
109052
|
+
for (const index of chunk.objectBlocks) {
|
|
109053
|
+
const block = chunk.renderedBlocks.get(index).object;
|
|
109054
|
+
if (!block || !block.visible || chunk.hiddenBlocks.has(index)) continue;
|
|
109055
|
+
const owner = { chunk, index };
|
|
109056
|
+
for (const model of block.models) {
|
|
109057
|
+
if (isInstanceReference(model)) {
|
|
109058
|
+
if (model.instanceable.isInstanceActive(model.index, model)) add(model.instanceable, owner, model);
|
|
109059
|
+
} else {
|
|
109060
|
+
add(model, owner);
|
|
109061
|
+
}
|
|
109062
|
+
}
|
|
109063
|
+
for (const entity of block.blockEntities) add(entity, owner);
|
|
109064
|
+
}
|
|
109065
|
+
if (chunk.sectionMesh) {
|
|
109066
|
+
for (const mesh of meshes(chunk.sectionMesh, chunk.scene)) {
|
|
109067
|
+
targets.set(mesh, { owners: /* @__PURE__ */ new Map(), section: { chunk, mesh: chunk.sectionMesh } });
|
|
109068
|
+
}
|
|
109069
|
+
}
|
|
109070
|
+
}
|
|
109071
|
+
for (const hit of raycaster.intersectObjects([...targets.keys()], false)) {
|
|
109072
|
+
if (!hit.face) continue;
|
|
109073
|
+
const mesh = hit.object;
|
|
109074
|
+
const material = Array.isArray(mesh.material) ? mesh.material[hit.face.materialIndex] : mesh.material;
|
|
109075
|
+
if (!material?.visible) continue;
|
|
109076
|
+
const entry = targets.get(mesh);
|
|
109077
|
+
let owner = entry.owners.get(hit.instanceId) ?? entry.owners.get(void 0);
|
|
109078
|
+
if (entry.section) {
|
|
109079
|
+
const index = entry.section.mesh.getBlockIndex(hit);
|
|
109080
|
+
if (index !== void 0) owner = { chunk: entry.section.chunk, index };
|
|
109081
|
+
}
|
|
109082
|
+
if (!owner || owner.chunk.hiddenBlocks.has(owner.index)) continue;
|
|
109083
|
+
const info = owner.chunk.renderedBlocks.get(owner.index);
|
|
109084
|
+
if (!info) continue;
|
|
109085
|
+
const matrix = mesh.matrixWorld.clone();
|
|
109086
|
+
if (isInstancedMesh(mesh) && hit.instanceId !== void 0) {
|
|
109087
|
+
const instance = new Matrix4();
|
|
109088
|
+
mesh.getMatrixAt(hit.instanceId, instance);
|
|
109089
|
+
matrix.multiply(instance);
|
|
109090
|
+
}
|
|
109091
|
+
return {
|
|
109092
|
+
position: new Vector3(
|
|
109093
|
+
owner.chunk.x * 16 + owner.index % 16,
|
|
109094
|
+
owner.chunk.y * 16 + Math.floor(owner.index / 256),
|
|
109095
|
+
owner.chunk.z * 16 + Math.floor(owner.index / 16) % 16
|
|
109096
|
+
),
|
|
109097
|
+
block: info.block,
|
|
109098
|
+
point: hit.point.clone(),
|
|
109099
|
+
normal: hit.face.normal.clone().applyNormalMatrix(new Matrix3().getNormalMatrix(matrix)),
|
|
109100
|
+
distance: hit.distance
|
|
109101
|
+
};
|
|
109102
|
+
}
|
|
109103
|
+
return void 0;
|
|
109104
|
+
}
|
|
108914
109105
|
getBlockAt(posOrX, y5, z4) {
|
|
108915
109106
|
if (typeof posOrX == "number") {
|
|
108916
109107
|
return this.getBlockAt(new Vector3(posOrX, y5, z4));
|
|
@@ -109031,6 +109222,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109031
109222
|
if (this.fluidCells[index]) this.meshDirty = true;
|
|
109032
109223
|
this.fluidCells[index] = 0;
|
|
109033
109224
|
this.renderedBlocks.delete(index);
|
|
109225
|
+
this.objectBlocks.delete(index);
|
|
109034
109226
|
const worldPos = new Vector3(
|
|
109035
109227
|
this.x * 16 + index % 16,
|
|
109036
109228
|
this.y * 16 + Math.floor(index / 256),
|
|
@@ -109073,6 +109265,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109073
109265
|
this.renderedBlocks.set(index, { get block() {
|
|
109074
109266
|
return readBlock();
|
|
109075
109267
|
}, object: object4 });
|
|
109268
|
+
if (object4) this.objectBlocks.add(index);
|
|
109076
109269
|
} catch (error2) {
|
|
109077
109270
|
this.data.assign(index, 0);
|
|
109078
109271
|
this.fluidCells[index] = 0;
|
|
@@ -109091,6 +109284,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109091
109284
|
this.fluidCells.fill(0);
|
|
109092
109285
|
this.waterTints = void 0;
|
|
109093
109286
|
this.renderedBlocks.clear();
|
|
109287
|
+
this.objectBlocks.clear();
|
|
109094
109288
|
this.hiddenBlocks.clear();
|
|
109095
109289
|
this.meshDirty = true;
|
|
109096
109290
|
this.data.copyFrom(data);
|
|
@@ -109140,6 +109334,7 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109140
109334
|
this.renderedBlocks.set(index, { get block() {
|
|
109141
109335
|
return readBlock();
|
|
109142
109336
|
}, object: void 0 });
|
|
109337
|
+
this.objectBlocks.delete(index);
|
|
109143
109338
|
} catch (error2) {
|
|
109144
109339
|
this.data.assign(index, 0);
|
|
109145
109340
|
this.fluidCells[index] = 0;
|
|
@@ -109165,10 +109360,12 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109165
109360
|
this.z * 256 + Math.floor(index / 16) % 16 * 16
|
|
109166
109361
|
));
|
|
109167
109362
|
this.renderedBlocks.get(index).object = object4;
|
|
109363
|
+
this.objectBlocks.add(index);
|
|
109168
109364
|
} catch (error2) {
|
|
109169
109365
|
this.data.assign(index, 0);
|
|
109170
109366
|
this.fluidCells[index] = 0;
|
|
109171
109367
|
this.renderedBlocks.delete(index);
|
|
109368
|
+
this.objectBlocks.delete(index);
|
|
109172
109369
|
object4?.removeFromScene();
|
|
109173
109370
|
if (!failed) failure = error2;
|
|
109174
109371
|
failed = true;
|
|
@@ -109186,6 +109383,25 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109186
109383
|
if (this.renderedBlocks.has(index)) this.meshDirty = true;
|
|
109187
109384
|
}
|
|
109188
109385
|
}
|
|
109386
|
+
/** Refreshes baked corner shading after edits or a world setting change. Disabled chunks keep no AO neighborhood. */
|
|
109387
|
+
refreshAmbientOcclusion(enabled) {
|
|
109388
|
+
if (!enabled && !this.ambientOcclusionCells) return;
|
|
109389
|
+
const cells = enabled ? this.buildAmbientOcclusionCells() : void 0;
|
|
109390
|
+
if (cells?.some((value, index) => value !== this.ambientOcclusionCells?.[index]) || !!cells !== !!this.ambientOcclusionCells) this.meshDirty = true;
|
|
109391
|
+
this.ambientOcclusionCells = cells;
|
|
109392
|
+
}
|
|
109393
|
+
buildAmbientOcclusionCells() {
|
|
109394
|
+
const cells = new Uint8Array(18 * 18 * 18);
|
|
109395
|
+
for (let y5 = -1; y5 <= 16; y5++) {
|
|
109396
|
+
for (let z4 = -1; z4 <= 16; z4++) {
|
|
109397
|
+
for (let x4 = -1; x4 <= 16; x4++) {
|
|
109398
|
+
const inner = x4 >= 0 && x4 < 16 && y5 >= 0 && y5 < 16 && z4 >= 0 && z4 < 16;
|
|
109399
|
+
cells[(y5 + 1) * 324 + (z4 + 1) * 18 + x4 + 1] = inner ? Number(this.isOccludingIndex(y5 * 256 + z4 * 16 + x4)) : Number(!!((this.neighborCell?.(this.x * 16 + x4, this.y * 16 + y5, this.z * 16 + z4) ?? 0) & 64));
|
|
109400
|
+
}
|
|
109401
|
+
}
|
|
109402
|
+
}
|
|
109403
|
+
return cells;
|
|
109404
|
+
}
|
|
109189
109405
|
biomePosition(index, blockState3, stored) {
|
|
109190
109406
|
const position = this.positionAt(index), name2 = blockState3.key?.toNamespacedString();
|
|
109191
109407
|
if (stored.properties?.half === "upper" && (name2 === "minecraft:tall_grass" || name2 === "minecraft:large_fern")) position[1]--;
|
|
@@ -109374,12 +109590,18 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109374
109590
|
}
|
|
109375
109591
|
}
|
|
109376
109592
|
}
|
|
109377
|
-
|
|
109378
|
-
|
|
109379
|
-
|
|
109380
|
-
|
|
109381
|
-
|
|
109382
|
-
|
|
109593
|
+
let next;
|
|
109594
|
+
try {
|
|
109595
|
+
next = entries.length || fluids ? await SectionMesh.buildAsync(
|
|
109596
|
+
entries,
|
|
109597
|
+
this.sectionModels.maxAtlasSize,
|
|
109598
|
+
fluids,
|
|
109599
|
+
{ light, ambientLight: this.ambientLight, ambientOcclusion: this.ambientOcclusionCells }
|
|
109600
|
+
) : void 0;
|
|
109601
|
+
} catch (error2) {
|
|
109602
|
+
if (generation === this.meshGeneration) this.meshDirty = true;
|
|
109603
|
+
throw error2;
|
|
109604
|
+
}
|
|
109383
109605
|
if (generation !== this.meshGeneration) {
|
|
109384
109606
|
next?.dispose();
|
|
109385
109607
|
return;
|
|
@@ -109404,9 +109626,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109404
109626
|
this.sectionMesh = void 0;
|
|
109405
109627
|
this.meshDirty = false;
|
|
109406
109628
|
this.renderedBlocks.clear();
|
|
109629
|
+
this.objectBlocks.clear();
|
|
109407
109630
|
this.hiddenBlocks.clear();
|
|
109408
109631
|
this.fluidCells.fill(0);
|
|
109409
109632
|
this.waterTints = void 0;
|
|
109633
|
+
this.ambientOcclusionCells = void 0;
|
|
109410
109634
|
this.data.clear();
|
|
109411
109635
|
this.biomes = void 0;
|
|
109412
109636
|
if (notify) {
|
|
@@ -109444,6 +109668,11 @@ gl_FragDepth=readDepth(vUv);
|
|
|
109444
109668
|
}
|
|
109445
109669
|
};
|
|
109446
109670
|
|
|
109671
|
+
// src/world/WorldBlockIntersection.ts
|
|
109672
|
+
init_dirname();
|
|
109673
|
+
init_buffer2();
|
|
109674
|
+
init_process2();
|
|
109675
|
+
|
|
109447
109676
|
// src/world/WorldChunkSource.ts
|
|
109448
109677
|
init_dirname();
|
|
109449
109678
|
init_buffer2();
|