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/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 p10 in s) if (Object.prototype.hasOwnProperty.call(s, p10))
|
|
36
|
+
t[p10] = s[p10];
|
|
37
37
|
}
|
|
38
38
|
return t;
|
|
39
39
|
};
|
|
@@ -770,11 +770,11 @@ var ImageLoader = class _ImageLoader {
|
|
|
770
770
|
static async loadCanvasData(src) {
|
|
771
771
|
const keyStr = serializeImageKey({ src });
|
|
772
772
|
const info = this.getInfo(src);
|
|
773
|
-
const
|
|
773
|
+
const cached2 = Caching.rawImageCache.getIfPresent(keyStr);
|
|
774
774
|
try {
|
|
775
775
|
return await this.infoToCanvasData(await info);
|
|
776
776
|
} catch (err) {
|
|
777
|
-
if (
|
|
777
|
+
if (cached2 && Caching.rawImageCache.getIfPresent(keyStr) === cached2) {
|
|
778
778
|
Caching.rawImageCache.invalidate(keyStr);
|
|
779
779
|
}
|
|
780
780
|
throw err;
|
|
@@ -911,8 +911,8 @@ var Textures = class _Textures {
|
|
|
911
911
|
}
|
|
912
912
|
static getImage(key) {
|
|
913
913
|
const keyStr = serializeTextureKey(key);
|
|
914
|
-
const
|
|
915
|
-
if (
|
|
914
|
+
const cached2 = Caching.textureCache.peek(keyStr);
|
|
915
|
+
if (cached2 && TextureLoader.hasFailed(cached2)) {
|
|
916
916
|
Caching.textureCache.invalidate(keyStr);
|
|
917
917
|
}
|
|
918
918
|
return Caching.textureCache.get(keyStr, (k) => {
|
|
@@ -1180,12 +1180,12 @@ var AssetKey = class _AssetKey extends BasicAssetKey {
|
|
|
1180
1180
|
return a.join("/");
|
|
1181
1181
|
}
|
|
1182
1182
|
getFullPath() {
|
|
1183
|
-
let
|
|
1183
|
+
let p10 = [];
|
|
1184
1184
|
if (this.type) {
|
|
1185
|
-
|
|
1185
|
+
p10.push(this.type);
|
|
1186
1186
|
}
|
|
1187
|
-
|
|
1188
|
-
return
|
|
1187
|
+
p10.push(this.path);
|
|
1188
|
+
return p10.join("/");
|
|
1189
1189
|
}
|
|
1190
1190
|
toNamespacedString() {
|
|
1191
1191
|
return this.namespace + ":" + this.getFullPath();
|
|
@@ -1272,7 +1272,7 @@ var ModelMerger = class {
|
|
|
1272
1272
|
merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
|
|
1273
1273
|
}
|
|
1274
1274
|
}
|
|
1275
|
-
merged.hierarchy = models.map((m) => m.parent).filter((
|
|
1275
|
+
merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
|
|
1276
1276
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1277
1277
|
return merged;
|
|
1278
1278
|
}
|
|
@@ -2001,7 +2001,7 @@ var ModelTextures = class {
|
|
|
2001
2001
|
static async get(key) {
|
|
2002
2002
|
const keyStr = key.serialize();
|
|
2003
2003
|
const pending = this.preload(key);
|
|
2004
|
-
const
|
|
2004
|
+
const cached2 = Caching.textureAssetCache.getIfPresent(keyStr);
|
|
2005
2005
|
try {
|
|
2006
2006
|
const asset = await pending;
|
|
2007
2007
|
if (asset) {
|
|
@@ -2009,7 +2009,7 @@ var ModelTextures = class {
|
|
|
2009
2009
|
}
|
|
2010
2010
|
return void 0;
|
|
2011
2011
|
} catch (err) {
|
|
2012
|
-
if (
|
|
2012
|
+
if (cached2 && Caching.textureAssetCache.getIfPresent(keyStr) === cached2) {
|
|
2013
2013
|
Caching.textureAssetCache.invalidate(keyStr);
|
|
2014
2014
|
}
|
|
2015
2015
|
throw err;
|
|
@@ -3902,6 +3902,93 @@ var ModelCulling = class {
|
|
|
3902
3902
|
}
|
|
3903
3903
|
};
|
|
3904
3904
|
|
|
3905
|
+
// src/model/block/BlockStateResolver.ts
|
|
3906
|
+
import { Euler as Euler5 } from "three";
|
|
3907
|
+
function matchesCondition(condition, state) {
|
|
3908
|
+
return Object.entries(condition).every(([key, value]) => {
|
|
3909
|
+
if (Array.isArray(value)) {
|
|
3910
|
+
if (key === "OR") return value.some((child) => matchesCondition(child, state));
|
|
3911
|
+
if (key === "AND") return value.every((child) => matchesCondition(child, state));
|
|
3912
|
+
return false;
|
|
3913
|
+
}
|
|
3914
|
+
return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
|
|
3915
|
+
});
|
|
3916
|
+
}
|
|
3917
|
+
var BlockStateResolver = class {
|
|
3918
|
+
static async defaults(blockState) {
|
|
3919
|
+
const defaults = blockState.key ? await BlockStates.getDefaultState(blockState.key) : void 0;
|
|
3920
|
+
const state = {};
|
|
3921
|
+
if (defaults && Object.keys(defaults).length > 0) {
|
|
3922
|
+
for (const key in defaults) state[key] = defaults[key].default;
|
|
3923
|
+
} else if (blockState.variants) {
|
|
3924
|
+
const variant = Object.keys(blockState.variants)[0];
|
|
3925
|
+
if (variant) {
|
|
3926
|
+
for (const property of variant.split(",")) {
|
|
3927
|
+
const [key, value] = property.split("=");
|
|
3928
|
+
state[key] = value;
|
|
3929
|
+
}
|
|
3930
|
+
}
|
|
3931
|
+
} else if (blockState.multipart) {
|
|
3932
|
+
const condition = blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
|
|
3933
|
+
for (const [key, value] of Object.entries(condition ?? {})) state[key] = value.split("|")[0];
|
|
3934
|
+
}
|
|
3935
|
+
return state;
|
|
3936
|
+
}
|
|
3937
|
+
static select(blockState, state, choose = this.choose) {
|
|
3938
|
+
return this.matching(blockState, state).map(choose);
|
|
3939
|
+
}
|
|
3940
|
+
static matching(blockState, state) {
|
|
3941
|
+
const out = [];
|
|
3942
|
+
if (blockState.variants) {
|
|
3943
|
+
if (Object.keys(blockState.variants).length === 1 && "" in blockState.variants) {
|
|
3944
|
+
out.push(blockState.variants[""]);
|
|
3945
|
+
} else {
|
|
3946
|
+
for (const variantKey in blockState.variants) {
|
|
3947
|
+
const matches = variantKey.split(",").every((property) => {
|
|
3948
|
+
const [key, value] = property.split("=");
|
|
3949
|
+
return `${state[key]}` === `${value}`;
|
|
3950
|
+
});
|
|
3951
|
+
if (matches) out.push(blockState.variants[variantKey]);
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
} else if (blockState.multipart) {
|
|
3955
|
+
for (const part of blockState.multipart) {
|
|
3956
|
+
if (part.apply && (!part.when || matchesCondition(part.when, state))) {
|
|
3957
|
+
out.push(part.apply);
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
return out;
|
|
3962
|
+
}
|
|
3963
|
+
static choose(variants) {
|
|
3964
|
+
if (!Array.isArray(variants)) return variants;
|
|
3965
|
+
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
3966
|
+
const total = variants.reduce((sum, variant) => {
|
|
3967
|
+
const weight = variant.weight ?? 1;
|
|
3968
|
+
if (!Number.isInteger(weight) || weight < 1) {
|
|
3969
|
+
throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
|
|
3970
|
+
}
|
|
3971
|
+
return sum + weight;
|
|
3972
|
+
}, 0);
|
|
3973
|
+
let choice = Math.random() * total;
|
|
3974
|
+
for (const variant of variants) {
|
|
3975
|
+
choice -= variant.weight ?? 1;
|
|
3976
|
+
if (choice < 0) return variant;
|
|
3977
|
+
}
|
|
3978
|
+
return variants[variants.length - 1];
|
|
3979
|
+
}
|
|
3980
|
+
static rotation(variant) {
|
|
3981
|
+
const rotation = new Euler5();
|
|
3982
|
+
if (typeof variant.x !== "undefined") {
|
|
3983
|
+
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
3984
|
+
}
|
|
3985
|
+
if (typeof variant.y !== "undefined") {
|
|
3986
|
+
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
3987
|
+
}
|
|
3988
|
+
return rotation;
|
|
3989
|
+
}
|
|
3990
|
+
};
|
|
3991
|
+
|
|
3905
3992
|
// src/model/block/blockTints.json
|
|
3906
3993
|
var blockTints_default = {
|
|
3907
3994
|
"minecraft:large_fern": { source: "grass" },
|
|
@@ -3988,7 +4075,7 @@ var BlockTints = class {
|
|
|
3988
4075
|
};
|
|
3989
4076
|
|
|
3990
4077
|
// src/model/scene/ModelObject.ts
|
|
3991
|
-
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as
|
|
4078
|
+
import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler6, Matrix4 as Matrix44 } from "three";
|
|
3992
4079
|
|
|
3993
4080
|
// src/three/BufferGeometryUtils.js
|
|
3994
4081
|
import {
|
|
@@ -4582,7 +4669,7 @@ var ModelObject = class _ModelObject extends SceneObject {
|
|
|
4582
4669
|
elGeo.clearGroups();
|
|
4583
4670
|
}
|
|
4584
4671
|
if (this.options.uvLockRotation) {
|
|
4585
|
-
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new
|
|
4672
|
+
UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler6(...this.options.uvLockRotation));
|
|
4586
4673
|
}
|
|
4587
4674
|
if (this.options.tints) {
|
|
4588
4675
|
const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
|
|
@@ -4678,18 +4765,7 @@ function isModelObject(obj) {
|
|
|
4678
4765
|
|
|
4679
4766
|
// src/model/block/scene/BlockObject.ts
|
|
4680
4767
|
var import_ts_deepmerge6 = __toESM(require_dist());
|
|
4681
|
-
import { Euler as
|
|
4682
|
-
var p10 = prefix("BlockObject");
|
|
4683
|
-
function matchesCondition(condition, state) {
|
|
4684
|
-
return Object.entries(condition).every(([key, value]) => {
|
|
4685
|
-
if (Array.isArray(value)) {
|
|
4686
|
-
if (key === "OR") return value.some((child) => matchesCondition(child, state));
|
|
4687
|
-
if (key === "AND") return value.every((child) => matchesCondition(child, state));
|
|
4688
|
-
return false;
|
|
4689
|
-
}
|
|
4690
|
-
return typeof value === "string" && state[key] !== void 0 && value.split("|").includes(`${state[key]}`);
|
|
4691
|
-
});
|
|
4692
|
-
}
|
|
4768
|
+
import { Euler as Euler7, Matrix4 as Matrix45, Quaternion as Quaternion4, Vector3 as Vector38 } from "three";
|
|
4693
4769
|
var BlockObject = class _BlockObject extends SceneObject {
|
|
4694
4770
|
constructor(blockState, options) {
|
|
4695
4771
|
super(options);
|
|
@@ -4713,22 +4789,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4713
4789
|
}
|
|
4714
4790
|
async init() {
|
|
4715
4791
|
if (this.options.applyDefaultState) {
|
|
4716
|
-
|
|
4717
|
-
if (defaultState && Object.keys(defaultState).length > 0) {
|
|
4718
|
-
const state = {};
|
|
4719
|
-
for (let k in defaultState) {
|
|
4720
|
-
state[k] = defaultState[k].default;
|
|
4721
|
-
}
|
|
4722
|
-
this._setState(state);
|
|
4723
|
-
} else {
|
|
4724
|
-
if (this.blockState.variants) {
|
|
4725
|
-
this._setState(Object.keys(this.blockState.variants)[0]);
|
|
4726
|
-
} else if (this.blockState.multipart) {
|
|
4727
|
-
const condition = this.blockState.multipart.map((part) => part.when).find((when) => when !== void 0 && Object.values(when).every((value) => typeof value === "string"));
|
|
4728
|
-
const state = Object.fromEntries(Object.entries(condition ?? {}).map(([key, value]) => [key, value.split("|")[0]]));
|
|
4729
|
-
this._setState(state);
|
|
4730
|
-
}
|
|
4731
|
-
}
|
|
4792
|
+
this._setState(await BlockStateResolver.defaults(this.blockState));
|
|
4732
4793
|
}
|
|
4733
4794
|
if (this.options.initialState !== void 0) this._setState(this.options.initialState);
|
|
4734
4795
|
await this.recreateModels();
|
|
@@ -4771,7 +4832,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4771
4832
|
const scale = new Vector38();
|
|
4772
4833
|
this.getModelMatrix(model).decompose(position, rotation, scale);
|
|
4773
4834
|
if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector38(1, 1, 1)) > 1e-10) return 0;
|
|
4774
|
-
return ModelCulling.toLocalMask(worldMask, new
|
|
4835
|
+
return ModelCulling.toLocalMask(worldMask, new Euler7().setFromQuaternion(rotation));
|
|
4775
4836
|
}
|
|
4776
4837
|
async setCullMask(worldMask) {
|
|
4777
4838
|
worldMask &= 63;
|
|
@@ -4819,39 +4880,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4819
4880
|
return ref;
|
|
4820
4881
|
}
|
|
4821
4882
|
async mapStateToVariant(state) {
|
|
4822
|
-
|
|
4823
|
-
if (this.blockState.variants) {
|
|
4824
|
-
if (Object.keys(this.blockState.variants).length === 1 && "" in this.blockState.variants) {
|
|
4825
|
-
out.push(this.getSingleVariant(this.blockState.variants[""]));
|
|
4826
|
-
} else {
|
|
4827
|
-
for (let variantKey in this.blockState.variants) {
|
|
4828
|
-
const split = variantKey.split(",");
|
|
4829
|
-
let matches = true;
|
|
4830
|
-
for (let s of split) {
|
|
4831
|
-
const [k, v] = s.split("=");
|
|
4832
|
-
if (`${state[k]}` !== `${v}`) {
|
|
4833
|
-
matches = false;
|
|
4834
|
-
break;
|
|
4835
|
-
}
|
|
4836
|
-
}
|
|
4837
|
-
if (matches) {
|
|
4838
|
-
const variants = this.blockState.variants[variantKey];
|
|
4839
|
-
out.push(this.getSingleVariant(variants));
|
|
4840
|
-
}
|
|
4841
|
-
}
|
|
4842
|
-
}
|
|
4843
|
-
} else if (this.blockState.multipart) {
|
|
4844
|
-
for (let part of this.blockState.multipart) {
|
|
4845
|
-
if (!part.apply) {
|
|
4846
|
-
console.debug(p10, "Missing apply for blockState part", part);
|
|
4847
|
-
continue;
|
|
4848
|
-
}
|
|
4849
|
-
if (!part.when || matchesCondition(part.when, state)) {
|
|
4850
|
-
out.push(this.getSingleVariant(part.apply));
|
|
4851
|
-
}
|
|
4852
|
-
}
|
|
4853
|
-
}
|
|
4854
|
-
return out;
|
|
4883
|
+
return BlockStateResolver.select(this.blockState, state, (variants) => this.getSingleVariant(variants));
|
|
4855
4884
|
}
|
|
4856
4885
|
async recreateModels() {
|
|
4857
4886
|
this.clearModels();
|
|
@@ -4862,21 +4891,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4862
4891
|
}
|
|
4863
4892
|
}
|
|
4864
4893
|
getSingleVariant(variants) {
|
|
4865
|
-
|
|
4866
|
-
if (!variants.length) throw new MineRenderError("Blockstate variant arrays must not be empty");
|
|
4867
|
-
const total = variants.reduce((sum, variant) => {
|
|
4868
|
-
const weight = variant.weight ?? 1;
|
|
4869
|
-
if (!Number.isInteger(weight) || weight < 1) {
|
|
4870
|
-
throw new MineRenderError(`Invalid blockstate variant weight: ${weight}`);
|
|
4871
|
-
}
|
|
4872
|
-
return sum + weight;
|
|
4873
|
-
}, 0);
|
|
4874
|
-
let choice = Math.random() * total;
|
|
4875
|
-
for (const variant of variants) {
|
|
4876
|
-
choice -= variant.weight ?? 1;
|
|
4877
|
-
if (choice < 0) return variant;
|
|
4878
|
-
}
|
|
4879
|
-
return variants[variants.length - 1];
|
|
4894
|
+
return BlockStateResolver.choose(variants);
|
|
4880
4895
|
}
|
|
4881
4896
|
// @deprecated
|
|
4882
4897
|
async createAVariant(variants, instanceInfo) {
|
|
@@ -4884,13 +4899,7 @@ var BlockObject = class _BlockObject extends SceneObject {
|
|
|
4884
4899
|
await this.createVariant(variant);
|
|
4885
4900
|
}
|
|
4886
4901
|
async createVariant(variant) {
|
|
4887
|
-
const rotation =
|
|
4888
|
-
if (typeof variant.x !== "undefined") {
|
|
4889
|
-
rotation.x = toRadians(clampRotationDegrees(variant.x));
|
|
4890
|
-
}
|
|
4891
|
-
if (typeof variant.y !== "undefined") {
|
|
4892
|
-
rotation.y = toRadians(clampRotationDegrees(typeof variant.x !== "undefined" ? variant.y : 360 - variant.y));
|
|
4893
|
-
}
|
|
4902
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
4894
4903
|
const modelKey = AssetKey.parse("models", variant.model);
|
|
4895
4904
|
modelKey.root = this.blockState.key?.root;
|
|
4896
4905
|
const model = await Models.getMerged(modelKey);
|
|
@@ -9393,32 +9402,121 @@ var AnvilParser = class {
|
|
|
9393
9402
|
};
|
|
9394
9403
|
|
|
9395
9404
|
// src/world/Chunk.ts
|
|
9405
|
+
import { Vector3 as Vector313 } from "three";
|
|
9406
|
+
|
|
9407
|
+
// src/world/MineRenderWorld.ts
|
|
9396
9408
|
import { Vector3 as Vector312 } from "three";
|
|
9397
9409
|
|
|
9410
|
+
// src/world/SectionModels.ts
|
|
9411
|
+
import { Matrix4 as Matrix46, Vector3 as Vector311 } from "three";
|
|
9412
|
+
var SectionModel = class extends ModelObject {
|
|
9413
|
+
applyTextures() {
|
|
9414
|
+
}
|
|
9415
|
+
};
|
|
9416
|
+
function cached(map, key, load) {
|
|
9417
|
+
let value = map.get(key);
|
|
9418
|
+
if (!value) {
|
|
9419
|
+
value = load().catch((error) => {
|
|
9420
|
+
map.delete(key);
|
|
9421
|
+
throw error;
|
|
9422
|
+
});
|
|
9423
|
+
map.set(key, value);
|
|
9424
|
+
}
|
|
9425
|
+
return value;
|
|
9426
|
+
}
|
|
9427
|
+
var SectionModels = class {
|
|
9428
|
+
constructor(maxAtlasSize = 2048) {
|
|
9429
|
+
this.maxAtlasSize = maxAtlasSize;
|
|
9430
|
+
this.states = /* @__PURE__ */ new WeakMap();
|
|
9431
|
+
this.models = /* @__PURE__ */ new WeakMap();
|
|
9432
|
+
this.templates = /* @__PURE__ */ new Set();
|
|
9433
|
+
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("maxAtlasSize must be a positive integer");
|
|
9434
|
+
}
|
|
9435
|
+
async get(blockState, properties = {}) {
|
|
9436
|
+
if (!blockState.variants || blockState.multipart) return void 0;
|
|
9437
|
+
let states = this.states.get(blockState);
|
|
9438
|
+
if (!states) this.states.set(blockState, states = /* @__PURE__ */ new Map());
|
|
9439
|
+
const key = JSON.stringify(Object.entries(properties).sort(([a], [b]) => a.localeCompare(b)));
|
|
9440
|
+
const prepared = await cached(states, key, () => this.prepare(blockState, properties));
|
|
9441
|
+
if (!prepared) return void 0;
|
|
9442
|
+
return prepared.templates.get(BlockStateResolver.choose(prepared.variants));
|
|
9443
|
+
}
|
|
9444
|
+
async prepare(blockState, properties) {
|
|
9445
|
+
const state = { ...await BlockStateResolver.defaults(blockState), ...properties };
|
|
9446
|
+
const groups = BlockStateResolver.matching(blockState, state);
|
|
9447
|
+
if (groups.length !== 1) return void 0;
|
|
9448
|
+
const variants = groups[0];
|
|
9449
|
+
const choices = Array.isArray(variants) ? variants : [variants];
|
|
9450
|
+
if (!choices.length) return void 0;
|
|
9451
|
+
const templates = /* @__PURE__ */ new Map();
|
|
9452
|
+
for (const variant of choices) {
|
|
9453
|
+
const model = await Models.getMerged(AssetKey.parse("models", variant.model));
|
|
9454
|
+
if (!model) return void 0;
|
|
9455
|
+
const atlas = await UVMapper.getAtlas(model);
|
|
9456
|
+
const rotation = BlockStateResolver.rotation(variant);
|
|
9457
|
+
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;
|
|
9458
|
+
const tints = await BlockTints.get(blockState.key, state, model);
|
|
9459
|
+
let models = this.models.get(model);
|
|
9460
|
+
if (!models) this.models.set(model, models = /* @__PURE__ */ new Map());
|
|
9461
|
+
const key = JSON.stringify([rotation.x, rotation.y, rotation.z, variant.uvlock, tints]);
|
|
9462
|
+
const template = await cached(models, key, async () => {
|
|
9463
|
+
const object = new SectionModel(model, {
|
|
9464
|
+
instanceMeshes: false,
|
|
9465
|
+
mergeMeshes: false,
|
|
9466
|
+
tints,
|
|
9467
|
+
uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
|
|
9468
|
+
});
|
|
9469
|
+
await object.init();
|
|
9470
|
+
const geometry = object.children[0].geometry;
|
|
9471
|
+
geometry.applyMatrix4(new Matrix46().makeRotationFromEuler(rotation));
|
|
9472
|
+
object.clear();
|
|
9473
|
+
const cullFaces = CUBE_FACES.map((face) => {
|
|
9474
|
+
const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
|
|
9475
|
+
if (local < 0) return 0;
|
|
9476
|
+
const normal = new Vector311(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
|
|
9477
|
+
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);
|
|
9478
|
+
return 1 << world;
|
|
9479
|
+
});
|
|
9480
|
+
const template2 = { geometry, atlas, cullFaces };
|
|
9481
|
+
this.templates.add(template2);
|
|
9482
|
+
return template2;
|
|
9483
|
+
});
|
|
9484
|
+
templates.set(variant, template);
|
|
9485
|
+
}
|
|
9486
|
+
return { variants, templates };
|
|
9487
|
+
}
|
|
9488
|
+
clear() {
|
|
9489
|
+
for (const template of this.templates) template.geometry.dispose();
|
|
9490
|
+
this.templates.clear();
|
|
9491
|
+
this.states = /* @__PURE__ */ new WeakMap();
|
|
9492
|
+
this.models = /* @__PURE__ */ new WeakMap();
|
|
9493
|
+
}
|
|
9494
|
+
};
|
|
9495
|
+
|
|
9398
9496
|
// src/world/MineRenderWorld.ts
|
|
9399
|
-
import { Vector3 as Vector311 } from "three";
|
|
9400
9497
|
var MineRenderWorld = class {
|
|
9401
|
-
constructor(scene) {
|
|
9498
|
+
constructor(scene, options = {}) {
|
|
9402
9499
|
this._chunks = /* @__PURE__ */ new Map();
|
|
9403
9500
|
this.pendingCulling = /* @__PURE__ */ new Map();
|
|
9404
9501
|
this.scene = scene;
|
|
9502
|
+
if (options.sectionMeshing) this.sectionModels = new SectionModels(options.maxAtlasSize);
|
|
9405
9503
|
}
|
|
9406
9504
|
getBlockAt(posOrX, y, z) {
|
|
9407
9505
|
if (typeof posOrX == "number") {
|
|
9408
|
-
return this.getBlockAt(new
|
|
9506
|
+
return this.getBlockAt(new Vector312(posOrX, y, z));
|
|
9409
9507
|
}
|
|
9410
9508
|
if (isTripleArray(posOrX)) {
|
|
9411
|
-
return this.getBlockAt(new
|
|
9509
|
+
return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
|
|
9412
9510
|
}
|
|
9413
9511
|
this.validatePosBounds(posOrX);
|
|
9414
9512
|
return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
|
|
9415
9513
|
}
|
|
9416
9514
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
9417
9515
|
if (typeof posOrX == "number") {
|
|
9418
|
-
return this.setBlockAt(new
|
|
9516
|
+
return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
|
|
9419
9517
|
}
|
|
9420
9518
|
if (isTripleArray(posOrX)) {
|
|
9421
|
-
return this.setBlockAt(new
|
|
9519
|
+
return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
9422
9520
|
}
|
|
9423
9521
|
return this.placeBlock(posOrX, yOrBlock);
|
|
9424
9522
|
}
|
|
@@ -9439,7 +9537,7 @@ var MineRenderWorld = class {
|
|
|
9439
9537
|
const collect = async (positions2) => {
|
|
9440
9538
|
for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
|
|
9441
9539
|
};
|
|
9442
|
-
const place = (block) => this.placeBlock(new
|
|
9540
|
+
const place = (block) => this.placeBlock(new Vector312(...block.position), block, collect);
|
|
9443
9541
|
const keys = /* @__PURE__ */ new Map();
|
|
9444
9542
|
for (const block of multiblock.blocks) {
|
|
9445
9543
|
if (Chunk.isAir(block)) continue;
|
|
@@ -9511,12 +9609,13 @@ var MineRenderWorld = class {
|
|
|
9511
9609
|
for (const chunk of chunks) {
|
|
9512
9610
|
await chunk.dispose();
|
|
9513
9611
|
}
|
|
9612
|
+
this.sectionModels?.clear();
|
|
9514
9613
|
}
|
|
9515
9614
|
updateCulling(positions) {
|
|
9516
9615
|
for (const pos of positions) {
|
|
9517
9616
|
this.pendingCulling.set(pos.toArray().join(","), pos.clone());
|
|
9518
9617
|
for (const offset of CUBE_FACE_OFFSETS) {
|
|
9519
|
-
const neighbor = pos.clone().add(new
|
|
9618
|
+
const neighbor = pos.clone().add(new Vector312(...offset));
|
|
9520
9619
|
this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
|
|
9521
9620
|
}
|
|
9522
9621
|
}
|
|
@@ -9525,17 +9624,22 @@ var MineRenderWorld = class {
|
|
|
9525
9624
|
while (this.pendingCulling.size) {
|
|
9526
9625
|
const batch = [...this.pendingCulling.values()];
|
|
9527
9626
|
this.pendingCulling.clear();
|
|
9627
|
+
const changed = /* @__PURE__ */ new Set();
|
|
9528
9628
|
for (const pos of batch) {
|
|
9529
|
-
const
|
|
9530
|
-
if (!
|
|
9629
|
+
const chunk = this.getChunkAt(pos);
|
|
9630
|
+
if (!chunk) continue;
|
|
9631
|
+
changed.add(chunk);
|
|
9632
|
+
if (!chunk.getBlockAt(pos)) continue;
|
|
9531
9633
|
let mask = 0;
|
|
9532
9634
|
for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
|
|
9533
|
-
|
|
9635
|
+
const neighbor = pos.clone().add(new Vector312(...offset));
|
|
9636
|
+
if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
|
|
9534
9637
|
mask |= 1 << face;
|
|
9535
9638
|
}
|
|
9536
9639
|
}
|
|
9537
|
-
await
|
|
9640
|
+
await chunk.setCullMaskAt(pos, mask);
|
|
9538
9641
|
}
|
|
9642
|
+
for (const chunk of changed) chunk.rebuildSectionMesh();
|
|
9539
9643
|
}
|
|
9540
9644
|
} finally {
|
|
9541
9645
|
this.culling = void 0;
|
|
@@ -9551,7 +9655,8 @@ var MineRenderWorld = class {
|
|
|
9551
9655
|
Math.floor(pos.x / 16),
|
|
9552
9656
|
Math.floor(pos.y / 16),
|
|
9553
9657
|
Math.floor(pos.z / 16),
|
|
9554
|
-
(positions) => this.updateCulling(positions)
|
|
9658
|
+
(positions) => this.updateCulling(positions),
|
|
9659
|
+
this.sectionModels
|
|
9555
9660
|
);
|
|
9556
9661
|
this._chunks.set(key, chunk);
|
|
9557
9662
|
}
|
|
@@ -9561,14 +9666,14 @@ var MineRenderWorld = class {
|
|
|
9561
9666
|
return this._chunks.get(this.worldPosToChunkKey(pos));
|
|
9562
9667
|
}
|
|
9563
9668
|
static worldToScenePosition(pos) {
|
|
9564
|
-
return new
|
|
9669
|
+
return new Vector312(
|
|
9565
9670
|
pos.x * 16,
|
|
9566
9671
|
pos.y * 16,
|
|
9567
9672
|
pos.z * 16
|
|
9568
9673
|
);
|
|
9569
9674
|
}
|
|
9570
9675
|
static sceneToWorldPosition(pos) {
|
|
9571
|
-
return new
|
|
9676
|
+
return new Vector312(
|
|
9572
9677
|
pos.x / 16,
|
|
9573
9678
|
pos.y / 16,
|
|
9574
9679
|
pos.z / 16
|
|
@@ -9587,12 +9692,118 @@ var MineRenderWorld = class {
|
|
|
9587
9692
|
}
|
|
9588
9693
|
};
|
|
9589
9694
|
|
|
9695
|
+
// src/world/SectionMesh.ts
|
|
9696
|
+
import { BufferGeometry as BufferGeometry2, Float32BufferAttribute as Float32BufferAttribute4, Group, Mesh as Mesh7 } from "three";
|
|
9697
|
+
var SectionMesh = class _SectionMesh extends Group {
|
|
9698
|
+
constructor() {
|
|
9699
|
+
super(...arguments);
|
|
9700
|
+
this.ownedMeshes = [];
|
|
9701
|
+
}
|
|
9702
|
+
static build(entries, maxAtlasSize = 2048) {
|
|
9703
|
+
if (!Number.isInteger(maxAtlasSize) || maxAtlasSize < 1) throw new RangeError("Section atlas size must be a positive integer");
|
|
9704
|
+
const visible = entries.filter((entry) => entry.template.cullFaces.some((direction) => !(entry.cullMask & direction)));
|
|
9705
|
+
const atlases = [...new Set(visible.map((entry) => entry.template.atlas))].sort((a, b) => b.image.height - a.image.height);
|
|
9706
|
+
const pages = [];
|
|
9707
|
+
const locations = /* @__PURE__ */ new Map();
|
|
9708
|
+
for (const atlas of atlases) {
|
|
9709
|
+
const { width, height } = atlas.image;
|
|
9710
|
+
if (width > maxAtlasSize || height > maxAtlasSize) throw new RangeError("Model atlas exceeds the section atlas size limit");
|
|
9711
|
+
let selected;
|
|
9712
|
+
for (const page of pages) {
|
|
9713
|
+
const nextRow = page.x + width > maxAtlasSize;
|
|
9714
|
+
if ((nextRow ? page.y + page.rowHeight : page.y) + height > maxAtlasSize) continue;
|
|
9715
|
+
if (nextRow) {
|
|
9716
|
+
page.y += page.rowHeight;
|
|
9717
|
+
page.x = 0;
|
|
9718
|
+
page.rowHeight = 0;
|
|
9719
|
+
}
|
|
9720
|
+
selected = page;
|
|
9721
|
+
break;
|
|
9722
|
+
}
|
|
9723
|
+
if (!selected) {
|
|
9724
|
+
selected = { placements: [], entries: [], x: 0, y: 0, rowHeight: 0, width: 0, height: 0 };
|
|
9725
|
+
pages.push(selected);
|
|
9726
|
+
}
|
|
9727
|
+
const placement = { atlas, x: selected.x, y: selected.y };
|
|
9728
|
+
selected.placements.push(placement);
|
|
9729
|
+
selected.x += width;
|
|
9730
|
+
selected.rowHeight = Math.max(selected.rowHeight, height);
|
|
9731
|
+
selected.width = Math.max(selected.width, selected.x);
|
|
9732
|
+
selected.height = Math.max(selected.height, selected.y + height);
|
|
9733
|
+
locations.set(atlas, { page: selected, placement });
|
|
9734
|
+
}
|
|
9735
|
+
for (const entry of visible) locations.get(entry.template.atlas).page.entries.push(entry);
|
|
9736
|
+
const section = new _SectionMesh();
|
|
9737
|
+
for (const page of pages) {
|
|
9738
|
+
const canvas = createCanvas2(page.width, page.height);
|
|
9739
|
+
const context = canvas.getContext("2d");
|
|
9740
|
+
for (const { atlas, x, y } of page.placements) {
|
|
9741
|
+
context.drawImage(atlas.image.canvas, x, y);
|
|
9742
|
+
}
|
|
9743
|
+
const positions = [], normals = [], uvs = [], colors = [], indices = [];
|
|
9744
|
+
for (const { index, template, cullMask } of page.entries) {
|
|
9745
|
+
const position = template.geometry.getAttribute("position");
|
|
9746
|
+
const normal = template.geometry.getAttribute("normal");
|
|
9747
|
+
const uv = template.geometry.getAttribute("uv");
|
|
9748
|
+
const color = template.geometry.getAttribute("color");
|
|
9749
|
+
const sourceIndices = template.geometry.getIndex();
|
|
9750
|
+
const placement = locations.get(template.atlas).placement;
|
|
9751
|
+
const offsetX = index % 16 * 16;
|
|
9752
|
+
const offsetY = Math.floor(index / 256) * 16;
|
|
9753
|
+
const offsetZ = Math.floor(index / 16) % 16 * 16;
|
|
9754
|
+
for (let face = 0; face < 6; face++) {
|
|
9755
|
+
if (cullMask & template.cullFaces[face]) continue;
|
|
9756
|
+
const start = positions.length / 3;
|
|
9757
|
+
for (let corner = 0; corner < 4; corner++) {
|
|
9758
|
+
const vertex = face * 4 + corner;
|
|
9759
|
+
positions.push(position.getX(vertex) + offsetX, position.getY(vertex) + offsetY, position.getZ(vertex) + offsetZ);
|
|
9760
|
+
normals.push(normal.getX(vertex), normal.getY(vertex), normal.getZ(vertex));
|
|
9761
|
+
uvs.push(
|
|
9762
|
+
(placement.x + uv.getX(vertex) * template.atlas.image.width) / page.width,
|
|
9763
|
+
1 - (placement.y + (1 - uv.getY(vertex)) * template.atlas.image.height) / page.height
|
|
9764
|
+
);
|
|
9765
|
+
colors.push(color?.getX(vertex) ?? 1, color?.getY(vertex) ?? 1, color?.getZ(vertex) ?? 1);
|
|
9766
|
+
}
|
|
9767
|
+
for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
|
|
9768
|
+
}
|
|
9769
|
+
}
|
|
9770
|
+
const geometry = new BufferGeometry2();
|
|
9771
|
+
geometry.setAttribute("position", new Float32BufferAttribute4(positions, 3));
|
|
9772
|
+
geometry.setAttribute("normal", new Float32BufferAttribute4(normals, 3));
|
|
9773
|
+
geometry.setAttribute("uv", new Float32BufferAttribute4(uvs, 2));
|
|
9774
|
+
geometry.setAttribute("color", new Float32BufferAttribute4(colors, 3));
|
|
9775
|
+
geometry.setIndex(indices);
|
|
9776
|
+
geometry.computeBoundingBox();
|
|
9777
|
+
geometry.computeBoundingSphere();
|
|
9778
|
+
const material = Materials.createShadedCanvasMaterial(canvas, false);
|
|
9779
|
+
material.vertexColors = true;
|
|
9780
|
+
const texture = material.uniforms?.map?.value ?? material.map;
|
|
9781
|
+
const mesh = new Mesh7(geometry, material);
|
|
9782
|
+
section.add(mesh);
|
|
9783
|
+
section.ownedMeshes.push({ mesh, texture });
|
|
9784
|
+
}
|
|
9785
|
+
return section;
|
|
9786
|
+
}
|
|
9787
|
+
dispose() {
|
|
9788
|
+
for (const { mesh, texture } of this.ownedMeshes.splice(0)) {
|
|
9789
|
+
mesh.removeFromParent();
|
|
9790
|
+
mesh.geometry.dispose();
|
|
9791
|
+
mesh.material.dispose();
|
|
9792
|
+
texture?.dispose();
|
|
9793
|
+
}
|
|
9794
|
+
this.removeFromParent();
|
|
9795
|
+
}
|
|
9796
|
+
};
|
|
9797
|
+
|
|
9590
9798
|
// src/world/Chunk.ts
|
|
9591
9799
|
var Chunk = class _Chunk {
|
|
9592
|
-
constructor(scene, x, y, z, onBlocksChanged) {
|
|
9800
|
+
constructor(scene, x, y, z, onBlocksChanged, sectionModels) {
|
|
9593
9801
|
this.onBlocksChanged = onBlocksChanged;
|
|
9802
|
+
this.sectionModels = sectionModels;
|
|
9594
9803
|
this.data = new ChunkData();
|
|
9595
9804
|
this.renderedBlocks = /* @__PURE__ */ new Map();
|
|
9805
|
+
this.sectionBlocks = /* @__PURE__ */ new Map();
|
|
9806
|
+
this.meshDirty = false;
|
|
9596
9807
|
this.scene = scene;
|
|
9597
9808
|
this.x = x;
|
|
9598
9809
|
this.y = y;
|
|
@@ -9600,10 +9811,10 @@ var Chunk = class _Chunk {
|
|
|
9600
9811
|
}
|
|
9601
9812
|
getBlockAt(posOrX, y, z) {
|
|
9602
9813
|
if (typeof posOrX == "number") {
|
|
9603
|
-
return this.getBlockAt(new
|
|
9814
|
+
return this.getBlockAt(new Vector313(posOrX, y, z));
|
|
9604
9815
|
}
|
|
9605
9816
|
if (isTripleArray(posOrX)) {
|
|
9606
|
-
return this.getBlockAt(new
|
|
9817
|
+
return this.getBlockAt(new Vector313(posOrX[0], posOrX[1], posOrX[2]));
|
|
9607
9818
|
}
|
|
9608
9819
|
const pos = this.worldPosToChunkPos(posOrX);
|
|
9609
9820
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
@@ -9611,10 +9822,10 @@ var Chunk = class _Chunk {
|
|
|
9611
9822
|
}
|
|
9612
9823
|
async setBlockAt(posOrX, yOrBlock, z, block) {
|
|
9613
9824
|
if (typeof posOrX == "number") {
|
|
9614
|
-
return this.setBlockAt(new
|
|
9825
|
+
return this.setBlockAt(new Vector313(posOrX, yOrBlock, z), block);
|
|
9615
9826
|
}
|
|
9616
9827
|
if (isTripleArray(posOrX)) {
|
|
9617
|
-
return this.setBlockAt(new
|
|
9828
|
+
return this.setBlockAt(new Vector313(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
|
|
9618
9829
|
}
|
|
9619
9830
|
const worldPos = posOrX;
|
|
9620
9831
|
const pos = this.worldPosToChunkPos(worldPos);
|
|
@@ -9631,7 +9842,8 @@ var Chunk = class _Chunk {
|
|
|
9631
9842
|
const index = _Chunk.chunkPosToBlockIndex(pos);
|
|
9632
9843
|
this.data.set(index, block);
|
|
9633
9844
|
const readBlock = this.data.snapshot(index);
|
|
9634
|
-
this.renderedBlocks.get(index)?.object
|
|
9845
|
+
this.renderedBlocks.get(index)?.object?.removeFromScene();
|
|
9846
|
+
if (this.sectionBlocks.delete(index)) this.meshDirty = true;
|
|
9635
9847
|
this.renderedBlocks.delete(index);
|
|
9636
9848
|
let object;
|
|
9637
9849
|
try {
|
|
@@ -9642,13 +9854,19 @@ var Chunk = class _Chunk {
|
|
|
9642
9854
|
this.data.set(index, void 0);
|
|
9643
9855
|
return void 0;
|
|
9644
9856
|
}
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
|
|
9650
|
-
|
|
9651
|
-
|
|
9857
|
+
const template = await this.sectionModels?.get(blockState, stored.properties);
|
|
9858
|
+
if (template) {
|
|
9859
|
+
this.sectionBlocks.set(index, { index, template, cullMask: 0 });
|
|
9860
|
+
this.meshDirty = true;
|
|
9861
|
+
} else {
|
|
9862
|
+
object = await this.scene.addBlock(blockState, {
|
|
9863
|
+
mergeMeshes: true,
|
|
9864
|
+
instanceMeshes: true,
|
|
9865
|
+
maxInstanceCount: 2e3,
|
|
9866
|
+
initialState: stored.properties
|
|
9867
|
+
});
|
|
9868
|
+
object.setPosition(MineRenderWorld.worldToScenePosition(worldPos));
|
|
9869
|
+
}
|
|
9652
9870
|
const info = { get block() {
|
|
9653
9871
|
return readBlock();
|
|
9654
9872
|
}, object };
|
|
@@ -9662,11 +9880,43 @@ var Chunk = class _Chunk {
|
|
|
9662
9880
|
await onBlocksChanged?.([worldPos]);
|
|
9663
9881
|
}
|
|
9664
9882
|
}
|
|
9883
|
+
isOccludingAt(pos) {
|
|
9884
|
+
const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
|
|
9885
|
+
return this.sectionBlocks.has(index) || (this.renderedBlocks.get(index)?.object?.isOccluding ?? false);
|
|
9886
|
+
}
|
|
9887
|
+
async setCullMaskAt(pos, mask) {
|
|
9888
|
+
const index = _Chunk.chunkPosToBlockIndex(this.worldPosToChunkPos(pos));
|
|
9889
|
+
const entry = this.sectionBlocks.get(index);
|
|
9890
|
+
if (entry) {
|
|
9891
|
+
if (entry.cullMask !== mask) {
|
|
9892
|
+
entry.cullMask = mask;
|
|
9893
|
+
this.meshDirty = true;
|
|
9894
|
+
}
|
|
9895
|
+
} else {
|
|
9896
|
+
await this.renderedBlocks.get(index)?.object?.setCullMask(mask);
|
|
9897
|
+
}
|
|
9898
|
+
}
|
|
9899
|
+
rebuildSectionMesh() {
|
|
9900
|
+
if (!this.meshDirty) return;
|
|
9901
|
+
const next = this.sectionBlocks.size ? SectionMesh.build([...this.sectionBlocks.values()], this.sectionModels.maxAtlasSize) : void 0;
|
|
9902
|
+
this.sectionMesh?.dispose();
|
|
9903
|
+
this.sectionMesh = next;
|
|
9904
|
+
if (next) {
|
|
9905
|
+
next.position.set(this.x * 256, this.y * 256, this.z * 256);
|
|
9906
|
+
this.scene.add(next);
|
|
9907
|
+
}
|
|
9908
|
+
this.scene.dirty = true;
|
|
9909
|
+
this.meshDirty = false;
|
|
9910
|
+
}
|
|
9665
9911
|
async clear(onBlocksChanged = this.onBlocksChanged) {
|
|
9666
9912
|
const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
|
|
9667
|
-
new
|
|
9913
|
+
new Vector313(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
|
|
9668
9914
|
));
|
|
9669
|
-
for (const info of this.renderedBlocks.values()) info.object
|
|
9915
|
+
for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
|
|
9916
|
+
this.sectionBlocks.clear();
|
|
9917
|
+
this.sectionMesh?.dispose();
|
|
9918
|
+
this.sectionMesh = void 0;
|
|
9919
|
+
this.meshDirty = false;
|
|
9670
9920
|
this.renderedBlocks.clear();
|
|
9671
9921
|
this.data.clear();
|
|
9672
9922
|
await onBlocksChanged?.(positions);
|
|
@@ -9684,14 +9934,14 @@ var Chunk = class _Chunk {
|
|
|
9684
9934
|
return pos.y * 16 * 16 + pos.z * 16 + pos.x;
|
|
9685
9935
|
}
|
|
9686
9936
|
worldPosToChunkPos(pos) {
|
|
9687
|
-
return new
|
|
9937
|
+
return new Vector313(
|
|
9688
9938
|
pos.x - this.x * 16,
|
|
9689
9939
|
pos.y - this.y * 16,
|
|
9690
9940
|
pos.z - this.z * 16
|
|
9691
9941
|
);
|
|
9692
9942
|
}
|
|
9693
9943
|
chunkPosToWorldPos(pos) {
|
|
9694
|
-
return new
|
|
9944
|
+
return new Vector313(
|
|
9695
9945
|
this.x * 16 + pos.x,
|
|
9696
9946
|
this.y * 16 + pos.y,
|
|
9697
9947
|
this.z * 16 + pos.z
|
|
@@ -9714,6 +9964,7 @@ export {
|
|
|
9714
9964
|
BasicAssetKey,
|
|
9715
9965
|
BatchedExecutor,
|
|
9716
9966
|
BlockObject,
|
|
9967
|
+
BlockStateResolver,
|
|
9717
9968
|
BlockStates,
|
|
9718
9969
|
BlockTints,
|
|
9719
9970
|
BrowserArchiveProxy,
|
|
@@ -9772,6 +10023,8 @@ export {
|
|
|
9772
10023
|
SceneStats,
|
|
9773
10024
|
SceneStatsDisplay,
|
|
9774
10025
|
SchematicParser,
|
|
10026
|
+
SectionMesh,
|
|
10027
|
+
SectionModels,
|
|
9775
10028
|
SkinImage,
|
|
9776
10029
|
SkinObject,
|
|
9777
10030
|
SkinPart,
|