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/node/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';
|
|
@@ -1312,6 +1312,15 @@ interface MineRenderDatasets {
|
|
|
1312
1312
|
untinted?: number[];
|
|
1313
1313
|
biome?: BiomeColorKind;
|
|
1314
1314
|
}>;
|
|
1315
|
+
blockCulling: {
|
|
1316
|
+
profiles: {
|
|
1317
|
+
type: string;
|
|
1318
|
+
group?: string;
|
|
1319
|
+
kind?: string;
|
|
1320
|
+
}[];
|
|
1321
|
+
blocks: Record<string, number>;
|
|
1322
|
+
groups?: Record<string, string[]>;
|
|
1323
|
+
};
|
|
1315
1324
|
fluids: Record<string, {
|
|
1316
1325
|
kind: "water" | "lava";
|
|
1317
1326
|
renderModel: boolean;
|
|
@@ -1424,6 +1433,12 @@ declare class DisplayTransforms {
|
|
|
1424
1433
|
static withHandFallbacks(display: Model["display"]): Model["display"];
|
|
1425
1434
|
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1426
1435
|
static getMatrix(display: Model["display"], position: DisplayPosition): Matrix4;
|
|
1436
|
+
/** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1437
|
+
static getTransform(display: Model["display"], position: DisplayPosition): {
|
|
1438
|
+
position: Vector3;
|
|
1439
|
+
quaternion: Quaternion;
|
|
1440
|
+
scale: Vector3;
|
|
1441
|
+
};
|
|
1427
1442
|
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1428
1443
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1429
1444
|
}
|
|
@@ -3891,6 +3906,8 @@ interface WorldBlockIntersection {
|
|
|
3891
3906
|
distance: number;
|
|
3892
3907
|
}
|
|
3893
3908
|
|
|
3909
|
+
type BlockCullingData = MineRenderDatasets["blockCulling"];
|
|
3910
|
+
|
|
3894
3911
|
/**
|
|
3895
3912
|
* A 16×16×16 block section and its render objects.
|
|
3896
3913
|
* Constructor coordinates identify the section. Block accessors use world block coordinates
|
|
@@ -3967,6 +3984,8 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3967
3984
|
isBlockVisibleAt(pos: Vector3): boolean;
|
|
3968
3985
|
/** Reports whether a cell has a visible render object or section entry. */
|
|
3969
3986
|
isBlockVisibleIndex(index: number): boolean;
|
|
3987
|
+
/** Stored state of a rendered, visible cell, or `undefined`. */
|
|
3988
|
+
visibleBlockIndex(index: number): Maybe<Pick<Block, "type" | "properties">>;
|
|
3970
3989
|
/** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
|
|
3971
3990
|
fluidByteIndex(index: number): number;
|
|
3972
3991
|
/** Whether the cell holds a fluid, merged or per-block. */
|
|
@@ -3975,8 +3994,11 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3975
3994
|
/** Reports whether a visible cell hides neighboring cube faces. */
|
|
3976
3995
|
isOccludingIndex(index: number): boolean;
|
|
3977
3996
|
setCullMaskAt(pos: Vector3, mask: number): Promise<void>;
|
|
3978
|
-
/**
|
|
3979
|
-
|
|
3997
|
+
/**
|
|
3998
|
+
* Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
|
|
3999
|
+
* `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
|
|
4000
|
+
*/
|
|
4001
|
+
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][];
|
|
3980
4002
|
/** Updates hidden faces for a cell's section entry or individual render object. */
|
|
3981
4003
|
setCullMaskIndex(index: number, mask: number): Promise<void>;
|
|
3982
4004
|
/** Rebuilds visible section geometry and discards results superseded by another rebuild or clear. */
|
package/dist/node/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';
|
|
@@ -1312,6 +1312,15 @@ interface MineRenderDatasets {
|
|
|
1312
1312
|
untinted?: number[];
|
|
1313
1313
|
biome?: BiomeColorKind;
|
|
1314
1314
|
}>;
|
|
1315
|
+
blockCulling: {
|
|
1316
|
+
profiles: {
|
|
1317
|
+
type: string;
|
|
1318
|
+
group?: string;
|
|
1319
|
+
kind?: string;
|
|
1320
|
+
}[];
|
|
1321
|
+
blocks: Record<string, number>;
|
|
1322
|
+
groups?: Record<string, string[]>;
|
|
1323
|
+
};
|
|
1315
1324
|
fluids: Record<string, {
|
|
1316
1325
|
kind: "water" | "lava";
|
|
1317
1326
|
renderModel: boolean;
|
|
@@ -1424,6 +1433,12 @@ declare class DisplayTransforms {
|
|
|
1424
1433
|
static withHandFallbacks(display: Model["display"]): Model["display"];
|
|
1425
1434
|
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1426
1435
|
static getMatrix(display: Model["display"], position: DisplayPosition): Matrix4;
|
|
1436
|
+
/** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1437
|
+
static getTransform(display: Model["display"], position: DisplayPosition): {
|
|
1438
|
+
position: Vector3;
|
|
1439
|
+
quaternion: Quaternion;
|
|
1440
|
+
scale: Vector3;
|
|
1441
|
+
};
|
|
1427
1442
|
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1428
1443
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1429
1444
|
}
|
|
@@ -3891,6 +3906,8 @@ interface WorldBlockIntersection {
|
|
|
3891
3906
|
distance: number;
|
|
3892
3907
|
}
|
|
3893
3908
|
|
|
3909
|
+
type BlockCullingData = MineRenderDatasets["blockCulling"];
|
|
3910
|
+
|
|
3894
3911
|
/**
|
|
3895
3912
|
* A 16×16×16 block section and its render objects.
|
|
3896
3913
|
* Constructor coordinates identify the section. Block accessors use world block coordinates
|
|
@@ -3967,6 +3984,8 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3967
3984
|
isBlockVisibleAt(pos: Vector3): boolean;
|
|
3968
3985
|
/** Reports whether a cell has a visible render object or section entry. */
|
|
3969
3986
|
isBlockVisibleIndex(index: number): boolean;
|
|
3987
|
+
/** Stored state of a rendered, visible cell, or `undefined`. */
|
|
3988
|
+
visibleBlockIndex(index: number): Maybe<Pick<Block, "type" | "properties">>;
|
|
3970
3989
|
/** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
|
|
3971
3990
|
fluidByteIndex(index: number): number;
|
|
3972
3991
|
/** Whether the cell holds a fluid, merged or per-block. */
|
|
@@ -3975,8 +3994,11 @@ declare class Chunk<SectionMeshing extends boolean = false> {
|
|
|
3975
3994
|
/** Reports whether a visible cell hides neighboring cube faces. */
|
|
3976
3995
|
isOccludingIndex(index: number): boolean;
|
|
3977
3996
|
setCullMaskAt(pos: Vector3, mask: number): Promise<void>;
|
|
3978
|
-
/**
|
|
3979
|
-
|
|
3997
|
+
/**
|
|
3998
|
+
* Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
|
|
3999
|
+
* `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
|
|
4000
|
+
*/
|
|
4001
|
+
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][];
|
|
3980
4002
|
/** Updates hidden faces for a cell's section entry or individual render object. */
|
|
3981
4003
|
setCullMaskIndex(index: number, mask: number): Promise<void>;
|
|
3982
4004
|
/** Rebuilds visible section geometry and discards results superseded by another rebuild or clear. */
|
package/dist/node/index.js
CHANGED
|
@@ -1535,6 +1535,11 @@ var init_DisplayTransforms = __esm({
|
|
|
1535
1535
|
}
|
|
1536
1536
|
/** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1537
1537
|
static getMatrix(display, position) {
|
|
1538
|
+
const transform = this.getTransform(display, position);
|
|
1539
|
+
return new import_three7.Matrix4().compose(transform.position, transform.quaternion, transform.scale);
|
|
1540
|
+
}
|
|
1541
|
+
/** Position, rotation, and scale of a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
|
|
1542
|
+
static getTransform(display, position) {
|
|
1538
1543
|
const transform = this.withHandFallbacks(display)?.[position] ?? {};
|
|
1539
1544
|
const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
|
|
1540
1545
|
const sign = left ? -1 : 1;
|
|
@@ -1543,7 +1548,7 @@ var init_DisplayTransforms = __esm({
|
|
|
1543
1548
|
const translation = new import_three7.Vector3(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
|
|
1544
1549
|
translation.x *= sign;
|
|
1545
1550
|
const scale = new import_three7.Vector3(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
|
|
1546
|
-
return
|
|
1551
|
+
return { position: translation, quaternion: rotation, scale };
|
|
1547
1552
|
}
|
|
1548
1553
|
/** Transforms geometry in place and reverses triangle winding when the matrix reflects it. */
|
|
1549
1554
|
static apply(geometry, matrix) {
|
|
@@ -1728,6 +1733,7 @@ ${key}` : key, async () => {
|
|
|
1728
1733
|
if (!object(data)) return false;
|
|
1729
1734
|
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)));
|
|
1730
1735
|
if (dataset === "legacyBlocks") return object(data.blocks) && Object.values(data.blocks).every((value) => typeof value === "string");
|
|
1736
|
+
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")));
|
|
1731
1737
|
return Object.values(data).every((value) => {
|
|
1732
1738
|
if (!object(value)) return false;
|
|
1733
1739
|
switch (dataset) {
|
|
@@ -7109,16 +7115,21 @@ var init_ModelObject = __esm({
|
|
|
7109
7115
|
const special = this.originalModel.special;
|
|
7110
7116
|
if (special) {
|
|
7111
7117
|
const parts2 = await SpecialItems.getParts(special, this.originalModel.key?.root, this.originalModel.components);
|
|
7112
|
-
const
|
|
7113
|
-
|
|
7118
|
+
const display = new SceneObject();
|
|
7119
|
+
if (this.options.displayPosition) {
|
|
7120
|
+
const transform = DisplayTransforms.getTransform(this.originalModel.display, this.options.displayPosition);
|
|
7121
|
+
display.position.copy(transform.position);
|
|
7122
|
+
display.quaternion.copy(transform.quaternion);
|
|
7123
|
+
display.scale.copy(transform.scale);
|
|
7124
|
+
}
|
|
7125
|
+
this.add(display);
|
|
7126
|
+
const offset = new import_three27.Matrix4().makeTranslation(-8, -8, -8);
|
|
7114
7127
|
try {
|
|
7115
7128
|
const targets = [];
|
|
7116
7129
|
for (const part of parts2) {
|
|
7117
7130
|
const object4 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe, tints: part.tints, faces: part.faces });
|
|
7118
|
-
object4.matrix.
|
|
7119
|
-
object4
|
|
7120
|
-
object4.matrixAutoUpdate = false;
|
|
7121
|
-
this.add(object4);
|
|
7131
|
+
object4.matrix.multiplyMatrices(offset, part.transform).decompose(object4.position, object4.quaternion, object4.scale);
|
|
7132
|
+
display.add(object4);
|
|
7122
7133
|
await object4.init(part.material);
|
|
7123
7134
|
object4.iterateAllMeshes((mesh) => {
|
|
7124
7135
|
const source = mesh.material;
|
|
@@ -17824,6 +17835,38 @@ function sampleSectionLight(light, index) {
|
|
|
17824
17835
|
};
|
|
17825
17836
|
}
|
|
17826
17837
|
|
|
17838
|
+
// src/world/_culling/BlockCulling.ts
|
|
17839
|
+
init_Assets();
|
|
17840
|
+
init_MineRenderData();
|
|
17841
|
+
init_CubeFace();
|
|
17842
|
+
async function loadBlockCulling(root) {
|
|
17843
|
+
const { manifest } = await MineRenderData.resolve(root);
|
|
17844
|
+
return manifest.datasets.blockCulling ? MineRenderData.get("blockCulling", root) : void 0;
|
|
17845
|
+
}
|
|
17846
|
+
function blockCullingRule(data, type) {
|
|
17847
|
+
if (!type.includes(":")) type = `${DEFAULT_NAMESPACE}:${type}`;
|
|
17848
|
+
return Object.prototype.hasOwnProperty.call(data.blocks, type) ? data.profiles[data.blocks[type]] : void 0;
|
|
17849
|
+
}
|
|
17850
|
+
function skipsBlockFace(data, rule, block, neighbor, face) {
|
|
17851
|
+
const type = block.type.includes(":") ? block.type : `${DEFAULT_NAMESPACE}:${block.type}`;
|
|
17852
|
+
const other = neighbor.type.includes(":") ? neighbor.type : `${DEFAULT_NAMESPACE}:${neighbor.type}`;
|
|
17853
|
+
const same = type === other;
|
|
17854
|
+
const vertical = CUBE_FACES[face] === "up" /* UP */ || CUBE_FACES[face] === "down" /* DOWN */;
|
|
17855
|
+
switch (rule.type) {
|
|
17856
|
+
case "same_block":
|
|
17857
|
+
return same;
|
|
17858
|
+
case "same_block_vertical":
|
|
17859
|
+
return same && vertical;
|
|
17860
|
+
case "connected": {
|
|
17861
|
+
if (vertical) return same;
|
|
17862
|
+
const group = rule.group ? data.groups?.[rule.group] : void 0;
|
|
17863
|
+
return (same || !!group?.includes(type) && group.includes(other)) && String(block.properties?.[CUBE_FACES[face]]) === "true" && String(neighbor.properties?.[CUBE_FACES[face ^ 1]]) === "true";
|
|
17864
|
+
}
|
|
17865
|
+
default:
|
|
17866
|
+
return false;
|
|
17867
|
+
}
|
|
17868
|
+
}
|
|
17869
|
+
|
|
17827
17870
|
// src/world/MineRenderWorld.ts
|
|
17828
17871
|
var MineRenderWorld = class {
|
|
17829
17872
|
constructor(scene, options = {}) {
|
|
@@ -18212,15 +18255,23 @@ var MineRenderWorld = class {
|
|
|
18212
18255
|
return this.culling ??= Promise.resolve().then(async () => {
|
|
18213
18256
|
let sliceStart = performance.now();
|
|
18214
18257
|
try {
|
|
18258
|
+
const culling = await loadBlockCulling();
|
|
18215
18259
|
while (this.pendingCulling.size) {
|
|
18216
18260
|
const batch = [...this.pendingCulling];
|
|
18217
18261
|
this.pendingCulling.clear();
|
|
18218
18262
|
for (const [chunk, indices] of batch) {
|
|
18219
18263
|
const neighbors = CUBE_FACE_OFFSETS.map(([x, y, z]) => this._chunks.get(`${chunk.x + x}_${chunk.y + y}_${chunk.z + z}`));
|
|
18220
|
-
const
|
|
18264
|
+
const neighborAt = (x, y, z) => {
|
|
18221
18265
|
const lx = x - chunk.x * 16, ly = y - chunk.y * 16, lz = z - chunk.z * 16;
|
|
18222
18266
|
const section = neighbors[lx >= 16 ? 0 : lx < 0 ? 1 : ly >= 16 ? 2 : ly < 0 ? 3 : lz >= 16 ? 4 : 5];
|
|
18223
|
-
return section
|
|
18267
|
+
return [section, (ly & 15) * 256 + (lz & 15) * 16 + (lx & 15)];
|
|
18268
|
+
};
|
|
18269
|
+
const masks = chunk.updateCullMasks(indices === "all" ? void 0 : indices, (x, y, z) => {
|
|
18270
|
+
const [section, i] = neighborAt(x, y, z);
|
|
18271
|
+
return section?.isOccludingIndex(i) ?? false;
|
|
18272
|
+
}, culling, (x, y, z) => {
|
|
18273
|
+
const [section, i] = neighborAt(x, y, z);
|
|
18274
|
+
return section?.visibleBlockIndex(i);
|
|
18224
18275
|
});
|
|
18225
18276
|
const fluidIndices = indices === "all" ? function* () {
|
|
18226
18277
|
for (let index = 0; index < 4096; index++) yield index;
|
|
@@ -19336,6 +19387,10 @@ var Chunk = class _Chunk {
|
|
|
19336
19387
|
isBlockVisibleIndex(index) {
|
|
19337
19388
|
return this.renderedBlocks.has(index) && !this.hiddenBlocks.has(index);
|
|
19338
19389
|
}
|
|
19390
|
+
/** Stored state of a rendered, visible cell, or `undefined`. */
|
|
19391
|
+
visibleBlockIndex(index) {
|
|
19392
|
+
return this.isBlockVisibleIndex(index) ? this.data.stateAt(this.data.idAt(index)) : void 0;
|
|
19393
|
+
}
|
|
19339
19394
|
/** Fluid kind bits and level of a cell, or 0. Hidden cells report 0. */
|
|
19340
19395
|
fluidByteIndex(index) {
|
|
19341
19396
|
return this.hiddenBlocks.has(index) ? 0 : this.fluidCells[index];
|
|
@@ -19354,18 +19409,30 @@ var Chunk = class _Chunk {
|
|
|
19354
19409
|
async setCullMaskAt(pos, mask) {
|
|
19355
19410
|
await this.setCullMaskIndex(_Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos)), mask);
|
|
19356
19411
|
}
|
|
19357
|
-
/**
|
|
19358
|
-
|
|
19412
|
+
/**
|
|
19413
|
+
* Recomputes section masks and returns changed per-block masks. Omit indices to visit every cell.
|
|
19414
|
+
* `culling` supplies neighbor face rules; `blockAt` supplies visible states outside this chunk.
|
|
19415
|
+
*/
|
|
19416
|
+
updateCullMasks(indices, occludes, culling, blockAt) {
|
|
19359
19417
|
const changed = [];
|
|
19418
|
+
const rules = [];
|
|
19360
19419
|
for (const index of indices ?? this.fluidCells.keys()) {
|
|
19361
19420
|
if (!this.isBlockVisibleIndex(index)) continue;
|
|
19362
19421
|
const x = index % 16, y = Math.floor(index / 256), z = Math.floor(index / 16) % 16;
|
|
19422
|
+
const id = this.data.idAt(index);
|
|
19423
|
+
let rule = rules[id];
|
|
19424
|
+
if (culling && rule === void 0) rules[id] = rule = blockCullingRule(culling, this.data.stateAt(id).type) ?? null;
|
|
19425
|
+
const block = rule ? this.data.stateAt(id) : void 0;
|
|
19363
19426
|
let mask = 0;
|
|
19364
19427
|
for (let face = 0; face < CUBE_FACE_OFFSETS.length; face++) {
|
|
19365
19428
|
const [dx, dy, dz] = CUBE_FACE_OFFSETS[face];
|
|
19366
19429
|
const nx = x + dx, ny = y + dy, nz = z + dz;
|
|
19367
19430
|
const inner = nx >= 0 && nx < 16 && ny >= 0 && ny < 16 && nz >= 0 && nz < 16;
|
|
19368
19431
|
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;
|
|
19432
|
+
else if (rule) {
|
|
19433
|
+
const neighbor = inner ? this.visibleBlockIndex(ny * 256 + nz * 16 + nx) : blockAt?.(this.x * 16 + nx, this.y * 16 + ny, this.z * 16 + nz);
|
|
19434
|
+
if (neighbor && skipsBlockFace(culling, rule, block, neighbor, face)) mask |= 1 << face;
|
|
19435
|
+
}
|
|
19369
19436
|
}
|
|
19370
19437
|
if (this.fluidCells[index]) this.meshDirty = true;
|
|
19371
19438
|
const entries = this.sectionBlocks.get(index);
|