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/node/index.mjs
CHANGED
|
@@ -278,6 +278,14 @@ var CubeFaceIndex = /* @__PURE__ */ ((CubeFaceIndex2) => {
|
|
|
278
278
|
return CubeFaceIndex2;
|
|
279
279
|
})(CubeFaceIndex || {});
|
|
280
280
|
var CUBE_FACES = Object.values(CubeFace);
|
|
281
|
+
var CUBE_FACE_OFFSETS = [
|
|
282
|
+
[1, 0, 0],
|
|
283
|
+
[-1, 0, 0],
|
|
284
|
+
[0, 1, 0],
|
|
285
|
+
[0, -1, 0],
|
|
286
|
+
[0, 0, 1],
|
|
287
|
+
[0, 0, -1]
|
|
288
|
+
];
|
|
281
289
|
|
|
282
290
|
// src/Disposable.ts
|
|
283
291
|
function isDisposable(obj) {
|
|
@@ -3849,6 +3857,42 @@ function isQuadArray(obj) {
|
|
|
3849
3857
|
return Array.isArray(obj) && obj.length === 4;
|
|
3850
3858
|
}
|
|
3851
3859
|
|
|
3860
|
+
// src/model/ModelCulling.ts
|
|
3861
|
+
import { Vector3 as Vector36 } from "three";
|
|
3862
|
+
var ModelCulling = class {
|
|
3863
|
+
static toLocalMask(worldMask, rotation) {
|
|
3864
|
+
let localMask = 0;
|
|
3865
|
+
for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
3866
|
+
const normal = new Vector36(...offset).applyEuler(rotation);
|
|
3867
|
+
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);
|
|
3868
|
+
if (worldFace < 0) return 0;
|
|
3869
|
+
if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
|
|
3870
|
+
}
|
|
3871
|
+
return localMask;
|
|
3872
|
+
}
|
|
3873
|
+
static isOpaqueFullCube(atlas) {
|
|
3874
|
+
if (!atlas || atlas.hasTransparency !== false || atlas.model.elements?.length !== 1) return false;
|
|
3875
|
+
const element = atlas.model.elements[0];
|
|
3876
|
+
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;
|
|
3877
|
+
if (!(atlas.image.width > 0 && atlas.image.height > 0)) return false;
|
|
3878
|
+
return CUBE_FACES.every((face, faceIndex) => {
|
|
3879
|
+
const texture = element.faces[face]?.texture;
|
|
3880
|
+
if (!texture?.startsWith("#")) return false;
|
|
3881
|
+
const key = texture.slice(1);
|
|
3882
|
+
const position = atlas.positions[key];
|
|
3883
|
+
const size = atlas.sizes[key];
|
|
3884
|
+
if (position?.length !== 2 || !position.every(Number.isFinite) || size?.length !== 2 || !size.every((value) => value > 0 && Number.isFinite(value))) return false;
|
|
3885
|
+
for (let vertex = 0; vertex < 4; vertex++) {
|
|
3886
|
+
const uvIndex = (faceIndex * 4 + vertex) * 2;
|
|
3887
|
+
const x = element.mappedUv[uvIndex] * atlas.image.width;
|
|
3888
|
+
const y = (1 - element.mappedUv[uvIndex + 1]) * atlas.image.height;
|
|
3889
|
+
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;
|
|
3890
|
+
}
|
|
3891
|
+
return true;
|
|
3892
|
+
});
|
|
3893
|
+
}
|
|
3894
|
+
};
|
|
3895
|
+
|
|
3852
3896
|
// src/model/block/blockTints.json
|
|
3853
3897
|
var blockTints_default = {
|
|
3854
3898
|
"minecraft:large_fern": { source: "grass" },
|
|
@@ -3935,7 +3979,7 @@ var BlockTints = class {
|
|
|
3935
3979
|
};
|
|
3936
3980
|
|
|
3937
3981
|
// src/model/scene/ModelObject.ts
|
|
3938
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as
|
|
3982
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler5, Matrix4 as Matrix44 } from "three";
|
|
3939
3983
|
|
|
3940
3984
|
// src/three/BufferGeometryUtils.js
|
|
3941
3985
|
import {
|
|
@@ -3947,7 +3991,7 @@ import {
|
|
|
3947
3991
|
TriangleFanDrawMode,
|
|
3948
3992
|
TriangleStripDrawMode,
|
|
3949
3993
|
TrianglesDrawMode,
|
|
3950
|
-
Vector3 as
|
|
3994
|
+
Vector3 as Vector37
|
|
3951
3995
|
} from "three";
|
|
3952
3996
|
function computeTangents(geometry) {
|
|
3953
3997
|
geometry.computeTangents();
|
|
@@ -4266,15 +4310,15 @@ function computeMorphedAttributes(object) {
|
|
|
4266
4310
|
console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
|
|
4267
4311
|
return null;
|
|
4268
4312
|
}
|
|
4269
|
-
const _vA = new
|
|
4270
|
-
const _vB = new
|
|
4271
|
-
const _vC = new
|
|
4272
|
-
const _tempA = new
|
|
4273
|
-
const _tempB = new
|
|
4274
|
-
const _tempC = new
|
|
4275
|
-
const _morphA = new
|
|
4276
|
-
const _morphB = new
|
|
4277
|
-
const _morphC = new
|
|
4313
|
+
const _vA = new Vector37();
|
|
4314
|
+
const _vB = new Vector37();
|
|
4315
|
+
const _vC = new Vector37();
|
|
4316
|
+
const _tempA = new Vector37();
|
|
4317
|
+
const _tempB = new Vector37();
|
|
4318
|
+
const _tempC = new Vector37();
|
|
4319
|
+
const _morphA = new Vector37();
|
|
4320
|
+
const _morphB = new Vector37();
|
|
4321
|
+
const _morphC = new Vector37();
|
|
4278
4322
|
function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
|
|
4279
4323
|
_vA.fromBufferAttribute(attribute, a2);
|
|
4280
4324
|
_vB.fromBufferAttribute(attribute, b2);
|
|
@@ -4503,6 +4547,9 @@ var ModelObject = class _ModelObject extends SceneObject {
|
|
|
4503
4547
|
get textureAtlas() {
|
|
4504
4548
|
return this.atlas;
|
|
4505
4549
|
}
|
|
4550
|
+
get isOpaqueFullCube() {
|
|
4551
|
+
return !this.options.displayPosition && ModelCulling.isOpaqueFullCube(this.atlas);
|
|
4552
|
+
}
|
|
4506
4553
|
//TODO: support for replacing textures
|
|
4507
4554
|
async loadTextures() {
|
|
4508
4555
|
this.atlas = await UVMapper.getAtlas(this.originalModel);
|
|
@@ -4516,8 +4563,17 @@ var ModelObject = class _ModelObject extends SceneObject {
|
|
|
4516
4563
|
if (this.atlas.model.elements) {
|
|
4517
4564
|
this.atlas.model.elements?.forEach((el) => {
|
|
4518
4565
|
const elGeo = this._getBoxGeometryFromElement(el).clone();
|
|
4566
|
+
if (this.options.cullMask) {
|
|
4567
|
+
const indices = Array.from(elGeo.getIndex().array);
|
|
4568
|
+
elGeo.setIndex(indices.filter((_, index) => {
|
|
4569
|
+
const face = CUBE_FACES[Math.floor(index / 6)];
|
|
4570
|
+
const direction = CUBE_FACES.findIndex((name) => name === el.faces[face]?.cullface);
|
|
4571
|
+
return direction < 0 || !(this.options.cullMask & 1 << direction);
|
|
4572
|
+
}));
|
|
4573
|
+
elGeo.clearGroups();
|
|
4574
|
+
}
|
|
4519
4575
|
if (this.options.uvLockRotation) {
|
|
4520
|
-
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new
|
|
4576
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler5(...this.options.uvLockRotation));
|
|
4521
4577
|
}
|
|
4522
4578
|
if (this.options.tints) {
|
|
4523
4579
|
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
@@ -4613,7 +4669,7 @@ function isModelObject(obj) {
|
|
|
4613
4669
|
|
|
4614
4670
|
// src/model/block/scene/BlockObject.ts
|
|
4615
4671
|
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4616
|
-
import { Euler as
|
|
4672
|
+
import { Euler as Euler6, Matrix4 as Matrix45, Quaternion as Quaternion4, Vector3 as Vector38 } from "three";
|
|
4617
4673
|
var p10 = prefix("BlockObject");
|
|
4618
4674
|
function matchesCondition(condition, state) {
|
|
4619
4675
|
return Object.entries(condition).every(([key, value]) => {
|
|
@@ -4638,6 +4694,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4638
4694
|
this._instanceModel = [];
|
|
4639
4695
|
this._variants = [];
|
|
4640
4696
|
this._models = [];
|
|
4697
|
+
this._cullMask = 0;
|
|
4641
4698
|
this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
|
|
4642
4699
|
}
|
|
4643
4700
|
static {
|
|
@@ -4676,12 +4733,69 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4676
4733
|
super.removeFromScene();
|
|
4677
4734
|
}
|
|
4678
4735
|
clearModels() {
|
|
4679
|
-
|
|
4736
|
+
this.removeModels(this._models.splice(0));
|
|
4737
|
+
this._isInstanced = false;
|
|
4738
|
+
this._instanceCounter = 0;
|
|
4739
|
+
}
|
|
4740
|
+
removeModels(models) {
|
|
4741
|
+
for (const model of models) {
|
|
4680
4742
|
model.removeFromScene();
|
|
4681
4743
|
if (!isInstanceReference(model)) model.dispose();
|
|
4682
4744
|
}
|
|
4683
|
-
|
|
4684
|
-
|
|
4745
|
+
}
|
|
4746
|
+
get isOccluding() {
|
|
4747
|
+
return this._models.some((model) => {
|
|
4748
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
4749
|
+
return object.isOpaqueFullCube && this.getModelCullMask(model, 63) === 63;
|
|
4750
|
+
});
|
|
4751
|
+
}
|
|
4752
|
+
getModelMatrix(model) {
|
|
4753
|
+
if (isInstanceReference(model)) return model.getMatrix();
|
|
4754
|
+
if (model.matrixAutoUpdate) model.updateMatrix();
|
|
4755
|
+
return model.matrix.clone();
|
|
4756
|
+
}
|
|
4757
|
+
getModelCullMask(model, worldMask) {
|
|
4758
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
4759
|
+
if (object.options.displayPosition) return 0;
|
|
4760
|
+
const position = new Vector38();
|
|
4761
|
+
const rotation = new Quaternion4();
|
|
4762
|
+
const scale = new Vector38();
|
|
4763
|
+
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
4764
|
+
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector38(1, 1, 1)) > 1e-10) return 0;
|
|
4765
|
+
return ModelCulling.toLocalMask(worldMask, new Euler6().setFromQuaternion(rotation));
|
|
4766
|
+
}
|
|
4767
|
+
async setCullMask(worldMask) {
|
|
4768
|
+
worldMask &= 63;
|
|
4769
|
+
const replacements = [];
|
|
4770
|
+
try {
|
|
4771
|
+
for (const model of this._models) {
|
|
4772
|
+
const object = isInstanceReference(model) ? model.instanceable : model;
|
|
4773
|
+
const cullMask = this.getModelCullMask(model, worldMask);
|
|
4774
|
+
if (cullMask === (object.options.cullMask ?? 0)) {
|
|
4775
|
+
replacements.push(model);
|
|
4776
|
+
continue;
|
|
4777
|
+
}
|
|
4778
|
+
const matrix = this.getModelMatrix(model);
|
|
4779
|
+
const replacement = await this.scene.addModel(object.originalModel, { ...object.options, cullMask });
|
|
4780
|
+
replacements.push(replacement);
|
|
4781
|
+
if (isInstanceReference(replacement)) {
|
|
4782
|
+
replacement.setMatrix(matrix);
|
|
4783
|
+
} else {
|
|
4784
|
+
replacement.matrix.copy(matrix);
|
|
4785
|
+
matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
|
|
4786
|
+
replacement.matrixAutoUpdate = object.matrixAutoUpdate;
|
|
4787
|
+
replacement.visible = object.visible;
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
} catch (error) {
|
|
4791
|
+
this.removeModels(replacements.filter((model) => !this._models.includes(model)));
|
|
4792
|
+
throw error;
|
|
4793
|
+
}
|
|
4794
|
+
const previous = this._models;
|
|
4795
|
+
this._models = replacements;
|
|
4796
|
+
this._cullMask = worldMask;
|
|
4797
|
+
this.removeModels(previous.filter((model) => !replacements.includes(model)));
|
|
4798
|
+
this.notifyDirty();
|
|
4685
4799
|
}
|
|
4686
4800
|
get state() {
|
|
4687
4801
|
return this._state;
|
|
@@ -4761,7 +4875,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4761
4875
|
await this.createVariant(variant);
|
|
4762
4876
|
}
|
|
4763
4877
|
async createVariant(variant) {
|
|
4764
|
-
const rotation = new
|
|
4878
|
+
const rotation = new Euler6();
|
|
4765
4879
|
if (typeof variant.x !== "undefined") {
|
|
4766
4880
|
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4767
4881
|
}
|
|
@@ -4774,7 +4888,8 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4774
4888
|
const options = {
|
|
4775
4889
|
...this.options,
|
|
4776
4890
|
tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
|
|
4777
|
-
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
4891
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0,
|
|
4892
|
+
cullMask: this.options.displayPosition ? 0 : ModelCulling.toLocalMask(this._cullMask, rotation)
|
|
4778
4893
|
};
|
|
4779
4894
|
const obj = await this.scene.addModel(model, options);
|
|
4780
4895
|
if (isInstanceReference(obj) || obj.isInstanced) {
|
|
@@ -6035,11 +6150,12 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
|
|
|
6035
6150
|
console.log("instanceMeshes + key");
|
|
6036
6151
|
let key = asset.key.serialize();
|
|
6037
6152
|
if (isModelObject(obj)) {
|
|
6038
|
-
const { displayPosition, uvLockRotation, tints } = obj.options;
|
|
6153
|
+
const { displayPosition, uvLockRotation, tints, cullMask } = obj.options;
|
|
6039
6154
|
if (displayPosition) key += `|display:${displayPosition}`;
|
|
6040
6155
|
if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
|
|
6041
6156
|
const palette = Object.entries(tints ?? {}).sort(([a], [b]) => Number(a) - Number(b));
|
|
6042
6157
|
if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
|
|
6158
|
+
if (cullMask) key += `|cull:${cullMask}`;
|
|
6043
6159
|
}
|
|
6044
6160
|
return this.instanceManager.getOrCreate(key, async () => {
|
|
6045
6161
|
obj.scene = this;
|
|
@@ -6083,7 +6199,7 @@ function isMineRenderScene(obj) {
|
|
|
6083
6199
|
}
|
|
6084
6200
|
|
|
6085
6201
|
// src/renderer/Renderer.ts
|
|
6086
|
-
import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace4, Vector3 as
|
|
6202
|
+
import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace4, Vector3 as Vector310, WebGLRenderer } from "three";
|
|
6087
6203
|
var import_ts_deepmerge9 = __toESM(require_dist());
|
|
6088
6204
|
import Stats from "stats.js";
|
|
6089
6205
|
import { EffectComposer, RenderPass } from "postprocessing";
|
|
@@ -6092,11 +6208,11 @@ import { EffectComposer, RenderPass } from "postprocessing";
|
|
|
6092
6208
|
import {
|
|
6093
6209
|
EventDispatcher,
|
|
6094
6210
|
MOUSE,
|
|
6095
|
-
Quaternion as
|
|
6211
|
+
Quaternion as Quaternion5,
|
|
6096
6212
|
Spherical,
|
|
6097
6213
|
TOUCH,
|
|
6098
6214
|
Vector2 as Vector23,
|
|
6099
|
-
Vector3 as
|
|
6215
|
+
Vector3 as Vector39
|
|
6100
6216
|
} from "three";
|
|
6101
6217
|
var _changeEvent = { type: "change" };
|
|
6102
6218
|
var _startEvent = { type: "start" };
|
|
@@ -6110,7 +6226,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6110
6226
|
this.domElement = domElement;
|
|
6111
6227
|
this.domElement.style.touchAction = "none";
|
|
6112
6228
|
this.enabled = true;
|
|
6113
|
-
this.target = new
|
|
6229
|
+
this.target = new Vector39();
|
|
6114
6230
|
this.minDistance = 0;
|
|
6115
6231
|
this.maxDistance = Infinity;
|
|
6116
6232
|
this.minZoom = 0;
|
|
@@ -6162,11 +6278,11 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6162
6278
|
state = STATE.NONE;
|
|
6163
6279
|
};
|
|
6164
6280
|
this.update = function() {
|
|
6165
|
-
const offset = new
|
|
6166
|
-
const quat = new
|
|
6281
|
+
const offset = new Vector39();
|
|
6282
|
+
const quat = new Quaternion5().setFromUnitVectors(object.up, new Vector39(0, 1, 0));
|
|
6167
6283
|
const quatInverse = quat.clone().invert();
|
|
6168
|
-
const lastPosition = new
|
|
6169
|
-
const lastQuaternion = new
|
|
6284
|
+
const lastPosition = new Vector39();
|
|
6285
|
+
const lastQuaternion = new Quaternion5();
|
|
6170
6286
|
const twoPI = 2 * Math.PI;
|
|
6171
6287
|
return function update() {
|
|
6172
6288
|
const position = scope.object.position;
|
|
@@ -6255,7 +6371,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6255
6371
|
const spherical = new Spherical();
|
|
6256
6372
|
const sphericalDelta = new Spherical();
|
|
6257
6373
|
let scale = 1;
|
|
6258
|
-
const panOffset = new
|
|
6374
|
+
const panOffset = new Vector39();
|
|
6259
6375
|
let zoomChanged = false;
|
|
6260
6376
|
const rotateStart = new Vector23();
|
|
6261
6377
|
const rotateEnd = new Vector23();
|
|
@@ -6281,7 +6397,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6281
6397
|
sphericalDelta.phi -= angle;
|
|
6282
6398
|
}
|
|
6283
6399
|
const panLeft = function() {
|
|
6284
|
-
const v = new
|
|
6400
|
+
const v = new Vector39();
|
|
6285
6401
|
return function panLeft2(distance, objectMatrix) {
|
|
6286
6402
|
v.setFromMatrixColumn(objectMatrix, 0);
|
|
6287
6403
|
v.multiplyScalar(-distance);
|
|
@@ -6289,7 +6405,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6289
6405
|
};
|
|
6290
6406
|
}();
|
|
6291
6407
|
const panUp = function() {
|
|
6292
|
-
const v = new
|
|
6408
|
+
const v = new Vector39();
|
|
6293
6409
|
return function panUp2(distance, objectMatrix) {
|
|
6294
6410
|
if (scope.screenSpacePanning === true) {
|
|
6295
6411
|
v.setFromMatrixColumn(objectMatrix, 1);
|
|
@@ -6302,7 +6418,7 @@ var OrbitControls = class extends EventDispatcher {
|
|
|
6302
6418
|
};
|
|
6303
6419
|
}();
|
|
6304
6420
|
const pan = function() {
|
|
6305
|
-
const offset = new
|
|
6421
|
+
const offset = new Vector39();
|
|
6306
6422
|
return function pan2(deltaX, deltaY) {
|
|
6307
6423
|
const element = scope.domElement;
|
|
6308
6424
|
if (scope.object.isPerspectiveCamera) {
|
|
@@ -6779,8 +6895,8 @@ var Renderer = class _Renderer {
|
|
|
6779
6895
|
top: void 0,
|
|
6780
6896
|
bottom: void 0
|
|
6781
6897
|
},
|
|
6782
|
-
position: new
|
|
6783
|
-
lookingAt: new
|
|
6898
|
+
position: new Vector310(50, 50, 50),
|
|
6899
|
+
lookingAt: new Vector310(0, 0, 0)
|
|
6784
6900
|
},
|
|
6785
6901
|
render: {
|
|
6786
6902
|
fpsLimit: 60,
|
|
@@ -7239,7 +7355,7 @@ var Skins = class {
|
|
|
7239
7355
|
};
|
|
7240
7356
|
|
|
7241
7357
|
// src/world/Chunk.ts
|
|
7242
|
-
import { Vector3 as
|
|
7358
|
+
import { Vector3 as Vector312 } from "three";
|
|
7243
7359
|
|
|
7244
7360
|
// src/world/ChunkData.ts
|
|
7245
7361
|
var ChunkData = class _ChunkData {
|
|
@@ -7323,28 +7439,29 @@ var ChunkData = class _ChunkData {
|
|
|
7323
7439
|
};
|
|
7324
7440
|
|
|
7325
7441
|
// src/world/MineRenderWorld.ts
|
|
7326
|
-
import { Vector3 as
|
|
7442
|
+
import { Vector3 as Vector311 } from "three";
|
|
7327
7443
|
var MineRenderWorld = class {
|
|
7328
7444
|
constructor(scene) {
|
|
7329
7445
|
this._chunks = /* @__PURE__ */ new Map();
|
|
7446
|
+
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
7330
7447
|
this.scene = scene;
|
|
7331
7448
|
}
|
|
7332
7449
|
getBlockAt(posOrX, y, z) {
|
|
7333
7450
|
if (typeof posOrX == "number") {
|
|
7334
|
-
return this.getBlockAt(new
|
|
7451
|
+
return this.getBlockAt(new Vector311(posOrX, y, z));
|
|
7335
7452
|
}
|
|
7336
7453
|
if (isTripleArray(posOrX)) {
|
|
7337
|
-
return this.getBlockAt(new
|
|
7454
|
+
return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
|
|
7338
7455
|
}
|
|
7339
7456
|
this.validatePosBounds(posOrX);
|
|
7340
7457
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
7341
7458
|
}
|
|
7342
7459
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7343
7460
|
if (typeof posOrX == "number") {
|
|
7344
|
-
return this.setBlockAt(new
|
|
7461
|
+
return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
|
|
7345
7462
|
}
|
|
7346
7463
|
if (isTripleArray(posOrX)) {
|
|
7347
|
-
return this.setBlockAt(new
|
|
7464
|
+
return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7348
7465
|
}
|
|
7349
7466
|
this.validatePosBounds(posOrX);
|
|
7350
7467
|
const value = yOrBlock;
|
|
@@ -7387,16 +7504,54 @@ var MineRenderWorld = class {
|
|
|
7387
7504
|
}
|
|
7388
7505
|
}
|
|
7389
7506
|
async clear() {
|
|
7390
|
-
|
|
7507
|
+
await this.culling;
|
|
7508
|
+
const chunks = [...this._chunks.values()];
|
|
7509
|
+
this._chunks.clear();
|
|
7510
|
+
for (const chunk of chunks) {
|
|
7391
7511
|
await chunk.dispose();
|
|
7392
7512
|
}
|
|
7393
|
-
|
|
7513
|
+
}
|
|
7514
|
+
updateCulling(positions) {
|
|
7515
|
+
for (const pos of positions) {
|
|
7516
|
+
this.pendingCulling.set(pos.toArray().join(","), pos.clone());
|
|
7517
|
+
for (const offset of CUBE_FACE_OFFSETS) {
|
|
7518
|
+
const neighbor = pos.clone().add(new Vector311(...offset));
|
|
7519
|
+
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
7520
|
+
}
|
|
7521
|
+
}
|
|
7522
|
+
return this.culling ??= Promise.resolve().then(async () => {
|
|
7523
|
+
try {
|
|
7524
|
+
while (this.pendingCulling.size) {
|
|
7525
|
+
const batch = [...this.pendingCulling.values()];
|
|
7526
|
+
this.pendingCulling.clear();
|
|
7527
|
+
for (const pos of batch) {
|
|
7528
|
+
const block = this.getBlockAt(pos)?.object;
|
|
7529
|
+
if (!block) continue;
|
|
7530
|
+
let mask = 0;
|
|
7531
|
+
for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
7532
|
+
if (this.getBlockAt(pos.clone().add(new Vector311(...offset)))?.object.isOccluding) {
|
|
7533
|
+
mask |= 1 << face;
|
|
7534
|
+
}
|
|
7535
|
+
}
|
|
7536
|
+
await block.setCullMask(mask);
|
|
7537
|
+
}
|
|
7538
|
+
}
|
|
7539
|
+
} finally {
|
|
7540
|
+
this.culling = void 0;
|
|
7541
|
+
}
|
|
7542
|
+
});
|
|
7394
7543
|
}
|
|
7395
7544
|
getOrCreateChunkAt(pos) {
|
|
7396
7545
|
const key = this.worldPosToChunkKey(pos);
|
|
7397
7546
|
let chunk = this._chunks.get(key);
|
|
7398
7547
|
if (typeof chunk === "undefined") {
|
|
7399
|
-
chunk = new Chunk(
|
|
7548
|
+
chunk = new Chunk(
|
|
7549
|
+
this.scene,
|
|
7550
|
+
Math.floor(pos.x / 16),
|
|
7551
|
+
Math.floor(pos.y / 16),
|
|
7552
|
+
Math.floor(pos.z / 16),
|
|
7553
|
+
(positions) => this.updateCulling(positions)
|
|
7554
|
+
);
|
|
7400
7555
|
this._chunks.set(key, chunk);
|
|
7401
7556
|
}
|
|
7402
7557
|
return chunk;
|
|
@@ -7405,14 +7560,14 @@ var MineRenderWorld = class {
|
|
|
7405
7560
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
7406
7561
|
}
|
|
7407
7562
|
static worldToScenePosition(pos) {
|
|
7408
|
-
return new
|
|
7563
|
+
return new Vector311(
|
|
7409
7564
|
pos.x * 16,
|
|
7410
7565
|
pos.y * 16,
|
|
7411
7566
|
pos.z * 16
|
|
7412
7567
|
);
|
|
7413
7568
|
}
|
|
7414
7569
|
static sceneToWorldPosition(pos) {
|
|
7415
|
-
return new
|
|
7570
|
+
return new Vector311(
|
|
7416
7571
|
pos.x / 16,
|
|
7417
7572
|
pos.y / 16,
|
|
7418
7573
|
pos.z / 16
|
|
@@ -7433,7 +7588,8 @@ var MineRenderWorld = class {
|
|
|
7433
7588
|
|
|
7434
7589
|
// src/world/Chunk.ts
|
|
7435
7590
|
var Chunk = class _Chunk {
|
|
7436
|
-
constructor(scene, x, y, z) {
|
|
7591
|
+
constructor(scene, x, y, z, onBlocksChanged) {
|
|
7592
|
+
this.onBlocksChanged = onBlocksChanged;
|
|
7437
7593
|
this.data = new ChunkData();
|
|
7438
7594
|
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
7439
7595
|
this.scene = scene;
|
|
@@ -7443,10 +7599,10 @@ var Chunk = class _Chunk {
|
|
|
7443
7599
|
}
|
|
7444
7600
|
getBlockAt(posOrX, y, z) {
|
|
7445
7601
|
if (typeof posOrX == "number") {
|
|
7446
|
-
return this.getBlockAt(new
|
|
7602
|
+
return this.getBlockAt(new Vector312(posOrX, y, z));
|
|
7447
7603
|
}
|
|
7448
7604
|
if (isTripleArray(posOrX)) {
|
|
7449
|
-
return this.getBlockAt(new
|
|
7605
|
+
return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
|
|
7450
7606
|
}
|
|
7451
7607
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
7452
7608
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -7454,10 +7610,10 @@ var Chunk = class _Chunk {
|
|
|
7454
7610
|
}
|
|
7455
7611
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7456
7612
|
if (typeof posOrX == "number") {
|
|
7457
|
-
return this.setBlockAt(new
|
|
7613
|
+
return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
|
|
7458
7614
|
}
|
|
7459
7615
|
if (isTripleArray(posOrX)) {
|
|
7460
|
-
return this.setBlockAt(new
|
|
7616
|
+
return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7461
7617
|
}
|
|
7462
7618
|
const worldPos = posOrX;
|
|
7463
7619
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -7476,10 +7632,10 @@ var Chunk = class _Chunk {
|
|
|
7476
7632
|
const readBlock = this.data.snapshot(index);
|
|
7477
7633
|
this.renderedBlocks.get(index)?.object.removeFromScene();
|
|
7478
7634
|
this.renderedBlocks.delete(index);
|
|
7479
|
-
if (!readBlock) return void 0;
|
|
7480
|
-
const stored = readBlock();
|
|
7481
7635
|
let object;
|
|
7482
7636
|
try {
|
|
7637
|
+
if (!readBlock) return void 0;
|
|
7638
|
+
const stored = readBlock();
|
|
7483
7639
|
const blockState = await BlockStates.get(AssetKey.parse("blockstates", stored.type));
|
|
7484
7640
|
if (!blockState) {
|
|
7485
7641
|
this.data.set(index, void 0);
|
|
@@ -7501,12 +7657,18 @@ var Chunk = class _Chunk {
|
|
|
7501
7657
|
this.data.set(index, void 0);
|
|
7502
7658
|
object?.removeFromScene();
|
|
7503
7659
|
throw error;
|
|
7660
|
+
} finally {
|
|
7661
|
+
await this.onBlocksChanged?.([worldPos]);
|
|
7504
7662
|
}
|
|
7505
7663
|
}
|
|
7506
7664
|
async clear() {
|
|
7665
|
+
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
7666
|
+
new Vector312(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
7667
|
+
));
|
|
7507
7668
|
for (const info of this.renderedBlocks.values()) info.object.removeFromScene();
|
|
7508
7669
|
this.renderedBlocks.clear();
|
|
7509
7670
|
this.data.clear();
|
|
7671
|
+
await this.onBlocksChanged?.(positions);
|
|
7510
7672
|
}
|
|
7511
7673
|
async dispose() {
|
|
7512
7674
|
await this.clear();
|
|
@@ -7521,14 +7683,14 @@ var Chunk = class _Chunk {
|
|
|
7521
7683
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
7522
7684
|
}
|
|
7523
7685
|
worldPosToChunkPos(pos) {
|
|
7524
|
-
return new
|
|
7686
|
+
return new Vector312(
|
|
7525
7687
|
pos.x - this.x * 16,
|
|
7526
7688
|
pos.y - this.y * 16,
|
|
7527
7689
|
pos.z - this.z * 16
|
|
7528
7690
|
);
|
|
7529
7691
|
}
|
|
7530
7692
|
chunkPosToWorldPos(pos) {
|
|
7531
|
-
return new
|
|
7693
|
+
return new Vector312(
|
|
7532
7694
|
this.x * 16 + pos.x,
|
|
7533
7695
|
this.y * 16 + pos.y,
|
|
7534
7696
|
this.z * 16 + pos.z
|
|
@@ -7554,6 +7716,7 @@ export {
|
|
|
7554
7716
|
BlockTints,
|
|
7555
7717
|
BrowserArchiveProxy,
|
|
7556
7718
|
CUBE_FACES,
|
|
7719
|
+
CUBE_FACE_OFFSETS,
|
|
7557
7720
|
Caching,
|
|
7558
7721
|
CanvasImage,
|
|
7559
7722
|
Chunk,
|
|
@@ -7587,6 +7750,7 @@ export {
|
|
|
7587
7750
|
MineRenderWorld,
|
|
7588
7751
|
MinecraftCubeTexture,
|
|
7589
7752
|
MinecraftFaceUV,
|
|
7753
|
+
ModelCulling,
|
|
7590
7754
|
ModelGenerator,
|
|
7591
7755
|
ModelMerger,
|
|
7592
7756
|
ModelObject,
|