minerender 2.1.0-alpha.37 → 2.1.0-alpha.38
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 +21 -2
- package/dist/browser/index.d.ts +21 -2
- package/dist/browser/index.js +275 -111
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +217 -53
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +177 -11
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +21 -2
- package/dist/node/index.d.ts +21 -2
- package/dist/node/index.js +277 -111
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +217 -53
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.mjs
CHANGED
|
@@ -315,6 +315,14 @@ var CubeFaceIndex = /* @__PURE__ */ ((CubeFaceIndex2) => {
|
|
|
315
315
|
return CubeFaceIndex2;
|
|
316
316
|
})(CubeFaceIndex || {});
|
|
317
317
|
var CUBE_FACES = Object.values(CubeFace);
|
|
318
|
+
var CUBE_FACE_OFFSETS = [
|
|
319
|
+
[1, 0, 0],
|
|
320
|
+
[-1, 0, 0],
|
|
321
|
+
[0, 1, 0],
|
|
322
|
+
[0, -1, 0],
|
|
323
|
+
[0, 0, 1],
|
|
324
|
+
[0, 0, -1]
|
|
325
|
+
];
|
|
318
326
|
|
|
319
327
|
// src/Disposable.ts
|
|
320
328
|
function isDisposable(obj) {
|
|
@@ -3803,6 +3811,42 @@ function isQuadArray(obj) {
|
|
|
3803
3811
|
return Array.isArray(obj) && obj.length === 4;
|
|
3804
3812
|
}
|
|
3805
3813
|
|
|
3814
|
+
// src/model/ModelCulling.ts
|
|
3815
|
+
import { Vector3 as Vector36 } from "three";
|
|
3816
|
+
var ModelCulling = class {
|
|
3817
|
+
static toLocalMask(worldMask, rotation) {
|
|
3818
|
+
let localMask = 0;
|
|
3819
|
+
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
3820
|
+
const normal = new Vector36(...offset).applyEuler(rotation);
|
|
3821
|
+
const worldFace = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
|
|
3822
|
+
if (worldFace < 0) return 0;
|
|
3823
|
+
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
3824
|
+
}
|
|
3825
|
+
return localMask;
|
|
3826
|
+
}
|
|
3827
|
+
static isOpaqueFullCube(atlas) {
|
|
3828
|
+
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
3829
|
+
const element = atlas.model.elements[0];
|
|
3830
|
+
if (element.from.length !== 3 || !element.from.every((value) => value === 0) || element.to.length !== 3 || !element.to.every((value) => value === 16) || element.rotation && element.rotation.angle !== 0 || element.mappedUv?.length !== 48 || !element.mappedUv.every(Number.isFinite)) return false;
|
|
3831
|
+
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
3832
|
+
return CUBE_FACES.every((face, faceIndex) => {
|
|
3833
|
+
const texture = element.faces[face]?.texture;
|
|
3834
|
+
if (!texture?.startsWith("#")) return false;
|
|
3835
|
+
const key = texture.slice(1);
|
|
3836
|
+
const position = atlas.positions[key];
|
|
3837
|
+
const size = atlas.sizes[key];
|
|
3838
|
+
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
3839
|
+
for (let vertex = 0; vertex < 4; vertex++) {
|
|
3840
|
+
const uvIndex = (faceIndex * 4 + vertex) * 2;
|
|
3841
|
+
const x = element.mappedUv[uvIndex] * atlas.image.width;
|
|
3842
|
+
const y = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
3843
|
+
if (x < position[0] - 1e-6 || x > position[0] + size[0] + 1e-6 || y < position[1] - 1e-6 || y > position[1] + size[1] + 1e-6) return false;
|
|
3844
|
+
}
|
|
3845
|
+
return true;
|
|
3846
|
+
});
|
|
3847
|
+
}
|
|
3848
|
+
};
|
|
3849
|
+
|
|
3806
3850
|
// src/model/block/blockTints.json
|
|
3807
3851
|
var blockTints_default = {
|
|
3808
3852
|
"minecraft:large_fern": { source: "grass" },
|
|
@@ -3889,7 +3933,7 @@ var BlockTints = class {
|
|
|
3889
3933
|
};
|
|
3890
3934
|
|
|
3891
3935
|
// src/model/scene/ModelObject.ts
|
|
3892
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as
|
|
3936
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler5, Matrix4 as Matrix44 } from "three";
|
|
3893
3937
|
|
|
3894
3938
|
// src/three/BufferGeometryUtils.js
|
|
3895
3939
|
import {
|
|
@@ -3901,7 +3945,7 @@ import {
|
|
|
3901
3945
|
TriangleFanDrawMode,
|
|
3902
3946
|
TriangleStripDrawMode,
|
|
3903
3947
|
TrianglesDrawMode,
|
|
3904
|
-
Vector3 as
|
|
3948
|
+
Vector3 as Vector37
|
|
3905
3949
|
} from "three";
|
|
3906
3950
|
function computeTangents(geometry) {
|
|
3907
3951
|
geometry.computeTangents();
|
|
@@ -4220,15 +4264,15 @@ function computeMorphedAttributes(object) {
|
|
|
4220
4264
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
4221
4265
|
return null;
|
|
4222
4266
|
}
|
|
4223
|
-
const _vA = new
|
|
4224
|
-
const _vB = new
|
|
4225
|
-
const _vC = new
|
|
4226
|
-
const _tempA = new
|
|
4227
|
-
const _tempB = new
|
|
4228
|
-
const _tempC = new
|
|
4229
|
-
const _morphA = new
|
|
4230
|
-
const _morphB = new
|
|
4231
|
-
const _morphC = new
|
|
4267
|
+
const _vA = new Vector37();
|
|
4268
|
+
const _vB = new Vector37();
|
|
4269
|
+
const _vC = new Vector37();
|
|
4270
|
+
const _tempA = new Vector37();
|
|
4271
|
+
const _tempB = new Vector37();
|
|
4272
|
+
const _tempC = new Vector37();
|
|
4273
|
+
const _morphA = new Vector37();
|
|
4274
|
+
const _morphB = new Vector37();
|
|
4275
|
+
const _morphC = new Vector37();
|
|
4232
4276
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
4233
4277
|
_vA.fromBufferAttribute(attribute, a2);
|
|
4234
4278
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4454,6 +4498,9 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4454
4498
|
get textureAtlas() {
|
|
4455
4499
|
return this.atlas;
|
|
4456
4500
|
}
|
|
4501
|
+
get isOpaqueFullCube() {
|
|
4502
|
+
return !this.options.displayPosition && ModelCulling.isOpaqueFullCube(this.atlas);
|
|
4503
|
+
}
|
|
4457
4504
|
//TODO: support for replacing textures
|
|
4458
4505
|
async loadTextures() {
|
|
4459
4506
|
this.atlas = await UVMapper.getAtlas(this.originalModel);
|
|
@@ -4467,8 +4514,17 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4467
4514
|
if (this.atlas.model.elements) {
|
|
4468
4515
|
this.atlas.model.elements?.forEach((el) => {
|
|
4469
4516
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
4517
|
+
if (this.options.cullMask) {
|
|
4518
|
+
const indices = Array.from(elGeo.getIndex().array);
|
|
4519
|
+
elGeo.setIndex(indices.filter((_, index) => {
|
|
4520
|
+
const face = CUBE_FACES[Math.floor(index / 6)];
|
|
4521
|
+
const direction = CUBE_FACES.findIndex((name) => name === el.faces[face]?.cullface);
|
|
4522
|
+
return direction < 0 || !(this.options.cullMask & 1 << direction);
|
|
4523
|
+
}));
|
|
4524
|
+
elGeo.clearGroups();
|
|
4525
|
+
}
|
|
4470
4526
|
if (this.options.uvLockRotation) {
|
|
4471
|
-
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new
|
|
4527
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler5(...this.options.uvLockRotation));
|
|
4472
4528
|
}
|
|
4473
4529
|
if (this.options.tints) {
|
|
4474
4530
|
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
@@ -4566,7 +4622,7 @@ function isModelObject(obj) {
|
|
|
4566
4622
|
|
|
4567
4623
|
// src/model/block/scene/BlockObject.ts
|
|
4568
4624
|
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4569
|
-
import { Euler as
|
|
4625
|
+
import { Euler as Euler6, Matrix4 as Matrix45, Quaternion as Quaternion4, Vector3 as Vector38 } from "three";
|
|
4570
4626
|
var p10 = prefix("BlockObject");
|
|
4571
4627
|
function matchesCondition(condition, state) {
|
|
4572
4628
|
return Object.entries(condition).every(([key, value]) => {
|
|
@@ -4591,6 +4647,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4591
4647
|
this._instanceModel = [];
|
|
4592
4648
|
this._variants = [];
|
|
4593
4649
|
this._models = [];
|
|
4650
|
+
this._cullMask = 0;
|
|
4594
4651
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
4595
4652
|
}
|
|
4596
4653
|
async init() {
|
|
@@ -4624,12 +4681,69 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4624
4681
|
super.removeFromScene();
|
|
4625
4682
|
}
|
|
4626
4683
|
clearModels() {
|
|
4627
|
-
|
|
4684
|
+
this.removeModels(this._models.splice(0));
|
|
4685
|
+
this._isInstanced = false;
|
|
4686
|
+
this._instanceCounter = 0;
|
|
4687
|
+
}
|
|
4688
|
+
removeModels(models) {
|
|
4689
|
+
for (const model of models) {
|
|
4628
4690
|
model.removeFromScene();
|
|
4629
4691
|
if (!isInstanceReference(model)) model.dispose();
|
|
4630
4692
|
}
|
|
4631
|
-
|
|
4632
|
-
|
|
4693
|
+
}
|
|
4694
|
+
get isOccluding() {
|
|
4695
|
+
return this._models.some((model) => {
|
|
4696
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
4697
|
+
return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
|
|
4698
|
+
});
|
|
4699
|
+
}
|
|
4700
|
+
getModelMatrix(model) {
|
|
4701
|
+
if (isInstanceReference(model)) return model.getMatrix();
|
|
4702
|
+
if (model.matrixAutoUpdate) model.updateMatrix();
|
|
4703
|
+
return model.matrix.clone();
|
|
4704
|
+
}
|
|
4705
|
+
getModelCullMask(model, worldMask) {
|
|
4706
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
4707
|
+
if (object.options.displayPosition) return 0;
|
|
4708
|
+
const position = new Vector38();
|
|
4709
|
+
const rotation = new Quaternion4();
|
|
4710
|
+
const scale = new Vector38();
|
|
4711
|
+
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
4712
|
+
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector38(1, 1, 1)) > 1e-10) return 0;
|
|
4713
|
+
return ModelCulling.toLocalMask(worldMask, new Euler6().setFromQuaternion(rotation));
|
|
4714
|
+
}
|
|
4715
|
+
async setCullMask(worldMask) {
|
|
4716
|
+
worldMask &= 63;
|
|
4717
|
+
const replacements = [];
|
|
4718
|
+
try {
|
|
4719
|
+
for (const model of this._models) {
|
|
4720
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
4721
|
+
const cullMask = this.getModelCullMask(model, worldMask);
|
|
4722
|
+
if (cullMask === (object.options.cullMask ?? 0)) {
|
|
4723
|
+
replacements.push(model);
|
|
4724
|
+
continue;
|
|
4725
|
+
}
|
|
4726
|
+
const matrix = this.getModelMatrix(model);
|
|
4727
|
+
const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });
|
|
4728
|
+
replacements.push(replacement);
|
|
4729
|
+
if (isInstanceReference(replacement)) {
|
|
4730
|
+
replacement.setMatrix(matrix);
|
|
4731
|
+
} else {
|
|
4732
|
+
replacement.matrix.copy(matrix);
|
|
4733
|
+
matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
4734
|
+
replacement.matrixAutoUpdate = object.matrixAutoUpdate;
|
|
4735
|
+
replacement.visible = object.visible;
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4738
|
+
} catch (error) {
|
|
4739
|
+
this.removeModels(replacements.filter((model) => !this._models.includes(model)));
|
|
4740
|
+
throw error;
|
|
4741
|
+
}
|
|
4742
|
+
const previous = this._models;
|
|
4743
|
+
this._models = replacements;
|
|
4744
|
+
this._cullMask = worldMask;
|
|
4745
|
+
this.removeModels(previous.filter((model) => !replacements.includes(model)));
|
|
4746
|
+
this.notifyDirty();
|
|
4633
4747
|
}
|
|
4634
4748
|
get state() {
|
|
4635
4749
|
return this._state;
|
|
@@ -4709,7 +4823,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4709
4823
|
await this.createVariant(variant);
|
|
4710
4824
|
}
|
|
4711
4825
|
async createVariant(variant) {
|
|
4712
|
-
const rotation = new
|
|
4826
|
+
const rotation = new Euler6();
|
|
4713
4827
|
if (typeof variant.x !== "undefined") {
|
|
4714
4828
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4715
4829
|
}
|
|
@@ -4722,7 +4836,8 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4722
4836
|
const options = {
|
|
4723
4837
|
...this.options,
|
|
4724
4838
|
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
4725
|
-
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
4839
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0,
|
|
4840
|
+
cullMask: this.options.displayPosition ? 0 : ModelCulling.toLocalMask(this._cullMask, rotation)
|
|
4726
4841
|
};
|
|
4727
4842
|
const obj = await this.scene.addModel(model, options);
|
|
4728
4843
|
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
@@ -5984,11 +6099,12 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
|
|
|
5984
6099
|
console.log("instanceMeshes + key");
|
|
5985
6100
|
let key = asset.key.serialize();
|
|
5986
6101
|
if (isModelObject(obj)) {
|
|
5987
|
-
const { displayPosition, uvLockRotation, tints } = obj.options;
|
|
6102
|
+
const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
|
|
5988
6103
|
if (displayPosition) key += `|display:${displayPosition}`;
|
|
5989
6104
|
if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
|
|
5990
6105
|
const palette = Object.entries(tints ?? {}).sort(([a], [b]) => Number(a) - Number(b));
|
|
5991
6106
|
if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
|
|
6107
|
+
if (cullMask) key += `|cull:${cullMask}`;
|
|
5992
6108
|
}
|
|
5993
6109
|
return this.instanceManager.getOrCreate(key, async () => {
|
|
5994
6110
|
obj.scene = this;
|
|
@@ -6034,7 +6150,7 @@ function isMineRenderScene(obj) {
|
|
|
6034
6150
|
}
|
|
6035
6151
|
|
|
6036
6152
|
// src/renderer/Renderer.ts
|
|
6037
|
-
import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace4, Vector3 as
|
|
6153
|
+
import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace4, Vector3 as Vector310, WebGLRenderer } from "three";
|
|
6038
6154
|
var import_ts_deepmerge9 = __toESM(require_dist());
|
|
6039
6155
|
import Stats from "stats.js";
|
|
6040
6156
|
import { EffectComposer, RenderPass } from "postprocessing";
|
|
@@ -6043,11 +6159,11 @@ import { EffectComposer, RenderPass } from "postprocessing";
|
|
|
6043
6159
|
import {
|
|
6044
6160
|
EventDispatcher,
|
|
6045
6161
|
MOUSE,
|
|
6046
|
-
Quaternion as
|
|
6162
|
+
Quaternion as Quaternion5,
|
|
6047
6163
|
Spherical,
|
|
6048
6164
|
TOUCH,
|
|
6049
6165
|
Vector2 as Vector23,
|
|
6050
|
-
Vector3 as
|
|
6166
|
+
Vector3 as Vector39
|
|
6051
6167
|
} from "three";
|
|
6052
6168
|
var _changeEvent = { type: "change" };
|
|
6053
6169
|
var _startEvent = { type: "start" };
|
|
@@ -6061,7 +6177,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6061
6177
|
this.domElement = domElement;
|
|
6062
6178
|
this.domElement.style.touchAction = "none";
|
|
6063
6179
|
this.enabled = true;
|
|
6064
|
-
this.target = new
|
|
6180
|
+
this.target = new Vector39();
|
|
6065
6181
|
this.minDistance = 0;
|
|
6066
6182
|
this.maxDistance = Infinity;
|
|
6067
6183
|
this.minZoom = 0;
|
|
@@ -6113,11 +6229,11 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6113
6229
|
state = STATE.NONE;
|
|
6114
6230
|
};
|
|
6115
6231
|
this.update = function() {
|
|
6116
|
-
const offset = new
|
|
6117
|
-
const quat = new
|
|
6232
|
+
const offset = new Vector39();
|
|
6233
|
+
const quat = new Quaternion5().setFromUnitVectors(object.up, new Vector39(0, 1, 0));
|
|
6118
6234
|
const quatInverse = quat.clone().invert();
|
|
6119
|
-
const lastPosition = new
|
|
6120
|
-
const lastQuaternion = new
|
|
6235
|
+
const lastPosition = new Vector39();
|
|
6236
|
+
const lastQuaternion = new Quaternion5();
|
|
6121
6237
|
const twoPI = 2 * Math.PI;
|
|
6122
6238
|
return function update() {
|
|
6123
6239
|
const position = scope.object.position;
|
|
@@ -6206,7 +6322,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6206
6322
|
const spherical = new Spherical();
|
|
6207
6323
|
const sphericalDelta = new Spherical();
|
|
6208
6324
|
let scale = 1;
|
|
6209
|
-
const panOffset = new
|
|
6325
|
+
const panOffset = new Vector39();
|
|
6210
6326
|
let zoomChanged = false;
|
|
6211
6327
|
const rotateStart = new Vector23();
|
|
6212
6328
|
const rotateEnd = new Vector23();
|
|
@@ -6232,7 +6348,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6232
6348
|
sphericalDelta.phi -= angle;
|
|
6233
6349
|
}
|
|
6234
6350
|
const panLeft = function() {
|
|
6235
|
-
const v = new
|
|
6351
|
+
const v = new Vector39();
|
|
6236
6352
|
return function panLeft2(distance, objectMatrix) {
|
|
6237
6353
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
6238
6354
|
v.multiplyScalar(-distance);
|
|
@@ -6240,7 +6356,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6240
6356
|
};
|
|
6241
6357
|
}();
|
|
6242
6358
|
const panUp = function() {
|
|
6243
|
-
const v = new
|
|
6359
|
+
const v = new Vector39();
|
|
6244
6360
|
return function panUp2(distance, objectMatrix) {
|
|
6245
6361
|
if (scope.screenSpacePanning === true) {
|
|
6246
6362
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -6253,7 +6369,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6253
6369
|
};
|
|
6254
6370
|
}();
|
|
6255
6371
|
const pan = function() {
|
|
6256
|
-
const offset = new
|
|
6372
|
+
const offset = new Vector39();
|
|
6257
6373
|
return function pan2(deltaX, deltaY) {
|
|
6258
6374
|
const element = scope.domElement;
|
|
6259
6375
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -7000,8 +7116,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
|
|
|
7000
7116
|
top: void 0,
|
|
7001
7117
|
bottom: void 0
|
|
7002
7118
|
},
|
|
7003
|
-
position: new
|
|
7004
|
-
lookingAt: new
|
|
7119
|
+
position: new Vector310(50, 50, 50),
|
|
7120
|
+
lookingAt: new Vector310(0, 0, 0)
|
|
7005
7121
|
},
|
|
7006
7122
|
render: {
|
|
7007
7123
|
fpsLimit: 60,
|
|
@@ -7189,7 +7305,7 @@ var Skins = class {
|
|
|
7189
7305
|
};
|
|
7190
7306
|
|
|
7191
7307
|
// src/world/Chunk.ts
|
|
7192
|
-
import { Vector3 as
|
|
7308
|
+
import { Vector3 as Vector312 } from "three";
|
|
7193
7309
|
|
|
7194
7310
|
// src/world/ChunkData.ts
|
|
7195
7311
|
var ChunkData = class _ChunkData {
|
|
@@ -7273,28 +7389,29 @@ var ChunkData = class _ChunkData {
|
|
|
7273
7389
|
};
|
|
7274
7390
|
|
|
7275
7391
|
// src/world/MineRenderWorld.ts
|
|
7276
|
-
import { Vector3 as
|
|
7392
|
+
import { Vector3 as Vector311 } from "three";
|
|
7277
7393
|
var MineRenderWorld = class {
|
|
7278
7394
|
constructor(scene) {
|
|
7279
7395
|
this._chunks = /* @__PURE__ */ new Map();
|
|
7396
|
+
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
7280
7397
|
this.scene = scene;
|
|
7281
7398
|
}
|
|
7282
7399
|
getBlockAt(posOrX, y, z) {
|
|
7283
7400
|
if (typeof posOrX == "number") {
|
|
7284
|
-
return this.getBlockAt(new
|
|
7401
|
+
return this.getBlockAt(new Vector311(posOrX, y, z));
|
|
7285
7402
|
}
|
|
7286
7403
|
if (isTripleArray(posOrX)) {
|
|
7287
|
-
return this.getBlockAt(new
|
|
7404
|
+
return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
|
|
7288
7405
|
}
|
|
7289
7406
|
this.validatePosBounds(posOrX);
|
|
7290
7407
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
7291
7408
|
}
|
|
7292
7409
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7293
7410
|
if (typeof posOrX == "number") {
|
|
7294
|
-
return this.setBlockAt(new
|
|
7411
|
+
return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
|
|
7295
7412
|
}
|
|
7296
7413
|
if (isTripleArray(posOrX)) {
|
|
7297
|
-
return this.setBlockAt(new
|
|
7414
|
+
return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7298
7415
|
}
|
|
7299
7416
|
this.validatePosBounds(posOrX);
|
|
7300
7417
|
const value = yOrBlock;
|
|
@@ -7337,16 +7454,54 @@ var MineRenderWorld = class {
|
|
|
7337
7454
|
}
|
|
7338
7455
|
}
|
|
7339
7456
|
async clear() {
|
|
7340
|
-
|
|
7457
|
+
await this.culling;
|
|
7458
|
+
const chunks = [...this._chunks.values()];
|
|
7459
|
+
this._chunks.clear();
|
|
7460
|
+
for (const chunk of chunks) {
|
|
7341
7461
|
await chunk.dispose();
|
|
7342
7462
|
}
|
|
7343
|
-
|
|
7463
|
+
}
|
|
7464
|
+
updateCulling(positions) {
|
|
7465
|
+
for (const pos of positions) {
|
|
7466
|
+
this.pendingCulling.set(pos.toArray().join(","), pos.clone());
|
|
7467
|
+
for (const offset of CUBE_FACE_OFFSETS) {
|
|
7468
|
+
const neighbor = pos.clone().add(new Vector311(...offset));
|
|
7469
|
+
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
7470
|
+
}
|
|
7471
|
+
}
|
|
7472
|
+
return this.culling ?? (this.culling = Promise.resolve().then(async () => {
|
|
7473
|
+
try {
|
|
7474
|
+
while (this.pendingCulling.size) {
|
|
7475
|
+
const batch = [...this.pendingCulling.values()];
|
|
7476
|
+
this.pendingCulling.clear();
|
|
7477
|
+
for (const pos of batch) {
|
|
7478
|
+
const block = this.getBlockAt(pos)?.object;
|
|
7479
|
+
if (!block) continue;
|
|
7480
|
+
let mask = 0;
|
|
7481
|
+
for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
7482
|
+
if (this.getBlockAt(pos.clone().add(new Vector311(...offset)))?.object.isOccluding) {
|
|
7483
|
+
mask |= 1 << face;
|
|
7484
|
+
}
|
|
7485
|
+
}
|
|
7486
|
+
await block.setCullMask(mask);
|
|
7487
|
+
}
|
|
7488
|
+
}
|
|
7489
|
+
} finally {
|
|
7490
|
+
this.culling = void 0;
|
|
7491
|
+
}
|
|
7492
|
+
}));
|
|
7344
7493
|
}
|
|
7345
7494
|
getOrCreateChunkAt(pos) {
|
|
7346
7495
|
const key = this.worldPosToChunkKey(pos);
|
|
7347
7496
|
let chunk = this._chunks.get(key);
|
|
7348
7497
|
if (typeof chunk === "undefined") {
|
|
7349
|
-
chunk = new Chunk(
|
|
7498
|
+
chunk = new Chunk(
|
|
7499
|
+
this.scene,
|
|
7500
|
+
Math.floor(pos.x / 16),
|
|
7501
|
+
Math.floor(pos.y / 16),
|
|
7502
|
+
Math.floor(pos.z / 16),
|
|
7503
|
+
(positions) => this.updateCulling(positions)
|
|
7504
|
+
);
|
|
7350
7505
|
this._chunks.set(key, chunk);
|
|
7351
7506
|
}
|
|
7352
7507
|
return chunk;
|
|
@@ -7355,14 +7510,14 @@ var MineRenderWorld = class {
|
|
|
7355
7510
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
7356
7511
|
}
|
|
7357
7512
|
static worldToScenePosition(pos) {
|
|
7358
|
-
return new
|
|
7513
|
+
return new Vector311(
|
|
7359
7514
|
pos.x * 16,
|
|
7360
7515
|
pos.y * 16,
|
|
7361
7516
|
pos.z * 16
|
|
7362
7517
|
);
|
|
7363
7518
|
}
|
|
7364
7519
|
static sceneToWorldPosition(pos) {
|
|
7365
|
-
return new
|
|
7520
|
+
return new Vector311(
|
|
7366
7521
|
pos.x / 16,
|
|
7367
7522
|
pos.y / 16,
|
|
7368
7523
|
pos.z / 16
|
|
@@ -7383,7 +7538,8 @@ var MineRenderWorld = class {
|
|
|
7383
7538
|
|
|
7384
7539
|
// src/world/Chunk.ts
|
|
7385
7540
|
var Chunk = class _Chunk {
|
|
7386
|
-
constructor(scene, x, y, z) {
|
|
7541
|
+
constructor(scene, x, y, z, onBlocksChanged) {
|
|
7542
|
+
this.onBlocksChanged = onBlocksChanged;
|
|
7387
7543
|
this.data = new ChunkData();
|
|
7388
7544
|
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
7389
7545
|
this.scene = scene;
|
|
@@ -7393,10 +7549,10 @@ var Chunk = class _Chunk {
|
|
|
7393
7549
|
}
|
|
7394
7550
|
getBlockAt(posOrX, y, z) {
|
|
7395
7551
|
if (typeof posOrX == "number") {
|
|
7396
|
-
return this.getBlockAt(new
|
|
7552
|
+
return this.getBlockAt(new Vector312(posOrX, y, z));
|
|
7397
7553
|
}
|
|
7398
7554
|
if (isTripleArray(posOrX)) {
|
|
7399
|
-
return this.getBlockAt(new
|
|
7555
|
+
return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
|
|
7400
7556
|
}
|
|
7401
7557
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
7402
7558
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -7404,10 +7560,10 @@ var Chunk = class _Chunk {
|
|
|
7404
7560
|
}
|
|
7405
7561
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7406
7562
|
if (typeof posOrX == "number") {
|
|
7407
|
-
return this.setBlockAt(new
|
|
7563
|
+
return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
|
|
7408
7564
|
}
|
|
7409
7565
|
if (isTripleArray(posOrX)) {
|
|
7410
|
-
return this.setBlockAt(new
|
|
7566
|
+
return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7411
7567
|
}
|
|
7412
7568
|
const worldPos = posOrX;
|
|
7413
7569
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -7426,10 +7582,10 @@ var Chunk = class _Chunk {
|
|
|
7426
7582
|
const readBlock = this.data.snapshot(index);
|
|
7427
7583
|
this.renderedBlocks.get(index)?.object.removeFromScene();
|
|
7428
7584
|
this.renderedBlocks.delete(index);
|
|
7429
|
-
if (!readBlock) return void 0;
|
|
7430
|
-
const stored = readBlock();
|
|
7431
7585
|
let object;
|
|
7432
7586
|
try {
|
|
7587
|
+
if (!readBlock) return void 0;
|
|
7588
|
+
const stored = readBlock();
|
|
7433
7589
|
const blockState = await BlockStates.get(AssetKey.parse("blockstates", stored.type));
|
|
7434
7590
|
if (!blockState) {
|
|
7435
7591
|
this.data.set(index, void 0);
|
|
@@ -7451,12 +7607,18 @@ var Chunk = class _Chunk {
|
|
|
7451
7607
|
this.data.set(index, void 0);
|
|
7452
7608
|
object?.removeFromScene();
|
|
7453
7609
|
throw error;
|
|
7610
|
+
} finally {
|
|
7611
|
+
await this.onBlocksChanged?.([worldPos]);
|
|
7454
7612
|
}
|
|
7455
7613
|
}
|
|
7456
7614
|
async clear() {
|
|
7615
|
+
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
7616
|
+
new Vector312(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
7617
|
+
));
|
|
7457
7618
|
for (const info of this.renderedBlocks.values()) info.object.removeFromScene();
|
|
7458
7619
|
this.renderedBlocks.clear();
|
|
7459
7620
|
this.data.clear();
|
|
7621
|
+
await this.onBlocksChanged?.(positions);
|
|
7460
7622
|
}
|
|
7461
7623
|
async dispose() {
|
|
7462
7624
|
await this.clear();
|
|
@@ -7471,14 +7633,14 @@ var Chunk = class _Chunk {
|
|
|
7471
7633
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
7472
7634
|
}
|
|
7473
7635
|
worldPosToChunkPos(pos) {
|
|
7474
|
-
return new
|
|
7636
|
+
return new Vector312(
|
|
7475
7637
|
pos.x - this.x * 16,
|
|
7476
7638
|
pos.y - this.y * 16,
|
|
7477
7639
|
pos.z - this.z * 16
|
|
7478
7640
|
);
|
|
7479
7641
|
}
|
|
7480
7642
|
chunkPosToWorldPos(pos) {
|
|
7481
|
-
return new
|
|
7643
|
+
return new Vector312(
|
|
7482
7644
|
this.x * 16 + pos.x,
|
|
7483
7645
|
this.y * 16 + pos.y,
|
|
7484
7646
|
this.z * 16 + pos.z
|
|
@@ -7506,6 +7668,7 @@ export {
|
|
|
7506
7668
|
BrowserCache,
|
|
7507
7669
|
BrowserEnv,
|
|
7508
7670
|
CUBE_FACES,
|
|
7671
|
+
CUBE_FACE_OFFSETS,
|
|
7509
7672
|
Caching,
|
|
7510
7673
|
CanvasImage,
|
|
7511
7674
|
Chunk,
|
|
@@ -7539,6 +7702,7 @@ export {
|
|
|
7539
7702
|
MineRenderWorld,
|
|
7540
7703
|
MinecraftCubeTexture,
|
|
7541
7704
|
MinecraftFaceUV,
|
|
7705
|
+
ModelCulling,
|
|
7542
7706
|
ModelGenerator,
|
|
7543
7707
|
ModelMerger,
|
|
7544
7708
|
ModelObject,
|