minerender 2.1.0-alpha.40 → 2.1.0-alpha.42
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 +72 -22
- package/dist/browser/index.d.ts +72 -22
- package/dist/browser/index.js +470 -217
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +384 -131
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +812 -553
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +72 -22
- package/dist/node/index.d.ts +72 -22
- package/dist/node/index.js +473 -217
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +384 -131
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/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 p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
|
|
36
|
+
t[p10] = s[p10];
|
|
37
37
|
}
|
|
38
38
|
return t;
|
|
39
39
|
};
|
|
@@ -766,11 +766,11 @@ var ImageLoader = class _ImageLoader {
|
|
|
766
766
|
static async loadCanvasData(src) {
|
|
767
767
|
const keyStr = serializeImageKey({ src });
|
|
768
768
|
const info = this.getInfo(src);
|
|
769
|
-
const
|
|
769
|
+
const cached2 = Caching.rawImageCache.getIfPresent(keyStr);
|
|
770
770
|
try {
|
|
771
771
|
return await this.infoToCanvasData(await info);
|
|
772
772
|
} catch (err) {
|
|
773
|
-
if (
|
|
773
|
+
if (cached2 && Caching.rawImageCache.getIfPresent(keyStr) === cached2) {
|
|
774
774
|
Caching.rawImageCache.invalidate(keyStr);
|
|
775
775
|
}
|
|
776
776
|
throw err;
|
|
@@ -905,8 +905,8 @@ var Textures = class _Textures {
|
|
|
905
905
|
}
|
|
906
906
|
static getImage(key) {
|
|
907
907
|
const keyStr = serializeTextureKey(key);
|
|
908
|
-
const
|
|
909
|
-
if (
|
|
908
|
+
const cached2 = Caching.textureCache.peek(keyStr);
|
|
909
|
+
if (cached2 && TextureLoader.hasFailed(cached2)) {
|
|
910
910
|
Caching.textureCache.invalidate(keyStr);
|
|
911
911
|
}
|
|
912
912
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
@@ -1173,12 +1173,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1173
1173
|
return a.join("/");
|
|
1174
1174
|
}
|
|
1175
1175
|
getFullPath() {
|
|
1176
|
-
let
|
|
1176
|
+
let p10 = [];
|
|
1177
1177
|
if (this.type) {
|
|
1178
|
-
|
|
1178
|
+
p10.push(this.type);
|
|
1179
1179
|
}
|
|
1180
|
-
|
|
1181
|
-
return
|
|
1180
|
+
p10.push(this.path);
|
|
1181
|
+
return p10.join("/");
|
|
1182
1182
|
}
|
|
1183
1183
|
toNamespacedString() {
|
|
1184
1184
|
return this.namespace + ":" + this.getFullPath();
|
|
@@ -1265,7 +1265,7 @@ var ModelMerger = class {
|
|
|
1265
1265
|
merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
|
|
1266
1266
|
}
|
|
1267
1267
|
}
|
|
1268
|
-
merged.hierarchy = models.map((m) => m.parent).filter((
|
|
1268
|
+
merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
|
|
1269
1269
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1270
1270
|
return merged;
|
|
1271
1271
|
}
|
|
@@ -1972,7 +1972,7 @@ var ModelTextures = class {
|
|
|
1972
1972
|
static async get(key) {
|
|
1973
1973
|
const keyStr = key.serialize();
|
|
1974
1974
|
const pending = this.preload(key);
|
|
1975
|
-
const
|
|
1975
|
+
const cached2 = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
1976
1976
|
try {
|
|
1977
1977
|
const asset = await pending;
|
|
1978
1978
|
if (asset) {
|
|
@@ -1980,7 +1980,7 @@ var ModelTextures = class {
|
|
|
1980
1980
|
}
|
|
1981
1981
|
return void 0;
|
|
1982
1982
|
} catch (err) {
|
|
1983
|
-
if (
|
|
1983
|
+
if (cached2 && Caching.textureAssetCache.getIfPresent(keyStr) === cached2) {
|
|
1984
1984
|
Caching.textureAssetCache.invalidate(keyStr);
|
|
1985
1985
|
}
|
|
1986
1986
|
throw err;
|
|
@@ -3856,6 +3856,93 @@ var ModelCulling = class {
|
|
|
3856
3856
|
}
|
|
3857
3857
|
};
|
|
3858
3858
|
|
|
3859
|
+
// src/model/block/BlockStateResolver.ts
|
|
3860
|
+
import { Euler as Euler5 } from "three";
|
|
3861
|
+
function matchesCondition(condition, state) {
|
|
3862
|
+
return Object.entries(condition).every(([key, value]) => {
|
|
3863
|
+
if (Array.isArray(value)) {
|
|
3864
|
+
if (key === "OR") return value.some((child) => matchesCondition(child, state));
|
|
3865
|
+
if (key === "AND") return value.every((child) => matchesCondition(child, state));
|
|
3866
|
+
return false;
|
|
3867
|
+
}
|
|
3868
|
+
return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
|
|
3869
|
+
});
|
|
3870
|
+
}
|
|
3871
|
+
var BlockStateResolver = class {
|
|
3872
|
+
static async defaults(blockState) {
|
|
3873
|
+
const defaults = blockState.key ? await BlockStates.getDefaultState(blockState.key) : void 0;
|
|
3874
|
+
const state = {};
|
|
3875
|
+
if (defaults && Object.keys(defaults).length > 0) {
|
|
3876
|
+
for (const key in defaults) state[key] = defaults[key].default;
|
|
3877
|
+
} else if (blockState.variants) {
|
|
3878
|
+
const variant = Object.keys(blockState.variants)[0];
|
|
3879
|
+
if (variant) {
|
|
3880
|
+
for (const property of variant.split(",")) {
|
|
3881
|
+
const [key, value] = property.split("=");
|
|
3882
|
+
state[key] = value;
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
} else if (blockState.multipart) {
|
|
3886
|
+
const condition = blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
|
|
3887
|
+
for (const [key, value] of Object.entries(condition ?? {})) state[key] = value.split("|")[0];
|
|
3888
|
+
}
|
|
3889
|
+
return state;
|
|
3890
|
+
}
|
|
3891
|
+
static select(blockState, state, choose = this.choose) {
|
|
3892
|
+
return this.matching(blockState, state).map(choose);
|
|
3893
|
+
}
|
|
3894
|
+
static matching(blockState, state) {
|
|
3895
|
+
const out = [];
|
|
3896
|
+
if (blockState.variants) {
|
|
3897
|
+
if (Object.keys(blockState.variants).length === 1 && "" in blockState.variants) {
|
|
3898
|
+
out.push(blockState.variants[""]);
|
|
3899
|
+
} else {
|
|
3900
|
+
for (const variantKey in blockState.variants) {
|
|
3901
|
+
const matches = variantKey.split(",").every((property) => {
|
|
3902
|
+
const [key, value] = property.split("=");
|
|
3903
|
+
return `${state[key]}` === `${value}`;
|
|
3904
|
+
});
|
|
3905
|
+
if (matches) out.push(blockState.variants[variantKey]);
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
} else if (blockState.multipart) {
|
|
3909
|
+
for (const part of blockState.multipart) {
|
|
3910
|
+
if (part.apply && (!part.when || matchesCondition(part.when, state))) {
|
|
3911
|
+
out.push(part.apply);
|
|
3912
|
+
}
|
|
3913
|
+
}
|
|
3914
|
+
}
|
|
3915
|
+
return out;
|
|
3916
|
+
}
|
|
3917
|
+
static choose(variants) {
|
|
3918
|
+
if (!Array.isArray(variants)) return variants;
|
|
3919
|
+
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
3920
|
+
const total = variants.reduce((sum, variant) => {
|
|
3921
|
+
const weight = variant.weight ?? 1;
|
|
3922
|
+
if (!Number.isInteger(weight) || weight < 1) {
|
|
3923
|
+
throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
|
|
3924
|
+
}
|
|
3925
|
+
return sum + weight;
|
|
3926
|
+
}, 0);
|
|
3927
|
+
let choice = Math.random() * total;
|
|
3928
|
+
for (const variant of variants) {
|
|
3929
|
+
choice -= variant.weight ?? 1;
|
|
3930
|
+
if (choice < 0) return variant;
|
|
3931
|
+
}
|
|
3932
|
+
return variants[variants.length - 1];
|
|
3933
|
+
}
|
|
3934
|
+
static rotation(variant) {
|
|
3935
|
+
const rotation = new Euler5();
|
|
3936
|
+
if (typeof variant.x !== "undefined") {
|
|
3937
|
+
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
3938
|
+
}
|
|
3939
|
+
if (typeof variant.y !== "undefined") {
|
|
3940
|
+
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
3941
|
+
}
|
|
3942
|
+
return rotation;
|
|
3943
|
+
}
|
|
3944
|
+
};
|
|
3945
|
+
|
|
3859
3946
|
// src/model/block/blockTints.json
|
|
3860
3947
|
var blockTints_default = {
|
|
3861
3948
|
"minecraft:large_fern": { source: "grass" },
|
|
@@ -3942,7 +4029,7 @@ var BlockTints = class {
|
|
|
3942
4029
|
};
|
|
3943
4030
|
|
|
3944
4031
|
// src/model/scene/ModelObject.ts
|
|
3945
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as
|
|
4032
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler6, Matrix4 as Matrix44 } from "three";
|
|
3946
4033
|
|
|
3947
4034
|
// src/three/BufferGeometryUtils.js
|
|
3948
4035
|
import {
|
|
@@ -4533,7 +4620,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
|
|
|
4533
4620
|
elGeo.clearGroups();
|
|
4534
4621
|
}
|
|
4535
4622
|
if (this.options.uvLockRotation) {
|
|
4536
|
-
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new
|
|
4623
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler6(...this.options.uvLockRotation));
|
|
4537
4624
|
}
|
|
4538
4625
|
if (this.options.tints) {
|
|
4539
4626
|
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
@@ -4631,18 +4718,7 @@ function isModelObject(obj) {
|
|
|
4631
4718
|
|
|
4632
4719
|
// src/model/block/scene/BlockObject.ts
|
|
4633
4720
|
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4634
|
-
import { Euler as
|
|
4635
|
-
var p10 = prefix("BlockObject");
|
|
4636
|
-
function matchesCondition(condition, state) {
|
|
4637
|
-
return Object.entries(condition).every(([key, value]) => {
|
|
4638
|
-
if (Array.isArray(value)) {
|
|
4639
|
-
if (key === "OR") return value.some((child) => matchesCondition(child, state));
|
|
4640
|
-
if (key === "AND") return value.every((child) => matchesCondition(child, state));
|
|
4641
|
-
return false;
|
|
4642
|
-
}
|
|
4643
|
-
return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
|
|
4644
|
-
});
|
|
4645
|
-
}
|
|
4721
|
+
import { Euler as Euler7, Matrix4 as Matrix45, Quaternion as Quaternion4, Vector3 as Vector38 } from "three";
|
|
4646
4722
|
var _BlockObject = class _BlockObject extends SceneObject {
|
|
4647
4723
|
constructor(blockState, options) {
|
|
4648
4724
|
super(options);
|
|
@@ -4661,22 +4737,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4661
4737
|
}
|
|
4662
4738
|
async init() {
|
|
4663
4739
|
if (this.options.applyDefaultState) {
|
|
4664
|
-
|
|
4665
|
-
if (defaultState && Object.keys(defaultState).length > 0) {
|
|
4666
|
-
const state = {};
|
|
4667
|
-
for (let k in defaultState) {
|
|
4668
|
-
state[k] = defaultState[k].default;
|
|
4669
|
-
}
|
|
4670
|
-
this._setState(state);
|
|
4671
|
-
} else {
|
|
4672
|
-
if (this.blockState.variants) {
|
|
4673
|
-
this._setState(Object.keys(this.blockState.variants)[0]);
|
|
4674
|
-
} else if (this.blockState.multipart) {
|
|
4675
|
-
const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
|
|
4676
|
-
const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
|
|
4677
|
-
this._setState(state);
|
|
4678
|
-
}
|
|
4679
|
-
}
|
|
4740
|
+
this._setState(await BlockStateResolver.defaults(this.blockState));
|
|
4680
4741
|
}
|
|
4681
4742
|
if (this.options.initialState !== void 0) this._setState(this.options.initialState);
|
|
4682
4743
|
await this.recreateModels();
|
|
@@ -4719,7 +4780,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4719
4780
|
const scale = new Vector38();
|
|
4720
4781
|
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
4721
4782
|
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector38(1, 1, 1)) > 1e-10) return 0;
|
|
4722
|
-
return ModelCulling.toLocalMask(worldMask, new
|
|
4783
|
+
return ModelCulling.toLocalMask(worldMask, new Euler7().setFromQuaternion(rotation));
|
|
4723
4784
|
}
|
|
4724
4785
|
async setCullMask(worldMask) {
|
|
4725
4786
|
worldMask &= 63;
|
|
@@ -4767,39 +4828,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4767
4828
|
return ref;
|
|
4768
4829
|
}
|
|
4769
4830
|
async mapStateToVariant(state) {
|
|
4770
|
-
|
|
4771
|
-
if (this.blockState.variants) {
|
|
4772
|
-
if (Object.keys(this.blockState.variants).length === 1 && "" in this.blockState.variants) {
|
|
4773
|
-
out.push(this.getSingleVariant(this.blockState.variants[""]));
|
|
4774
|
-
} else {
|
|
4775
|
-
for (let variantKey in this.blockState.variants) {
|
|
4776
|
-
const split = variantKey.split(",");
|
|
4777
|
-
let matches = true;
|
|
4778
|
-
for (let s of split) {
|
|
4779
|
-
const [k, v] = s.split("=");
|
|
4780
|
-
if (`${state[k]}` !== `${v}`) {
|
|
4781
|
-
matches = false;
|
|
4782
|
-
break;
|
|
4783
|
-
}
|
|
4784
|
-
}
|
|
4785
|
-
if (matches) {
|
|
4786
|
-
const variants = this.blockState.variants[variantKey];
|
|
4787
|
-
out.push(this.getSingleVariant(variants));
|
|
4788
|
-
}
|
|
4789
|
-
}
|
|
4790
|
-
}
|
|
4791
|
-
} else if (this.blockState.multipart) {
|
|
4792
|
-
for (let part of this.blockState.multipart) {
|
|
4793
|
-
if (!part.apply) {
|
|
4794
|
-
console.debug(p10, "Missing apply for blockState part", part);
|
|
4795
|
-
continue;
|
|
4796
|
-
}
|
|
4797
|
-
if (!part.when || matchesCondition(part.when, state)) {
|
|
4798
|
-
out.push(this.getSingleVariant(part.apply));
|
|
4799
|
-
}
|
|
4800
|
-
}
|
|
4801
|
-
}
|
|
4802
|
-
return out;
|
|
4831
|
+
return BlockStateResolver.select(this.blockState, state, (variants) => this.getSingleVariant(variants));
|
|
4803
4832
|
}
|
|
4804
4833
|
async recreateModels() {
|
|
4805
4834
|
this.clearModels();
|
|
@@ -4810,21 +4839,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4810
4839
|
}
|
|
4811
4840
|
}
|
|
4812
4841
|
getSingleVariant(variants) {
|
|
4813
|
-
|
|
4814
|
-
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
4815
|
-
const total = variants.reduce((sum, variant) => {
|
|
4816
|
-
const weight = variant.weight ?? 1;
|
|
4817
|
-
if (!Number.isInteger(weight) || weight < 1) {
|
|
4818
|
-
throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
|
|
4819
|
-
}
|
|
4820
|
-
return sum + weight;
|
|
4821
|
-
}, 0);
|
|
4822
|
-
let choice = Math.random() * total;
|
|
4823
|
-
for (const variant of variants) {
|
|
4824
|
-
choice -= variant.weight ?? 1;
|
|
4825
|
-
if (choice < 0) return variant;
|
|
4826
|
-
}
|
|
4827
|
-
return variants[variants.length - 1];
|
|
4842
|
+
return BlockStateResolver.choose(variants);
|
|
4828
4843
|
}
|
|
4829
4844
|
// @deprecated
|
|
4830
4845
|
async createAVariant(variants, instanceInfo) {
|
|
@@ -4832,13 +4847,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
|
|
|
4832
4847
|
await this.createVariant(variant);
|
|
4833
4848
|
}
|
|
4834
4849
|
async createVariant(variant) {
|
|
4835
|
-
const rotation =
|
|
4836
|
-
if (typeof variant.x !== "undefined") {
|
|
4837
|
-
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4838
|
-
}
|
|
4839
|
-
if (typeof variant.y !== "undefined") {
|
|
4840
|
-
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
4841
|
-
}
|
|
4850
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
4842
4851
|
const modelKey = AssetKey.parse("models", variant.model);
|
|
4843
4852
|
modelKey.root = this.blockState.key?.root;
|
|
4844
4853
|
const model = await Models.getMerged(modelKey);
|
|
@@ -9343,32 +9352,121 @@ var AnvilParser = class {
|
|
|
9343
9352
|
};
|
|
9344
9353
|
|
|
9345
9354
|
// src/world/Chunk.ts
|
|
9355
|
+
import { Vector3 as Vector313 } from "three";
|
|
9356
|
+
|
|
9357
|
+
// src/world/MineRenderWorld.ts
|
|
9346
9358
|
import { Vector3 as Vector312 } from "three";
|
|
9347
9359
|
|
|
9360
|
+
// src/world/SectionModels.ts
|
|
9361
|
+
import { Matrix4 as Matrix46, Vector3 as Vector311 } from "three";
|
|
9362
|
+
var SectionModel = class extends ModelObject {
|
|
9363
|
+
applyTextures() {
|
|
9364
|
+
}
|
|
9365
|
+
};
|
|
9366
|
+
function cached(map, key, load) {
|
|
9367
|
+
let value = map.get(key);
|
|
9368
|
+
if (!value) {
|
|
9369
|
+
value = load().catch((error) => {
|
|
9370
|
+
map.delete(key);
|
|
9371
|
+
throw error;
|
|
9372
|
+
});
|
|
9373
|
+
map.set(key, value);
|
|
9374
|
+
}
|
|
9375
|
+
return value;
|
|
9376
|
+
}
|
|
9377
|
+
var SectionModels = class {
|
|
9378
|
+
constructor(maxAtlasSize = 2048) {
|
|
9379
|
+
this.maxAtlasSize = maxAtlasSize;
|
|
9380
|
+
this.states = /* @__PURE__ */ new WeakMap();
|
|
9381
|
+
this.models = /* @__PURE__ */ new WeakMap();
|
|
9382
|
+
this.templates = /* @__PURE__ */ new Set();
|
|
9383
|
+
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("maxAtlasSize must be a positive integer");
|
|
9384
|
+
}
|
|
9385
|
+
async get(blockState, properties = {}) {
|
|
9386
|
+
if (!blockState.variants || blockState.multipart) return void 0;
|
|
9387
|
+
let states = this.states.get(blockState);
|
|
9388
|
+
if (!states) this.states.set(blockState, states = /* @__PURE__ */ new Map());
|
|
9389
|
+
const key = JSON.stringify(Object.entries(properties).sort(([a], [b]) => a.localeCompare(b)));
|
|
9390
|
+
const prepared = await cached(states, key, () => this.prepare(blockState, properties));
|
|
9391
|
+
if (!prepared) return void 0;
|
|
9392
|
+
return prepared.templates.get(BlockStateResolver.choose(prepared.variants));
|
|
9393
|
+
}
|
|
9394
|
+
async prepare(blockState, properties) {
|
|
9395
|
+
const state = { ...await BlockStateResolver.defaults(blockState), ...properties };
|
|
9396
|
+
const groups = BlockStateResolver.matching(blockState, state);
|
|
9397
|
+
if (groups.length !== 1) return void 0;
|
|
9398
|
+
const variants = groups[0];
|
|
9399
|
+
const choices = Array.isArray(variants) ? variants : [variants];
|
|
9400
|
+
if (!choices.length) return void 0;
|
|
9401
|
+
const templates = /* @__PURE__ */ new Map();
|
|
9402
|
+
for (const variant of choices) {
|
|
9403
|
+
const model = await Models.getMerged(AssetKey.parse("models", variant.model));
|
|
9404
|
+
if (!model) return void 0;
|
|
9405
|
+
const atlas = await UVMapper.getAtlas(model);
|
|
9406
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
9407
|
+
if (!atlas || atlas.hasAnimation || !ModelCulling.isOpaqueFullCube(atlas) || atlas.image.width > this.maxAtlasSize || atlas.image.height > this.maxAtlasSize || ModelCulling.toLocalMask(63, rotation) !== 63) return void 0;
|
|
9408
|
+
const tints = await BlockTints.get(blockState.key, state, model);
|
|
9409
|
+
let models = this.models.get(model);
|
|
9410
|
+
if (!models) this.models.set(model, models = /* @__PURE__ */ new Map());
|
|
9411
|
+
const key = JSON.stringify([rotation.x, rotation.y, rotation.z, variant.uvlock, tints]);
|
|
9412
|
+
const template = await cached(models, key, async () => {
|
|
9413
|
+
const object = new SectionModel(model, {
|
|
9414
|
+
instanceMeshes: false,
|
|
9415
|
+
mergeMeshes: false,
|
|
9416
|
+
tints,
|
|
9417
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
9418
|
+
});
|
|
9419
|
+
await object.init();
|
|
9420
|
+
const geometry = object.children[0].geometry;
|
|
9421
|
+
geometry.applyMatrix4(new Matrix46().makeRotationFromEuler(rotation));
|
|
9422
|
+
object.clear();
|
|
9423
|
+
const cullFaces = CUBE_FACES.map((face) => {
|
|
9424
|
+
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
9425
|
+
if (local < 0) return 0;
|
|
9426
|
+
const normal = new Vector311(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
|
|
9427
|
+
const world = 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);
|
|
9428
|
+
return 1 << world;
|
|
9429
|
+
});
|
|
9430
|
+
const template2 = { geometry, atlas, cullFaces };
|
|
9431
|
+
this.templates.add(template2);
|
|
9432
|
+
return template2;
|
|
9433
|
+
});
|
|
9434
|
+
templates.set(variant, template);
|
|
9435
|
+
}
|
|
9436
|
+
return { variants, templates };
|
|
9437
|
+
}
|
|
9438
|
+
clear() {
|
|
9439
|
+
for (const template of this.templates) template.geometry.dispose();
|
|
9440
|
+
this.templates.clear();
|
|
9441
|
+
this.states = /* @__PURE__ */ new WeakMap();
|
|
9442
|
+
this.models = /* @__PURE__ */ new WeakMap();
|
|
9443
|
+
}
|
|
9444
|
+
};
|
|
9445
|
+
|
|
9348
9446
|
// src/world/MineRenderWorld.ts
|
|
9349
|
-
import { Vector3 as Vector311 } from "three";
|
|
9350
9447
|
var MineRenderWorld = class {
|
|
9351
|
-
constructor(scene) {
|
|
9448
|
+
constructor(scene, options = {}) {
|
|
9352
9449
|
this._chunks = /* @__PURE__ */ new Map();
|
|
9353
9450
|
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
9354
9451
|
this.scene = scene;
|
|
9452
|
+
if (options.sectionMeshing) this.sectionModels = new SectionModels(options.maxAtlasSize);
|
|
9355
9453
|
}
|
|
9356
9454
|
getBlockAt(posOrX, y, z) {
|
|
9357
9455
|
if (typeof posOrX == "number") {
|
|
9358
|
-
return this.getBlockAt(new
|
|
9456
|
+
return this.getBlockAt(new Vector312(posOrX, y, z));
|
|
9359
9457
|
}
|
|
9360
9458
|
if (isTripleArray(posOrX)) {
|
|
9361
|
-
return this.getBlockAt(new
|
|
9459
|
+
return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
|
|
9362
9460
|
}
|
|
9363
9461
|
this.validatePosBounds(posOrX);
|
|
9364
9462
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
9365
9463
|
}
|
|
9366
9464
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
9367
9465
|
if (typeof posOrX == "number") {
|
|
9368
|
-
return this.setBlockAt(new
|
|
9466
|
+
return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
|
|
9369
9467
|
}
|
|
9370
9468
|
if (isTripleArray(posOrX)) {
|
|
9371
|
-
return this.setBlockAt(new
|
|
9469
|
+
return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
9372
9470
|
}
|
|
9373
9471
|
return this.placeBlock(posOrX, yOrBlock);
|
|
9374
9472
|
}
|
|
@@ -9389,7 +9487,7 @@ var MineRenderWorld = class {
|
|
|
9389
9487
|
const collect = async (positions2) => {
|
|
9390
9488
|
for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
|
|
9391
9489
|
};
|
|
9392
|
-
const place = (block) => this.placeBlock(new
|
|
9490
|
+
const place = (block) => this.placeBlock(new Vector312(...block.position), block, collect);
|
|
9393
9491
|
const keys = /* @__PURE__ */ new Map();
|
|
9394
9492
|
for (const block of multiblock.blocks) {
|
|
9395
9493
|
if (Chunk.isAir(block)) continue;
|
|
@@ -9461,12 +9559,13 @@ var MineRenderWorld = class {
|
|
|
9461
9559
|
for (const chunk of chunks) {
|
|
9462
9560
|
await chunk.dispose();
|
|
9463
9561
|
}
|
|
9562
|
+
this.sectionModels?.clear();
|
|
9464
9563
|
}
|
|
9465
9564
|
updateCulling(positions) {
|
|
9466
9565
|
for (const pos of positions) {
|
|
9467
9566
|
this.pendingCulling.set(pos.toArray().join(","), pos.clone());
|
|
9468
9567
|
for (const offset of CUBE_FACE_OFFSETS) {
|
|
9469
|
-
const neighbor = pos.clone().add(new
|
|
9568
|
+
const neighbor = pos.clone().add(new Vector312(...offset));
|
|
9470
9569
|
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
9471
9570
|
}
|
|
9472
9571
|
}
|
|
@@ -9475,17 +9574,22 @@ var MineRenderWorld = class {
|
|
|
9475
9574
|
while (this.pendingCulling.size) {
|
|
9476
9575
|
const batch = [...this.pendingCulling.values()];
|
|
9477
9576
|
this.pendingCulling.clear();
|
|
9577
|
+
const changed = /* @__PURE__ */ new Set();
|
|
9478
9578
|
for (const pos of batch) {
|
|
9479
|
-
const
|
|
9480
|
-
if (!
|
|
9579
|
+
const chunk = this.getChunkAt(pos);
|
|
9580
|
+
if (!chunk) continue;
|
|
9581
|
+
changed.add(chunk);
|
|
9582
|
+
if (!chunk.getBlockAt(pos)) continue;
|
|
9481
9583
|
let mask = 0;
|
|
9482
9584
|
for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
9483
|
-
|
|
9585
|
+
const neighbor = pos.clone().add(new Vector312(...offset));
|
|
9586
|
+
if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
|
|
9484
9587
|
mask |= 1 << face;
|
|
9485
9588
|
}
|
|
9486
9589
|
}
|
|
9487
|
-
await
|
|
9590
|
+
await chunk.setCullMaskAt(pos, mask);
|
|
9488
9591
|
}
|
|
9592
|
+
for (const chunk of changed) chunk.rebuildSectionMesh();
|
|
9489
9593
|
}
|
|
9490
9594
|
} finally {
|
|
9491
9595
|
this.culling = void 0;
|
|
@@ -9501,7 +9605,8 @@ var MineRenderWorld = class {
|
|
|
9501
9605
|
Math.floor(pos.x / 16),
|
|
9502
9606
|
Math.floor(pos.y / 16),
|
|
9503
9607
|
Math.floor(pos.z / 16),
|
|
9504
|
-
(positions) => this.updateCulling(positions)
|
|
9608
|
+
(positions) => this.updateCulling(positions),
|
|
9609
|
+
this.sectionModels
|
|
9505
9610
|
);
|
|
9506
9611
|
this._chunks.set(key, chunk);
|
|
9507
9612
|
}
|
|
@@ -9511,14 +9616,14 @@ var MineRenderWorld = class {
|
|
|
9511
9616
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
9512
9617
|
}
|
|
9513
9618
|
static worldToScenePosition(pos) {
|
|
9514
|
-
return new
|
|
9619
|
+
return new Vector312(
|
|
9515
9620
|
pos.x * 16,
|
|
9516
9621
|
pos.y * 16,
|
|
9517
9622
|
pos.z * 16
|
|
9518
9623
|
);
|
|
9519
9624
|
}
|
|
9520
9625
|
static sceneToWorldPosition(pos) {
|
|
9521
|
-
return new
|
|
9626
|
+
return new Vector312(
|
|
9522
9627
|
pos.x / 16,
|
|
9523
9628
|
pos.y / 16,
|
|
9524
9629
|
pos.z / 16
|
|
@@ -9537,12 +9642,118 @@ var MineRenderWorld = class {
|
|
|
9537
9642
|
}
|
|
9538
9643
|
};
|
|
9539
9644
|
|
|
9645
|
+
// src/world/SectionMesh.ts
|
|
9646
|
+
import { BufferGeometry as BufferGeometry2, Float32BufferAttribute as Float32BufferAttribute4, Group, Mesh as Mesh7 } from "three";
|
|
9647
|
+
var SectionMesh = class _SectionMesh extends Group {
|
|
9648
|
+
constructor() {
|
|
9649
|
+
super(...arguments);
|
|
9650
|
+
this.ownedMeshes = [];
|
|
9651
|
+
}
|
|
9652
|
+
static build(entries, maxAtlasSize = 2048) {
|
|
9653
|
+
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
9654
|
+
const visible = entries.filter((entry) => entry.template.cullFaces.some((direction) => !(entry.cullMask & direction)));
|
|
9655
|
+
const atlases = [...new Set(visible.map((entry) => entry.template.atlas))].sort((a, b) => b.image.height - a.image.height);
|
|
9656
|
+
const pages = [];
|
|
9657
|
+
const locations = /* @__PURE__ */ new Map();
|
|
9658
|
+
for (const atlas of atlases) {
|
|
9659
|
+
const { width, height } = atlas.image;
|
|
9660
|
+
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
9661
|
+
let selected;
|
|
9662
|
+
for (const page of pages) {
|
|
9663
|
+
const nextRow = page.x + width > maxAtlasSize;
|
|
9664
|
+
if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;
|
|
9665
|
+
if (nextRow) {
|
|
9666
|
+
page.y += page.rowHeight;
|
|
9667
|
+
page.x = 0;
|
|
9668
|
+
page.rowHeight = 0;
|
|
9669
|
+
}
|
|
9670
|
+
selected = page;
|
|
9671
|
+
break;
|
|
9672
|
+
}
|
|
9673
|
+
if (!selected) {
|
|
9674
|
+
selected = { placements: [], entries: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 };
|
|
9675
|
+
pages.push(selected);
|
|
9676
|
+
}
|
|
9677
|
+
const placement = { atlas, x: selected.x, y: selected.y };
|
|
9678
|
+
selected.placements.push(placement);
|
|
9679
|
+
selected.x += width;
|
|
9680
|
+
selected.rowHeight = Math.max(selected.rowHeight, height);
|
|
9681
|
+
selected.width = Math.max(selected.width, selected.x);
|
|
9682
|
+
selected.height = Math.max(selected.height, selected.y + height);
|
|
9683
|
+
locations.set(atlas, { page: selected, placement });
|
|
9684
|
+
}
|
|
9685
|
+
for (const entry of visible) locations.get(entry.template.atlas).page.entries.push(entry);
|
|
9686
|
+
const section = new _SectionMesh();
|
|
9687
|
+
for (const page of pages) {
|
|
9688
|
+
const canvas = createCanvas(page.width, page.height);
|
|
9689
|
+
const context = canvas.getContext("2d");
|
|
9690
|
+
for (const { atlas, x, y } of page.placements) {
|
|
9691
|
+
context.drawImage(atlas.image.canvas, x, y);
|
|
9692
|
+
}
|
|
9693
|
+
const positions = [], normals = [], uvs = [], colors = [], indices = [];
|
|
9694
|
+
for (const { index, template, cullMask } of page.entries) {
|
|
9695
|
+
const position = template.geometry.getAttribute("position");
|
|
9696
|
+
const normal = template.geometry.getAttribute("normal");
|
|
9697
|
+
const uv = template.geometry.getAttribute("uv");
|
|
9698
|
+
const color = template.geometry.getAttribute("color");
|
|
9699
|
+
const sourceIndices = template.geometry.getIndex();
|
|
9700
|
+
const placement = locations.get(template.atlas).placement;
|
|
9701
|
+
const offsetX = index % 16 * 16;
|
|
9702
|
+
const offsetY = Math.floor(index / 256) * 16;
|
|
9703
|
+
const offsetZ = Math.floor(index / 16) % 16 * 16;
|
|
9704
|
+
for (let face = 0; face < 6; face++) {
|
|
9705
|
+
if (cullMask & template.cullFaces[face]) continue;
|
|
9706
|
+
const start = positions.length / 3;
|
|
9707
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
9708
|
+
const vertex = face * 4 + corner;
|
|
9709
|
+
positions.push(position.getX(vertex) + offsetX, position.getY(vertex) + offsetY, position.getZ(vertex) + offsetZ);
|
|
9710
|
+
normals.push(normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex));
|
|
9711
|
+
uvs.push(
|
|
9712
|
+
(placement.x + uv.getX(vertex) * template.atlas.image.width) / page.width,
|
|
9713
|
+
1 - (placement.y + (1 - uv.getY(vertex)) * template.atlas.image.height) / page.height
|
|
9714
|
+
);
|
|
9715
|
+
colors.push(color?.getX(vertex) ?? 1, color?.getY(vertex) ?? 1, color?.getZ(vertex) ?? 1);
|
|
9716
|
+
}
|
|
9717
|
+
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
9718
|
+
}
|
|
9719
|
+
}
|
|
9720
|
+
const geometry = new BufferGeometry2();
|
|
9721
|
+
geometry.setAttribute("position", new Float32BufferAttribute4(positions, 3));
|
|
9722
|
+
geometry.setAttribute("normal", new Float32BufferAttribute4(normals, 3));
|
|
9723
|
+
geometry.setAttribute("uv", new Float32BufferAttribute4(uvs, 2));
|
|
9724
|
+
geometry.setAttribute("color", new Float32BufferAttribute4(colors, 3));
|
|
9725
|
+
geometry.setIndex(indices);
|
|
9726
|
+
geometry.computeBoundingBox();
|
|
9727
|
+
geometry.computeBoundingSphere();
|
|
9728
|
+
const material = Materials.createShadedCanvasMaterial(canvas, false);
|
|
9729
|
+
material.vertexColors = true;
|
|
9730
|
+
const texture = material.uniforms?.map?.value ?? material.map;
|
|
9731
|
+
const mesh = new Mesh7(geometry, material);
|
|
9732
|
+
section.add(mesh);
|
|
9733
|
+
section.ownedMeshes.push({ mesh, texture });
|
|
9734
|
+
}
|
|
9735
|
+
return section;
|
|
9736
|
+
}
|
|
9737
|
+
dispose() {
|
|
9738
|
+
for (const { mesh, texture } of this.ownedMeshes.splice(0)) {
|
|
9739
|
+
mesh.removeFromParent();
|
|
9740
|
+
mesh.geometry.dispose();
|
|
9741
|
+
mesh.material.dispose();
|
|
9742
|
+
texture?.dispose();
|
|
9743
|
+
}
|
|
9744
|
+
this.removeFromParent();
|
|
9745
|
+
}
|
|
9746
|
+
};
|
|
9747
|
+
|
|
9540
9748
|
// src/world/Chunk.ts
|
|
9541
9749
|
var Chunk = class _Chunk {
|
|
9542
|
-
constructor(scene, x, y, z, onBlocksChanged) {
|
|
9750
|
+
constructor(scene, x, y, z, onBlocksChanged, sectionModels) {
|
|
9543
9751
|
this.onBlocksChanged = onBlocksChanged;
|
|
9752
|
+
this.sectionModels = sectionModels;
|
|
9544
9753
|
this.data = new ChunkData();
|
|
9545
9754
|
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
9755
|
+
this.sectionBlocks = /* @__PURE__ */ new Map();
|
|
9756
|
+
this.meshDirty = false;
|
|
9546
9757
|
this.scene = scene;
|
|
9547
9758
|
this.x = x;
|
|
9548
9759
|
this.y = y;
|
|
@@ -9550,10 +9761,10 @@ var Chunk = class _Chunk {
|
|
|
9550
9761
|
}
|
|
9551
9762
|
getBlockAt(posOrX, y, z) {
|
|
9552
9763
|
if (typeof posOrX == "number") {
|
|
9553
|
-
return this.getBlockAt(new
|
|
9764
|
+
return this.getBlockAt(new Vector313(posOrX, y, z));
|
|
9554
9765
|
}
|
|
9555
9766
|
if (isTripleArray(posOrX)) {
|
|
9556
|
-
return this.getBlockAt(new
|
|
9767
|
+
return this.getBlockAt(new Vector313(posOrX[0], posOrX[1], posOrX[2]));
|
|
9557
9768
|
}
|
|
9558
9769
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
9559
9770
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -9561,10 +9772,10 @@ var Chunk = class _Chunk {
|
|
|
9561
9772
|
}
|
|
9562
9773
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
9563
9774
|
if (typeof posOrX == "number") {
|
|
9564
|
-
return this.setBlockAt(new
|
|
9775
|
+
return this.setBlockAt(new Vector313(posOrX, yOrBlock, z), block);
|
|
9565
9776
|
}
|
|
9566
9777
|
if (isTripleArray(posOrX)) {
|
|
9567
|
-
return this.setBlockAt(new
|
|
9778
|
+
return this.setBlockAt(new Vector313(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
9568
9779
|
}
|
|
9569
9780
|
const worldPos = posOrX;
|
|
9570
9781
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -9581,7 +9792,8 @@ var Chunk = class _Chunk {
|
|
|
9581
9792
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
9582
9793
|
this.data.set(index, block);
|
|
9583
9794
|
const readBlock = this.data.snapshot(index);
|
|
9584
|
-
this.renderedBlocks.get(index)?.object
|
|
9795
|
+
this.renderedBlocks.get(index)?.object?.removeFromScene();
|
|
9796
|
+
if (this.sectionBlocks.delete(index)) this.meshDirty = true;
|
|
9585
9797
|
this.renderedBlocks.delete(index);
|
|
9586
9798
|
let object;
|
|
9587
9799
|
try {
|
|
@@ -9592,13 +9804,19 @@ var Chunk = class _Chunk {
|
|
|
9592
9804
|
this.data.set(index, void 0);
|
|
9593
9805
|
return void 0;
|
|
9594
9806
|
}
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9807
|
+
const template = await this.sectionModels?.get(blockState, stored.properties);
|
|
9808
|
+
if (template) {
|
|
9809
|
+
this.sectionBlocks.set(index, { index, template, cullMask: 0 });
|
|
9810
|
+
this.meshDirty = true;
|
|
9811
|
+
} else {
|
|
9812
|
+
object = await this.scene.addBlock(blockState, {
|
|
9813
|
+
mergeMeshes: true,
|
|
9814
|
+
instanceMeshes: true,
|
|
9815
|
+
maxInstanceCount: 2e3,
|
|
9816
|
+
initialState: stored.properties
|
|
9817
|
+
});
|
|
9818
|
+
object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
|
|
9819
|
+
}
|
|
9602
9820
|
const info = { get block() {
|
|
9603
9821
|
return readBlock();
|
|
9604
9822
|
}, object };
|
|
@@ -9612,11 +9830,43 @@ var Chunk = class _Chunk {
|
|
|
9612
9830
|
await onBlocksChanged?.([worldPos]);
|
|
9613
9831
|
}
|
|
9614
9832
|
}
|
|
9833
|
+
isOccludingAt(pos) {
|
|
9834
|
+
const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
|
|
9835
|
+
return this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false);
|
|
9836
|
+
}
|
|
9837
|
+
async setCullMaskAt(pos, mask) {
|
|
9838
|
+
const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
|
|
9839
|
+
const entry = this.sectionBlocks.get(index);
|
|
9840
|
+
if (entry) {
|
|
9841
|
+
if (entry.cullMask !== mask) {
|
|
9842
|
+
entry.cullMask = mask;
|
|
9843
|
+
this.meshDirty = true;
|
|
9844
|
+
}
|
|
9845
|
+
} else {
|
|
9846
|
+
await this.renderedBlocks.get(index)?.object?.setCullMask(mask);
|
|
9847
|
+
}
|
|
9848
|
+
}
|
|
9849
|
+
rebuildSectionMesh() {
|
|
9850
|
+
if (!this.meshDirty) return;
|
|
9851
|
+
const next = this.sectionBlocks.size ? SectionMesh.build([...this.sectionBlocks.values()], this.sectionModels.maxAtlasSize) : void 0;
|
|
9852
|
+
this.sectionMesh?.dispose();
|
|
9853
|
+
this.sectionMesh = next;
|
|
9854
|
+
if (next) {
|
|
9855
|
+
next.position.set(this.x * 256, this.y * 256, this.z * 256);
|
|
9856
|
+
this.scene.add(next);
|
|
9857
|
+
}
|
|
9858
|
+
this.scene.dirty = true;
|
|
9859
|
+
this.meshDirty = false;
|
|
9860
|
+
}
|
|
9615
9861
|
async clear(onBlocksChanged = this.onBlocksChanged) {
|
|
9616
9862
|
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
9617
|
-
new
|
|
9863
|
+
new Vector313(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
9618
9864
|
));
|
|
9619
|
-
for (const info of this.renderedBlocks.values()) info.object
|
|
9865
|
+
for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
|
|
9866
|
+
this.sectionBlocks.clear();
|
|
9867
|
+
this.sectionMesh?.dispose();
|
|
9868
|
+
this.sectionMesh = void 0;
|
|
9869
|
+
this.meshDirty = false;
|
|
9620
9870
|
this.renderedBlocks.clear();
|
|
9621
9871
|
this.data.clear();
|
|
9622
9872
|
await onBlocksChanged?.(positions);
|
|
@@ -9634,14 +9884,14 @@ var Chunk = class _Chunk {
|
|
|
9634
9884
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
9635
9885
|
}
|
|
9636
9886
|
worldPosToChunkPos(pos) {
|
|
9637
|
-
return new
|
|
9887
|
+
return new Vector313(
|
|
9638
9888
|
pos.x - this.x * 16,
|
|
9639
9889
|
pos.y - this.y * 16,
|
|
9640
9890
|
pos.z - this.z * 16
|
|
9641
9891
|
);
|
|
9642
9892
|
}
|
|
9643
9893
|
chunkPosToWorldPos(pos) {
|
|
9644
|
-
return new
|
|
9894
|
+
return new Vector313(
|
|
9645
9895
|
this.x * 16 + pos.x,
|
|
9646
9896
|
this.y * 16 + pos.y,
|
|
9647
9897
|
this.z * 16 + pos.z
|
|
@@ -9664,6 +9914,7 @@ export {
|
|
|
9664
9914
|
BasicAssetKey,
|
|
9665
9915
|
BatchedExecutor,
|
|
9666
9916
|
BlockObject,
|
|
9917
|
+
BlockStateResolver,
|
|
9667
9918
|
BlockStates,
|
|
9668
9919
|
BlockTints,
|
|
9669
9920
|
BrowserArchiveProxy,
|
|
@@ -9722,6 +9973,8 @@ export {
|
|
|
9722
9973
|
SceneStats,
|
|
9723
9974
|
SceneStatsDisplay,
|
|
9724
9975
|
SchematicParser,
|
|
9976
|
+
SectionMesh,
|
|
9977
|
+
SectionModels,
|
|
9725
9978
|
SkinImage,
|
|
9726
9979
|
SkinObject,
|
|
9727
9980
|
SkinPart,
|