minerender 2.1.0-alpha.36 → 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 +40 -4
- package/dist/browser/index.d.ts +40 -4
- package/dist/browser/index.js +394 -145
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +336 -87
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +737 -483
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +40 -4
- package/dist/node/index.d.ts +40 -4
- package/dist/node/index.js +397 -145
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +336 -87
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.mjs
CHANGED
|
@@ -32,8 +32,8 @@ var require_dist = __commonJS({
|
|
|
32
32
|
__assign = Object.assign || function(t) {
|
|
33
33
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
34
34
|
s = arguments[i];
|
|
35
|
-
for (var
|
|
36
|
-
t[
|
|
35
|
+
for (var p11 in s) if (Object.prototype.hasOwnProperty.call(s, p11))
|
|
36
|
+
t[p11] = s[p11];
|
|
37
37
|
}
|
|
38
38
|
return t;
|
|
39
39
|
};
|
|
@@ -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) {
|
|
@@ -1172,12 +1180,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1172
1180
|
return a.join("/");
|
|
1173
1181
|
}
|
|
1174
1182
|
getFullPath() {
|
|
1175
|
-
let
|
|
1183
|
+
let p11 = [];
|
|
1176
1184
|
if (this.type) {
|
|
1177
|
-
|
|
1185
|
+
p11.push(this.type);
|
|
1178
1186
|
}
|
|
1179
|
-
|
|
1180
|
-
return
|
|
1187
|
+
p11.push(this.path);
|
|
1188
|
+
return p11.join("/");
|
|
1181
1189
|
}
|
|
1182
1190
|
toNamespacedString() {
|
|
1183
1191
|
return this.namespace + ":" + this.getFullPath();
|
|
@@ -1264,7 +1272,7 @@ var ModelMerger = class {
|
|
|
1264
1272
|
merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
|
|
1265
1273
|
}
|
|
1266
1274
|
}
|
|
1267
|
-
merged.hierarchy = models.map((m) => m.parent).filter((
|
|
1275
|
+
merged.hierarchy = models.map((m) => m.parent).filter((p11) => `${p11}`);
|
|
1268
1276
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1269
1277
|
return merged;
|
|
1270
1278
|
}
|
|
@@ -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,31 +7355,113 @@ var Skins = class {
|
|
|
7239
7355
|
};
|
|
7240
7356
|
|
|
7241
7357
|
// src/world/Chunk.ts
|
|
7242
|
-
import { Vector3 as
|
|
7358
|
+
import { Vector3 as Vector312 } from "three";
|
|
7359
|
+
|
|
7360
|
+
// src/world/ChunkData.ts
|
|
7361
|
+
var ChunkData = class _ChunkData {
|
|
7362
|
+
constructor() {
|
|
7363
|
+
this.indices = new Uint16Array(4096);
|
|
7364
|
+
this.palette = [void 0];
|
|
7365
|
+
this.paletteIds = /* @__PURE__ */ new Map();
|
|
7366
|
+
this.freeIds = [];
|
|
7367
|
+
this.nbt = /* @__PURE__ */ new Map();
|
|
7368
|
+
}
|
|
7369
|
+
get(index) {
|
|
7370
|
+
_ChunkData.validateIndex(index);
|
|
7371
|
+
const entry = this.palette[this.indices[index]];
|
|
7372
|
+
return entry ? _ChunkData.copyBlock(entry.state, this.nbt.get(index)) : void 0;
|
|
7373
|
+
}
|
|
7374
|
+
snapshot(index) {
|
|
7375
|
+
_ChunkData.validateIndex(index);
|
|
7376
|
+
const entry = this.palette[this.indices[index]];
|
|
7377
|
+
return entry ? _ChunkData.copyBlock.bind(void 0, entry.state, this.nbt.get(index)) : void 0;
|
|
7378
|
+
}
|
|
7379
|
+
set(index, block) {
|
|
7380
|
+
_ChunkData.validateIndex(index);
|
|
7381
|
+
let state;
|
|
7382
|
+
let key;
|
|
7383
|
+
let nbt;
|
|
7384
|
+
if (block && !_ChunkData.isAir(block)) {
|
|
7385
|
+
const type = AssetKey.parse("blockstates", block.type).toNamespacedString();
|
|
7386
|
+
const properties = Object.fromEntries(Object.keys(block.properties ?? {}).sort().map((name) => [name, block.properties[name]]));
|
|
7387
|
+
state = Object.freeze(Object.keys(properties).length ? { type, properties: Object.freeze(properties) } : { type });
|
|
7388
|
+
key = JSON.stringify([type, properties]);
|
|
7389
|
+
if (block.nbt !== void 0) nbt = structuredClone(block.nbt);
|
|
7390
|
+
}
|
|
7391
|
+
const previousId = this.indices[index];
|
|
7392
|
+
if (previousId !== 0) {
|
|
7393
|
+
const previous = this.palette[previousId];
|
|
7394
|
+
if (--previous.references === 0) {
|
|
7395
|
+
this.paletteIds.delete(previous.key);
|
|
7396
|
+
this.palette[previousId] = void 0;
|
|
7397
|
+
this.freeIds.push(previousId);
|
|
7398
|
+
}
|
|
7399
|
+
}
|
|
7400
|
+
let id = 0;
|
|
7401
|
+
if (state && key !== void 0) {
|
|
7402
|
+
const existingId = this.paletteIds.get(key);
|
|
7403
|
+
if (existingId !== void 0) {
|
|
7404
|
+
id = existingId;
|
|
7405
|
+
this.palette[id].references++;
|
|
7406
|
+
} else {
|
|
7407
|
+
id = this.freeIds.pop() ?? this.palette.length;
|
|
7408
|
+
this.palette[id] = { key, state, references: 1 };
|
|
7409
|
+
this.paletteIds.set(key, id);
|
|
7410
|
+
}
|
|
7411
|
+
}
|
|
7412
|
+
this.indices[index] = id;
|
|
7413
|
+
if (nbt !== void 0) this.nbt.set(index, nbt);
|
|
7414
|
+
else this.nbt.delete(index);
|
|
7415
|
+
}
|
|
7416
|
+
clear() {
|
|
7417
|
+
this.indices.fill(0);
|
|
7418
|
+
this.palette.length = 1;
|
|
7419
|
+
this.paletteIds.clear();
|
|
7420
|
+
this.freeIds.length = 0;
|
|
7421
|
+
this.nbt.clear();
|
|
7422
|
+
}
|
|
7423
|
+
static isAir(block) {
|
|
7424
|
+
if (typeof block === "undefined" || typeof block.type === "undefined") return true;
|
|
7425
|
+
const key = AssetKey.parse("blockstates", block.type);
|
|
7426
|
+
return key.namespace === "minecraft" && !key.type && ["air", "cave_air", "void_air"].includes(key.path);
|
|
7427
|
+
}
|
|
7428
|
+
static copyBlock(state, nbt) {
|
|
7429
|
+
const block = { type: state.type };
|
|
7430
|
+
if (state.properties) block.properties = { ...state.properties };
|
|
7431
|
+
if (nbt !== void 0) block.nbt = structuredClone(nbt);
|
|
7432
|
+
return block;
|
|
7433
|
+
}
|
|
7434
|
+
static validateIndex(index) {
|
|
7435
|
+
if (!Number.isInteger(index) || index < 0 || index >= 4096) {
|
|
7436
|
+
throw new RangeError("Block index must be an integer from 0 to 4095");
|
|
7437
|
+
}
|
|
7438
|
+
}
|
|
7439
|
+
};
|
|
7243
7440
|
|
|
7244
7441
|
// src/world/MineRenderWorld.ts
|
|
7245
|
-
import { Vector3 as
|
|
7442
|
+
import { Vector3 as Vector311 } from "three";
|
|
7246
7443
|
var MineRenderWorld = class {
|
|
7247
7444
|
constructor(scene) {
|
|
7248
7445
|
this._chunks = /* @__PURE__ */ new Map();
|
|
7446
|
+
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
7249
7447
|
this.scene = scene;
|
|
7250
7448
|
}
|
|
7251
7449
|
getBlockAt(posOrX, y, z) {
|
|
7252
7450
|
if (typeof posOrX == "number") {
|
|
7253
|
-
return this.getBlockAt(new
|
|
7451
|
+
return this.getBlockAt(new Vector311(posOrX, y, z));
|
|
7254
7452
|
}
|
|
7255
7453
|
if (isTripleArray(posOrX)) {
|
|
7256
|
-
return this.getBlockAt(new
|
|
7454
|
+
return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
|
|
7257
7455
|
}
|
|
7258
7456
|
this.validatePosBounds(posOrX);
|
|
7259
7457
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
7260
7458
|
}
|
|
7261
7459
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7262
7460
|
if (typeof posOrX == "number") {
|
|
7263
|
-
return this.setBlockAt(new
|
|
7461
|
+
return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
|
|
7264
7462
|
}
|
|
7265
7463
|
if (isTripleArray(posOrX)) {
|
|
7266
|
-
return this.setBlockAt(new
|
|
7464
|
+
return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7267
7465
|
}
|
|
7268
7466
|
this.validatePosBounds(posOrX);
|
|
7269
7467
|
const value = yOrBlock;
|
|
@@ -7306,16 +7504,54 @@ var MineRenderWorld = class {
|
|
|
7306
7504
|
}
|
|
7307
7505
|
}
|
|
7308
7506
|
async clear() {
|
|
7309
|
-
|
|
7507
|
+
await this.culling;
|
|
7508
|
+
const chunks = [...this._chunks.values()];
|
|
7509
|
+
this._chunks.clear();
|
|
7510
|
+
for (const chunk of chunks) {
|
|
7310
7511
|
await chunk.dispose();
|
|
7311
7512
|
}
|
|
7312
|
-
|
|
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
|
+
});
|
|
7313
7543
|
}
|
|
7314
7544
|
getOrCreateChunkAt(pos) {
|
|
7315
7545
|
const key = this.worldPosToChunkKey(pos);
|
|
7316
7546
|
let chunk = this._chunks.get(key);
|
|
7317
7547
|
if (typeof chunk === "undefined") {
|
|
7318
|
-
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
|
+
);
|
|
7319
7555
|
this._chunks.set(key, chunk);
|
|
7320
7556
|
}
|
|
7321
7557
|
return chunk;
|
|
@@ -7324,14 +7560,14 @@ var MineRenderWorld = class {
|
|
|
7324
7560
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
7325
7561
|
}
|
|
7326
7562
|
static worldToScenePosition(pos) {
|
|
7327
|
-
return new
|
|
7563
|
+
return new Vector311(
|
|
7328
7564
|
pos.x * 16,
|
|
7329
7565
|
pos.y * 16,
|
|
7330
7566
|
pos.z * 16
|
|
7331
7567
|
);
|
|
7332
7568
|
}
|
|
7333
7569
|
static sceneToWorldPosition(pos) {
|
|
7334
|
-
return new
|
|
7570
|
+
return new Vector311(
|
|
7335
7571
|
pos.x / 16,
|
|
7336
7572
|
pos.y / 16,
|
|
7337
7573
|
pos.z / 16
|
|
@@ -7351,10 +7587,11 @@ var MineRenderWorld = class {
|
|
|
7351
7587
|
};
|
|
7352
7588
|
|
|
7353
7589
|
// src/world/Chunk.ts
|
|
7354
|
-
var p11 = prefix("Chunk");
|
|
7355
7590
|
var Chunk = class _Chunk {
|
|
7356
|
-
constructor(scene, x, y, z) {
|
|
7357
|
-
this.
|
|
7591
|
+
constructor(scene, x, y, z, onBlocksChanged) {
|
|
7592
|
+
this.onBlocksChanged = onBlocksChanged;
|
|
7593
|
+
this.data = new ChunkData();
|
|
7594
|
+
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
7358
7595
|
this.scene = scene;
|
|
7359
7596
|
this.x = x;
|
|
7360
7597
|
this.y = y;
|
|
@@ -7362,21 +7599,21 @@ var Chunk = class _Chunk {
|
|
|
7362
7599
|
}
|
|
7363
7600
|
getBlockAt(posOrX, y, z) {
|
|
7364
7601
|
if (typeof posOrX == "number") {
|
|
7365
|
-
return this.getBlockAt(new
|
|
7602
|
+
return this.getBlockAt(new Vector312(posOrX, y, z));
|
|
7366
7603
|
}
|
|
7367
7604
|
if (isTripleArray(posOrX)) {
|
|
7368
|
-
return this.getBlockAt(new
|
|
7605
|
+
return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
|
|
7369
7606
|
}
|
|
7370
7607
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
7371
7608
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
7372
|
-
return this.
|
|
7609
|
+
return this.renderedBlocks.get(index);
|
|
7373
7610
|
}
|
|
7374
7611
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
7375
7612
|
if (typeof posOrX == "number") {
|
|
7376
|
-
return this.setBlockAt(new
|
|
7613
|
+
return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
|
|
7377
7614
|
}
|
|
7378
7615
|
if (isTripleArray(posOrX)) {
|
|
7379
|
-
return this.setBlockAt(new
|
|
7616
|
+
return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
7380
7617
|
}
|
|
7381
7618
|
const worldPos = posOrX;
|
|
7382
7619
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -7391,44 +7628,53 @@ var Chunk = class _Chunk {
|
|
|
7391
7628
|
worldPos = this.chunkPosToWorldPos(pos);
|
|
7392
7629
|
}
|
|
7393
7630
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
7394
|
-
|
|
7395
|
-
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7631
|
+
this.data.set(index, block);
|
|
7632
|
+
const readBlock = this.data.snapshot(index);
|
|
7633
|
+
this.renderedBlocks.get(index)?.object.removeFromScene();
|
|
7634
|
+
this.renderedBlocks.delete(index);
|
|
7635
|
+
let object;
|
|
7636
|
+
try {
|
|
7637
|
+
if (!readBlock) return void 0;
|
|
7638
|
+
const stored = readBlock();
|
|
7639
|
+
const blockState = await BlockStates.get(AssetKey.parse("blockstates", stored.type));
|
|
7640
|
+
if (!blockState) {
|
|
7641
|
+
this.data.set(index, void 0);
|
|
7642
|
+
return void 0;
|
|
7643
|
+
}
|
|
7644
|
+
object = await this.scene.addBlock(blockState, {
|
|
7404
7645
|
mergeMeshes: true,
|
|
7405
7646
|
instanceMeshes: true,
|
|
7406
7647
|
maxInstanceCount: 2e3
|
|
7407
7648
|
});
|
|
7408
|
-
if (
|
|
7409
|
-
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
this.
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7649
|
+
if (stored.properties) await object.setState(stored.properties);
|
|
7650
|
+
object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
|
|
7651
|
+
const info = { get block() {
|
|
7652
|
+
return readBlock();
|
|
7653
|
+
}, object };
|
|
7654
|
+
this.renderedBlocks.set(index, info);
|
|
7655
|
+
return info;
|
|
7656
|
+
} catch (error) {
|
|
7657
|
+
this.data.set(index, void 0);
|
|
7658
|
+
object?.removeFromScene();
|
|
7659
|
+
throw error;
|
|
7660
|
+
} finally {
|
|
7661
|
+
await this.onBlocksChanged?.([worldPos]);
|
|
7418
7662
|
}
|
|
7419
|
-
return void 0;
|
|
7420
7663
|
}
|
|
7421
7664
|
async clear() {
|
|
7422
|
-
this.
|
|
7423
|
-
|
|
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
|
+
));
|
|
7668
|
+
for (const info of this.renderedBlocks.values()) info.object.removeFromScene();
|
|
7669
|
+
this.renderedBlocks.clear();
|
|
7670
|
+
this.data.clear();
|
|
7671
|
+
await this.onBlocksChanged?.(positions);
|
|
7424
7672
|
}
|
|
7425
7673
|
async dispose() {
|
|
7426
7674
|
await this.clear();
|
|
7427
7675
|
}
|
|
7428
7676
|
static isAir(block) {
|
|
7429
|
-
|
|
7430
|
-
const key = AssetKey.parse("blockstates", block.type);
|
|
7431
|
-
return key.namespace === "minecraft" && !key.type && ["air", "cave_air", "void_air"].includes(key.path);
|
|
7677
|
+
return ChunkData.isAir(block);
|
|
7432
7678
|
}
|
|
7433
7679
|
static chunkPosToBlockIndex(pos) {
|
|
7434
7680
|
if ([pos.x, pos.y, pos.z].some((value) => !Number.isInteger(value) || value < 0 || value >= 16)) {
|
|
@@ -7437,14 +7683,14 @@ var Chunk = class _Chunk {
|
|
|
7437
7683
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
7438
7684
|
}
|
|
7439
7685
|
worldPosToChunkPos(pos) {
|
|
7440
|
-
return new
|
|
7686
|
+
return new Vector312(
|
|
7441
7687
|
pos.x - this.x * 16,
|
|
7442
7688
|
pos.y - this.y * 16,
|
|
7443
7689
|
pos.z - this.z * 16
|
|
7444
7690
|
);
|
|
7445
7691
|
}
|
|
7446
7692
|
chunkPosToWorldPos(pos) {
|
|
7447
|
-
return new
|
|
7693
|
+
return new Vector312(
|
|
7448
7694
|
this.x * 16 + pos.x,
|
|
7449
7695
|
this.y * 16 + pos.y,
|
|
7450
7696
|
this.z * 16 + pos.z
|
|
@@ -7470,9 +7716,11 @@ export {
|
|
|
7470
7716
|
BlockTints,
|
|
7471
7717
|
BrowserArchiveProxy,
|
|
7472
7718
|
CUBE_FACES,
|
|
7719
|
+
CUBE_FACE_OFFSETS,
|
|
7473
7720
|
Caching,
|
|
7474
7721
|
CanvasImage,
|
|
7475
7722
|
Chunk,
|
|
7723
|
+
ChunkData,
|
|
7476
7724
|
CubeFace,
|
|
7477
7725
|
CubeFaceIndex,
|
|
7478
7726
|
DEFAULT_ELEMENTS,
|
|
@@ -7502,6 +7750,7 @@ export {
|
|
|
7502
7750
|
MineRenderWorld,
|
|
7503
7751
|
MinecraftCubeTexture,
|
|
7504
7752
|
MinecraftFaceUV,
|
|
7753
|
+
ModelCulling,
|
|
7505
7754
|
ModelGenerator,
|
|
7506
7755
|
ModelMerger,
|
|
7507
7756
|
ModelObject,
|