minerender 2.1.0-alpha.125 → 2.1.0-alpha.127
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 +25 -3
- package/dist/browser/index.d.ts +25 -3
- package/dist/browser/index.js +78 -11
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +78 -11
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +81 -11
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +25 -3
- package/dist/node/index.d.ts +25 -3
- package/dist/node/index.js +78 -11
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +78 -11
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as three from 'three';
|
|
2
|
-
import { Vector3, PixelFormat, BoxGeometry, Material, ColorRepresentation, MeshBasicMaterial, Mesh, Euler, Vector2, BufferAttribute, Float32BufferAttribute, BufferGeometry, Object3D, Box3, InstancedMesh, PerspectiveCamera, OrthographicCamera, Matrix4, Box2, Scene, Object3DEventMap, ShaderMaterial, Texture, Camera, MOUSE, TOUCH, Controls, WebGLRenderer, EventDispatcher, Raycaster, Intersection, Group, DataTexture, CanvasTexture, InterleavedBufferAttribute, TrianglesDrawModes, Line, Points } from 'three';
|
|
2
|
+
import { Vector3, PixelFormat, BoxGeometry, Material, ColorRepresentation, MeshBasicMaterial, Mesh, Euler, Vector2, BufferAttribute, Float32BufferAttribute, BufferGeometry, Object3D, Box3, InstancedMesh, PerspectiveCamera, OrthographicCamera, Matrix4, Quaternion, Box2, Scene, Object3DEventMap, ShaderMaterial, Texture, Camera, MOUSE, TOUCH, Controls, WebGLRenderer, EventDispatcher, Raycaster, Intersection, Group, DataTexture, CanvasTexture, InterleavedBufferAttribute, TrianglesDrawModes, Line, Points } from 'three';
|
|
3
3
|
import * as nodeCanvas from 'canvas';
|
|
4
4
|
import { ImageData as ImageData$1, CanvasRenderingContext2D } from 'canvas';
|
|
5
5
|
import { Buffer } from 'buffer';
|
|
@@ -1310,6 +1310,15 @@ interface MineRenderDatasets {
|
|
|
1310
1310
|
untinted?: number[];
|
|
1311
1311
|
biome?: BiomeColorKind;
|
|
1312
1312
|
}>;
|
|
1313
|
+
blockCulling: {
|
|
1314
|
+
profiles: {
|
|
1315
|
+
type: string;
|
|
1316
|
+
group?: string;
|
|
1317
|
+
kind?: string;
|
|
1318
|
+
}[];
|
|
1319
|
+
blocks: Record<string, number>;
|
|
1320
|
+
groups?: Record<string, string[]>;
|
|
1321
|
+
};
|
|
1313
1322
|
fluids: Record<string, {
|
|
1314
1323
|
kind: "water" | "lava";
|
|
1315
1324
|
renderModel: boolean;
|
|
@@ -1422,6 +1431,12 @@ declare class DisplayTransforms {
|
|
|
1422
1431
|
static withHandFallbacks(display: Model["display"]): Model["display"];
|
|
1423
1432
|
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1424
1433
|
static getMatrix(display: Model["display"], position: DisplayPosition): Matrix4;
|
|
1434
|
+
/** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1435
|
+
static getTransform(display: Model["display"], position: DisplayPosition): {
|
|
1436
|
+
position: Vector3;
|
|
1437
|
+
quaternion: Quaternion;
|
|
1438
|
+
scale: Vector3;
|
|
1439
|
+
};
|
|
1425
1440
|
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1426
1441
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1427
1442
|
}
|
|
@@ -3889,6 +3904,8 @@ interface WorldBlockIntersection {
|
|
|
3889
3904
|
distance: number;
|
|
3890
3905
|
}
|
|
3891
3906
|
|
|
3907
|
+
type BlockCullingData = MineRenderDatasets["blockCulling"];
|
|
3908
|
+
|
|
3892
3909
|
/**
|
|
3893
3910
|
* A 16×16×16 block section and its render objects.
|
|
3894
3911
|
* Constructor coordinates identify the section. Block accessors use world block coordinates
|
|
@@ -3965,6 +3982,8 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3965
3982
|
isBlockVisibleAt(pos: Vector3): boolean;
|
|
3966
3983
|
/** Reports whether a cell has a visible render object or section entry. */
|
|
3967
3984
|
isBlockVisibleIndex(index: number): boolean;
|
|
3985
|
+
/** Stored state of a rendered, visible cell, or `undefined`. */
|
|
3986
|
+
visibleBlockIndex(index: number): Maybe<Pick<Block, "type" | "properties">>;
|
|
3968
3987
|
/** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
|
|
3969
3988
|
fluidByteIndex(index: number): number;
|
|
3970
3989
|
/** Whether the cell holds a fluid, merged or per-block. */
|
|
@@ -3973,8 +3992,11 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3973
3992
|
/** Reports whether a visible cell hides neighboring cube faces. */
|
|
3974
3993
|
isOccludingIndex(index: number): boolean;
|
|
3975
3994
|
setCullMaskAt(pos: Vector3, mask: number): Promise<void>;
|
|
3976
|
-
/**
|
|
3977
|
-
|
|
3995
|
+
/**
|
|
3996
|
+
* Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
|
|
3997
|
+
* `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
|
|
3998
|
+
*/
|
|
3999
|
+
updateCullMasks(indices: Iterable<number> | undefined, occludes: (x: number, y: number, z: number) => boolean, culling?: BlockCullingData, blockAt?: (x: number, y: number, z: number) => Maybe<Pick<Block, "type" | "properties">>): [number, number][];
|
|
3978
4000
|
/** Updates hidden faces for a cell's section entry or individual render object. */
|
|
3979
4001
|
setCullMaskIndex(index: number, mask: number): Promise<void>;
|
|
3980
4002
|
/** Rebuilds visible section geometry and discards results superseded by another rebuild or clear. */
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as three from 'three';
|
|
2
|
-
import { Vector3, PixelFormat, BoxGeometry, Material, ColorRepresentation, MeshBasicMaterial, Mesh, Euler, Vector2, BufferAttribute, Float32BufferAttribute, BufferGeometry, Object3D, Box3, InstancedMesh, PerspectiveCamera, OrthographicCamera, Matrix4, Box2, Scene, Object3DEventMap, ShaderMaterial, Texture, Camera, MOUSE, TOUCH, Controls, WebGLRenderer, EventDispatcher, Raycaster, Intersection, Group, DataTexture, CanvasTexture, InterleavedBufferAttribute, TrianglesDrawModes, Line, Points } from 'three';
|
|
2
|
+
import { Vector3, PixelFormat, BoxGeometry, Material, ColorRepresentation, MeshBasicMaterial, Mesh, Euler, Vector2, BufferAttribute, Float32BufferAttribute, BufferGeometry, Object3D, Box3, InstancedMesh, PerspectiveCamera, OrthographicCamera, Matrix4, Quaternion, Box2, Scene, Object3DEventMap, ShaderMaterial, Texture, Camera, MOUSE, TOUCH, Controls, WebGLRenderer, EventDispatcher, Raycaster, Intersection, Group, DataTexture, CanvasTexture, InterleavedBufferAttribute, TrianglesDrawModes, Line, Points } from 'three';
|
|
3
3
|
import * as nodeCanvas from 'canvas';
|
|
4
4
|
import { ImageData as ImageData$1, CanvasRenderingContext2D } from 'canvas';
|
|
5
5
|
import { Buffer } from 'buffer';
|
|
@@ -1310,6 +1310,15 @@ interface MineRenderDatasets {
|
|
|
1310
1310
|
untinted?: number[];
|
|
1311
1311
|
biome?: BiomeColorKind;
|
|
1312
1312
|
}>;
|
|
1313
|
+
blockCulling: {
|
|
1314
|
+
profiles: {
|
|
1315
|
+
type: string;
|
|
1316
|
+
group?: string;
|
|
1317
|
+
kind?: string;
|
|
1318
|
+
}[];
|
|
1319
|
+
blocks: Record<string, number>;
|
|
1320
|
+
groups?: Record<string, string[]>;
|
|
1321
|
+
};
|
|
1313
1322
|
fluids: Record<string, {
|
|
1314
1323
|
kind: "water" | "lava";
|
|
1315
1324
|
renderModel: boolean;
|
|
@@ -1422,6 +1431,12 @@ declare class DisplayTransforms {
|
|
|
1422
1431
|
static withHandFallbacks(display: Model["display"]): Model["display"];
|
|
1423
1432
|
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1424
1433
|
static getMatrix(display: Model["display"], position: DisplayPosition): Matrix4;
|
|
1434
|
+
/** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1435
|
+
static getTransform(display: Model["display"], position: DisplayPosition): {
|
|
1436
|
+
position: Vector3;
|
|
1437
|
+
quaternion: Quaternion;
|
|
1438
|
+
scale: Vector3;
|
|
1439
|
+
};
|
|
1425
1440
|
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1426
1441
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1427
1442
|
}
|
|
@@ -3889,6 +3904,8 @@ interface WorldBlockIntersection {
|
|
|
3889
3904
|
distance: number;
|
|
3890
3905
|
}
|
|
3891
3906
|
|
|
3907
|
+
type BlockCullingData = MineRenderDatasets["blockCulling"];
|
|
3908
|
+
|
|
3892
3909
|
/**
|
|
3893
3910
|
* A 16×16×16 block section and its render objects.
|
|
3894
3911
|
* Constructor coordinates identify the section. Block accessors use world block coordinates
|
|
@@ -3965,6 +3982,8 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3965
3982
|
isBlockVisibleAt(pos: Vector3): boolean;
|
|
3966
3983
|
/** Reports whether a cell has a visible render object or section entry. */
|
|
3967
3984
|
isBlockVisibleIndex(index: number): boolean;
|
|
3985
|
+
/** Stored state of a rendered, visible cell, or `undefined`. */
|
|
3986
|
+
visibleBlockIndex(index: number): Maybe<Pick<Block, "type" | "properties">>;
|
|
3968
3987
|
/** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
|
|
3969
3988
|
fluidByteIndex(index: number): number;
|
|
3970
3989
|
/** Whether the cell holds a fluid, merged or per-block. */
|
|
@@ -3973,8 +3992,11 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3973
3992
|
/** Reports whether a visible cell hides neighboring cube faces. */
|
|
3974
3993
|
isOccludingIndex(index: number): boolean;
|
|
3975
3994
|
setCullMaskAt(pos: Vector3, mask: number): Promise<void>;
|
|
3976
|
-
/**
|
|
3977
|
-
|
|
3995
|
+
/**
|
|
3996
|
+
* Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
|
|
3997
|
+
* `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
|
|
3998
|
+
*/
|
|
3999
|
+
updateCullMasks(indices: Iterable<number> | undefined, occludes: (x: number, y: number, z: number) => boolean, culling?: BlockCullingData, blockAt?: (x: number, y: number, z: number) => Maybe<Pick<Block, "type" | "properties">>): [number, number][];
|
|
3978
4000
|
/** Updates hidden faces for a cell's section entry or individual render object. */
|
|
3979
4001
|
setCullMaskIndex(index: number, mask: number): Promise<void>;
|
|
3980
4002
|
/** Rebuilds visible section geometry and discards results superseded by another rebuild or clear. */
|
package/dist/browser/index.js
CHANGED
|
@@ -1479,6 +1479,11 @@ var init_DisplayTransforms = __esm({
|
|
|
1479
1479
|
}
|
|
1480
1480
|
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1481
1481
|
static getMatrix(display, position) {
|
|
1482
|
+
const transform = this.getTransform(display, position);
|
|
1483
|
+
return new import_three7.Matrix4().compose(transform.position, transform.quaternion, transform.scale);
|
|
1484
|
+
}
|
|
1485
|
+
/** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1486
|
+
static getTransform(display, position) {
|
|
1482
1487
|
const transform = this.withHandFallbacks(display)?.[position] ?? {};
|
|
1483
1488
|
const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
|
|
1484
1489
|
const sign = left ? -1 : 1;
|
|
@@ -1487,7 +1492,7 @@ var init_DisplayTransforms = __esm({
|
|
|
1487
1492
|
const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
|
|
1488
1493
|
translation.x *= sign;
|
|
1489
1494
|
const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
|
|
1490
|
-
return
|
|
1495
|
+
return { position: translation, quaternion: rotation, scale };
|
|
1491
1496
|
}
|
|
1492
1497
|
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1493
1498
|
static apply(geometry, matrix) {
|
|
@@ -1672,6 +1677,7 @@ ${key}` : key, async () => {
|
|
|
1672
1677
|
if (!object(data)) return false;
|
|
1673
1678
|
if (dataset === "potionColors") return object(data.effects) && Object.values(data.effects).every(Number.isInteger) && object(data.potions) && Object.values(data.potions).every((effects) => Array.isArray(effects) && effects.every((effect) => object(effect) && typeof effect.id === "string" && Number.isInteger(effect.amplifier)));
|
|
1674
1679
|
if (dataset === "legacyBlocks") return object(data.blocks) && Object.values(data.blocks).every((value) => typeof value === "string");
|
|
1680
|
+
if (dataset === "blockCulling") return Array.isArray(data.profiles) && data.profiles.every((profile) => object(profile) && typeof profile.type === "string") && object(data.blocks) && Object.values(data.blocks).every((index) => Number.isInteger(index) && index >= 0 && index < data.profiles.length) && (data.groups === void 0 || object(data.groups) && Object.values(data.groups).every((group) => Array.isArray(group) && group.every((type) => typeof type === "string")));
|
|
1675
1681
|
return Object.values(data).every((value) => {
|
|
1676
1682
|
if (!object(value)) return false;
|
|
1677
1683
|
switch (dataset) {
|
|
@@ -7007,16 +7013,21 @@ var init_ModelObject = __esm({
|
|
|
7007
7013
|
const special = this.originalModel.special;
|
|
7008
7014
|
if (special) {
|
|
7009
7015
|
const parts2 = await SpecialItems.getParts(special, this.originalModel.key?.root, this.originalModel.components);
|
|
7010
|
-
const
|
|
7011
|
-
|
|
7016
|
+
const display = new SceneObject();
|
|
7017
|
+
if (this.options.displayPosition) {
|
|
7018
|
+
const transform = DisplayTransforms.getTransform(this.originalModel.display, this.options.displayPosition);
|
|
7019
|
+
display.position.copy(transform.position);
|
|
7020
|
+
display.quaternion.copy(transform.quaternion);
|
|
7021
|
+
display.scale.copy(transform.scale);
|
|
7022
|
+
}
|
|
7023
|
+
this.add(display);
|
|
7024
|
+
const offset = new import_three27.Matrix4().makeTranslation(-8, -8, -8);
|
|
7012
7025
|
try {
|
|
7013
7026
|
const targets = [];
|
|
7014
7027
|
for (const part of parts2) {
|
|
7015
7028
|
const object4 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe, tints: part.tints, faces: part.faces });
|
|
7016
|
-
object4.matrix.
|
|
7017
|
-
object4
|
|
7018
|
-
object4.matrixAutoUpdate = false;
|
|
7019
|
-
this.add(object4);
|
|
7029
|
+
object4.matrix.multiplyMatrices(offset, part.transform).decompose(object4.position, object4.quaternion, object4.scale);
|
|
7030
|
+
display.add(object4);
|
|
7020
7031
|
await object4.init(part.material);
|
|
7021
7032
|
object4.iterateAllMeshes((mesh) => {
|
|
7022
7033
|
const source = mesh.material;
|
|
@@ -17789,6 +17800,38 @@ function sampleSectionLight(light, index) {
|
|
|
17789
17800
|
};
|
|
17790
17801
|
}
|
|
17791
17802
|
|
|
17803
|
+
// src/world/_culling/BlockCulling.ts
|
|
17804
|
+
init_Assets();
|
|
17805
|
+
init_MineRenderData();
|
|
17806
|
+
init_CubeFace();
|
|
17807
|
+
async function loadBlockCulling(root) {
|
|
17808
|
+
const { manifest } = await MineRenderData.resolve(root);
|
|
17809
|
+
return manifest.datasets.blockCulling ? MineRenderData.get("blockCulling", root) : void 0;
|
|
17810
|
+
}
|
|
17811
|
+
function blockCullingRule(data, type) {
|
|
17812
|
+
if (!type.includes(":")) type = `${DEFAULT_NAMESPACE}:${type}`;
|
|
17813
|
+
return Object.prototype.hasOwnProperty.call(data.blocks, type) ? data.profiles[data.blocks[type]] : void 0;
|
|
17814
|
+
}
|
|
17815
|
+
function skipsBlockFace(data, rule, block, neighbor, face) {
|
|
17816
|
+
const type = block.type.includes(":") ? block.type : `${DEFAULT_NAMESPACE}:${block.type}`;
|
|
17817
|
+
const other = neighbor.type.includes(":") ? neighbor.type : `${DEFAULT_NAMESPACE}:${neighbor.type}`;
|
|
17818
|
+
const same = type === other;
|
|
17819
|
+
const vertical = CUBE_FACES[face] === "up" /* UP */ || CUBE_FACES[face] === "down" /* DOWN */;
|
|
17820
|
+
switch (rule.type) {
|
|
17821
|
+
case "same_block":
|
|
17822
|
+
return same;
|
|
17823
|
+
case "same_block_vertical":
|
|
17824
|
+
return same && vertical;
|
|
17825
|
+
case "connected": {
|
|
17826
|
+
if (vertical) return same;
|
|
17827
|
+
const group = rule.group ? data.groups?.[rule.group] : void 0;
|
|
17828
|
+
return (same || !!group?.includes(type) && group.includes(other)) && String(block.properties?.[CUBE_FACES[face]]) === "true" && String(neighbor.properties?.[CUBE_FACES[face ^ 1]]) === "true";
|
|
17829
|
+
}
|
|
17830
|
+
default:
|
|
17831
|
+
return false;
|
|
17832
|
+
}
|
|
17833
|
+
}
|
|
17834
|
+
|
|
17792
17835
|
// src/world/MineRenderWorld.ts
|
|
17793
17836
|
var MineRenderWorld = class {
|
|
17794
17837
|
constructor(scene, options = {}) {
|
|
@@ -18177,15 +18220,23 @@ var MineRenderWorld = class {
|
|
|
18177
18220
|
return this.culling ?? (this.culling = Promise.resolve().then(async () => {
|
|
18178
18221
|
let sliceStart = performance.now();
|
|
18179
18222
|
try {
|
|
18223
|
+
const culling = await loadBlockCulling();
|
|
18180
18224
|
while (this.pendingCulling.size) {
|
|
18181
18225
|
const batch = [...this.pendingCulling];
|
|
18182
18226
|
this.pendingCulling.clear();
|
|
18183
18227
|
for (const [chunk, indices] of batch) {
|
|
18184
18228
|
const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
|
|
18185
|
-
const
|
|
18229
|
+
const neighborAt = (x, y, z) => {
|
|
18186
18230
|
const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
|
|
18187
18231
|
const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
|
|
18188
|
-
return section
|
|
18232
|
+
return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
|
|
18233
|
+
};
|
|
18234
|
+
const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
|
|
18235
|
+
const [section, i] = neighborAt(x, y, z);
|
|
18236
|
+
return section?.isOccludingIndex(i) ?? false;
|
|
18237
|
+
}, culling, (x, y, z) => {
|
|
18238
|
+
const [section, i] = neighborAt(x, y, z);
|
|
18239
|
+
return section?.visibleBlockIndex(i);
|
|
18189
18240
|
});
|
|
18190
18241
|
const fluidIndices = indices === "all" ? function* () {
|
|
18191
18242
|
for (let index = 0; index < 4096; index++) yield index;
|
|
@@ -19300,6 +19351,10 @@ var Chunk = class _Chunk {
|
|
|
19300
19351
|
isBlockVisibleIndex(index) {
|
|
19301
19352
|
return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
|
|
19302
19353
|
}
|
|
19354
|
+
/** Stored state of a rendered, visible cell, or `undefined`. */
|
|
19355
|
+
visibleBlockIndex(index) {
|
|
19356
|
+
return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : void 0;
|
|
19357
|
+
}
|
|
19303
19358
|
/** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
|
|
19304
19359
|
fluidByteIndex(index) {
|
|
19305
19360
|
return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];
|
|
@@ -19318,18 +19373,30 @@ var Chunk = class _Chunk {
|
|
|
19318
19373
|
async setCullMaskAt(pos, mask) {
|
|
19319
19374
|
await this.setCullMaskIndex(_Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);
|
|
19320
19375
|
}
|
|
19321
|
-
/**
|
|
19322
|
-
|
|
19376
|
+
/**
|
|
19377
|
+
* Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
|
|
19378
|
+
* `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
|
|
19379
|
+
*/
|
|
19380
|
+
updateCullMasks(indices, occludes, culling, blockAt) {
|
|
19323
19381
|
const changed = [];
|
|
19382
|
+
const rules = [];
|
|
19324
19383
|
for (const index of indices ?? this.fluidCells.keys()) {
|
|
19325
19384
|
if (!this.isBlockVisibleIndex(index)) continue;
|
|
19326
19385
|
const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;
|
|
19386
|
+
const id = this.data.idAt(index);
|
|
19387
|
+
let rule = rules[id];
|
|
19388
|
+
if (culling && rule === void 0) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id).type) ?? null;
|
|
19389
|
+
const block = rule ? this.data.stateAt(id) : void 0;
|
|
19327
19390
|
let mask = 0;
|
|
19328
19391
|
for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {
|
|
19329
19392
|
const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];
|
|
19330
19393
|
const nx = x + dx, ny = y + dy, nz = z + dz;
|
|
19331
19394
|
const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;
|
|
19332
19395
|
if (inner ? this.isOccludingIndex(ny * 256 + nz * 16 + nx) : occludes(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz)) mask |= 1 << face;
|
|
19396
|
+
else if (rule) {
|
|
19397
|
+
const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx) : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);
|
|
19398
|
+
if (neighbor && skipsBlockFace(culling, rule, block, neighbor, face)) mask |= 1 << face;
|
|
19399
|
+
}
|
|
19333
19400
|
}
|
|
19334
19401
|
if (this.fluidCells[index]) this.meshDirty = true;
|
|
19335
19402
|
const entries = this.sectionBlocks.get(index);
|