minerender 2.1.0-alpha.59 → 2.1.0-alpha.60

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/bundle.js CHANGED
@@ -33399,6 +33399,29 @@ var MineRender = (() => {
33399
33399
  }
33400
33400
  });
33401
33401
 
33402
+ // src/model/Model.ts
33403
+ function isDoubleArray(obj) {
33404
+ return Array.isArray(obj) && obj.length === 2;
33405
+ }
33406
+ function isTripleArray(obj) {
33407
+ return Array.isArray(obj) && obj.length === 3;
33408
+ }
33409
+ function isQuadArray(obj) {
33410
+ return Array.isArray(obj) && obj.length === 4;
33411
+ }
33412
+ var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
33413
+ var init_Model = __esm({
33414
+ "src/model/Model.ts"() {
33415
+ init_dirname();
33416
+ init_buffer2();
33417
+ init_process2();
33418
+ ITEM_GENERATED = "item/generated";
33419
+ BUILTIN_GENERATED = "builtin/generated";
33420
+ BUILTIN_ENTITY = "builtin/entity";
33421
+ DEFAULT_ELEMENTS = [];
33422
+ }
33423
+ });
33424
+
33402
33425
  // ../../node_modules/ts-deepmerge/dist/index.js
33403
33426
  var require_dist = __commonJS({
33404
33427
  "../../node_modules/ts-deepmerge/dist/index.js"(exports13) {
@@ -33672,6 +33695,7 @@ var MineRender = (() => {
33672
33695
  init_dirname();
33673
33696
  init_buffer2();
33674
33697
  init_process2();
33698
+ init_Model();
33675
33699
  init_Models();
33676
33700
  import_ts_deepmerge = __toESM(require_dist());
33677
33701
  init_AssetKey();
@@ -33697,6 +33721,7 @@ var MineRender = (() => {
33697
33721
  }
33698
33722
  const models = [];
33699
33723
  const parentKey = AssetKey.parse("models", model.parent);
33724
+ if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
33700
33725
  parentKey.root = model.key?.root;
33701
33726
  const parentModel = await Models.getRaw(parentKey);
33702
33727
  if (parentModel) {
@@ -33769,12 +33794,12 @@ var MineRender = (() => {
33769
33794
  const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
33770
33795
  if (!result) return void 0;
33771
33796
  if (result.key.assetType !== "items") return { ...result.asset, key };
33772
- const reference = this.defaultItemModel(result.asset.model, key);
33773
- const modelKey = AssetKey.parse("models", reference);
33797
+ const selected = this.defaultItemModel(result.asset.model, key);
33798
+ const modelKey = AssetKey.parse("models", selected.model);
33774
33799
  modelKey.root = key.root;
33775
33800
  const model2 = await this.getRaw(modelKey);
33776
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
33777
- return model2;
33801
+ if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
33802
+ return selected.special ? { ...model2, special: selected.special } : model2;
33778
33803
  });
33779
33804
  return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
33780
33805
  }
@@ -33785,8 +33810,25 @@ var MineRender = (() => {
33785
33810
  }
33786
33811
  switch (node.type.replace(/^minecraft:/, "")) {
33787
33812
  case "model":
33788
- if (typeof node.model === "string" && node.model) return node.model;
33813
+ if (typeof node.model === "string" && node.model) return { model: node.model };
33789
33814
  break;
33815
+ case "special": {
33816
+ if (!node.base || !node.model || typeof node.model !== "object") break;
33817
+ const special = node.model;
33818
+ switch (special.type) {
33819
+ case "chest":
33820
+ case "minecraft:chest":
33821
+ case "bed":
33822
+ case "minecraft:bed":
33823
+ if (typeof special.texture === "string" && special.texture) return { model: node.base, special };
33824
+ break;
33825
+ case "head":
33826
+ case "minecraft:head":
33827
+ if (typeof special.kind === "string" && special.kind) return { model: node.base, special };
33828
+ break;
33829
+ }
33830
+ throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);
33831
+ }
33790
33832
  case "condition":
33791
33833
  return this.defaultItemModel(node.on_false, key);
33792
33834
  case "select": {
@@ -78687,6 +78729,105 @@ ${key}` : key;
78687
78729
  }
78688
78730
  });
78689
78731
 
78732
+ // src/MinecraftCubeTexture.ts
78733
+ var MinecraftCubeTexture;
78734
+ var init_MinecraftCubeTexture = __esm({
78735
+ "src/MinecraftCubeTexture.ts"() {
78736
+ init_dirname();
78737
+ init_buffer2();
78738
+ init_process2();
78739
+ init_UVMapper();
78740
+ init_CubeFace();
78741
+ MinecraftCubeTexture = class {
78742
+ constructor(u4, v5, width, height) {
78743
+ this.u = u4;
78744
+ this.v = v5;
78745
+ this.width = width;
78746
+ this.height = height;
78747
+ }
78748
+ mapW(x4) {
78749
+ return x4 / this.width;
78750
+ }
78751
+ mapH(x4) {
78752
+ return 1 - x4 / this.height;
78753
+ }
78754
+ getUvEast(w4, h5, l4) {
78755
+ return [
78756
+ [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4 + h5)],
78757
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4 + h5)],
78758
+ [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4)],
78759
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)]
78760
+ ];
78761
+ }
78762
+ getUvWest(w4, h5, l4) {
78763
+ return [
78764
+ [this.mapW(this.u + l4), this.mapH(this.v + l4 + h5)],
78765
+ [this.mapW(this.u), this.mapH(this.v + l4 + h5)],
78766
+ [this.mapW(this.u + l4), this.mapH(this.v + l4)],
78767
+ [this.mapW(this.u), this.mapH(this.v + l4)]
78768
+ ];
78769
+ }
78770
+ getUvUp(w4, h5, l4) {
78771
+ return [
78772
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)],
78773
+ [this.mapW(this.u + l4 + w4 + w4), this.mapH(this.v + l4)],
78774
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v)],
78775
+ [this.mapW(this.u + l4 + w4 + w4), this.mapH(this.v)]
78776
+ ];
78777
+ }
78778
+ getUvDown(w4, h5, l4) {
78779
+ return [
78780
+ [this.mapW(this.u + l4), this.mapH(this.v)],
78781
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v)],
78782
+ [this.mapW(this.u + l4), this.mapH(this.v + l4)],
78783
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)]
78784
+ ];
78785
+ }
78786
+ getUvSouth(w4, h5, l4) {
78787
+ return [
78788
+ [this.mapW(this.u + l4 + w4 + l4 + w4), this.mapH(this.v + l4 + h5)],
78789
+ [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4 + h5)],
78790
+ [this.mapW(this.u + l4 + w4 + l4 + w4), this.mapH(this.v + l4)],
78791
+ [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4)]
78792
+ ];
78793
+ }
78794
+ getUvNorth(w4, h5, l4) {
78795
+ return [
78796
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4 + h5)],
78797
+ [this.mapW(this.u + l4), this.mapH(this.v + l4 + h5)],
78798
+ [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)],
78799
+ [this.mapW(this.u + l4), this.mapH(this.v + l4)]
78800
+ ];
78801
+ }
78802
+ getFaceUv(face, w4, h5, l4) {
78803
+ switch (face) {
78804
+ case "east" /* EAST */:
78805
+ return this.getUvEast(w4, h5, l4);
78806
+ case "west" /* WEST */:
78807
+ return this.getUvWest(w4, h5, l4);
78808
+ case "up" /* UP */:
78809
+ return this.getUvUp(w4, h5, l4);
78810
+ case "down" /* DOWN */:
78811
+ return this.getUvDown(w4, h5, l4);
78812
+ case "south" /* SOUTH */:
78813
+ return this.getUvSouth(w4, h5, l4);
78814
+ case "north" /* NORTH */:
78815
+ return this.getUvNorth(w4, h5, l4);
78816
+ }
78817
+ }
78818
+ toUvArray(w4, h5, l4, mirror = false) {
78819
+ const uv = [];
78820
+ for (let i4 = 0; i4 < CUBE_FACES.length; i4++) {
78821
+ const face = mirror && i4 < 2 ? CUBE_FACES[1 - i4] : CUBE_FACES[i4];
78822
+ const corners = this.getFaceUv(face, w4, h5, l4);
78823
+ UVMapper.setFaceUvInArray(uv, i4 * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
78824
+ }
78825
+ return uv;
78826
+ }
78827
+ };
78828
+ }
78829
+ });
78830
+
78690
78831
  // src/error/MineRenderError.ts
78691
78832
  var MineRenderError;
78692
78833
  var init_MineRenderError = __esm({
@@ -78706,6 +78847,257 @@ ${key}` : key;
78706
78847
  }
78707
78848
  });
78708
78849
 
78850
+ // src/assets/Entities.ts
78851
+ var Entities;
78852
+ var init_Entities = __esm({
78853
+ "src/assets/Entities.ts"() {
78854
+ init_dirname();
78855
+ init_buffer2();
78856
+ init_process2();
78857
+ init_AssetKey();
78858
+ init_AssetLoader();
78859
+ init_source();
78860
+ init_Caching();
78861
+ init_Assets();
78862
+ init_MineRenderError();
78863
+ init_ModelTextures();
78864
+ Entities = class {
78865
+ static async getEntityList() {
78866
+ const collect = async (path) => {
78867
+ const prefix2 = path ? `${path}/` : "";
78868
+ const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
78869
+ const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
78870
+ if (!list) return [];
78871
+ const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
78872
+ const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
78873
+ return [...files, ...children.flat()];
78874
+ };
78875
+ return collect("");
78876
+ }
78877
+ static async getModelFile(modelKey) {
78878
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
78879
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
78880
+ return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
78881
+ }
78882
+ static async getLayerList(modelKey) {
78883
+ return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
78884
+ }
78885
+ /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
78886
+ static async getPassList(modelKey) {
78887
+ return (await this.getModelFile(modelKey))?.passes ?? [];
78888
+ }
78889
+ static async getEntity(modelKey, textureKey, options) {
78890
+ const model = await this.getModelFile(modelKey);
78891
+ if (!model) return void 0;
78892
+ const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
78893
+ const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
78894
+ if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
78895
+ draws.push(...passes);
78896
+ const names = [];
78897
+ const selected = draws.map((pass) => {
78898
+ const layer = model.layers[pass.layer];
78899
+ if (!layer) {
78900
+ throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
78901
+ }
78902
+ let name2 = pass.layer;
78903
+ for (let n4 = 2; names.includes(name2); n4++) name2 = `${pass.layer}#${n4}`;
78904
+ names.push(name2);
78905
+ return { name: name2, layer, pass };
78906
+ });
78907
+ const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name: name2, layer, pass }, index) => {
78908
+ const override = options?.textures?.[name2] ?? (index === 0 ? textureKey : void 0);
78909
+ const textureLocation = pass.textureLocation ?? layer.textureLocation;
78910
+ let texture;
78911
+ if (override) {
78912
+ const path = isAssetKey(override) ? override.getFullPath() : override.path;
78913
+ texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
78914
+ } else if (textureLocation !== void 0) {
78915
+ texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
78916
+ if (isAssetKey(modelKey)) texture.root = modelKey.root;
78917
+ } else {
78918
+ texture = await this.resolveTexture(modelKey);
78919
+ }
78920
+ const render = pass.render ?? layer.render;
78921
+ return [name2, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
78922
+ })));
78923
+ return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
78924
+ }
78925
+ /**
78926
+ * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
78927
+ */
78928
+ static async getAnimations(modelKey) {
78929
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
78930
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
78931
+ const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
78932
+ return file?.animations;
78933
+ }
78934
+ static async resolveTexture(modelKey) {
78935
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
78936
+ const root = isAssetKey(modelKey) ? modelKey.root : void 0;
78937
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", root);
78938
+ return Caching.entityTextureCache.get(key.serialize(), async () => {
78939
+ const name2 = path.split("/").pop();
78940
+ for (const candidate of [path, `${path}/${name2}`]) {
78941
+ const texture2 = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png", root);
78942
+ if (await ModelTextures.get(texture2)) return texture2;
78943
+ }
78944
+ const listKey = new AssetKey(modelKey.namespace, "_list", `${name2}_variant`, void 0, "data", ".json", root);
78945
+ const list = await AssetLoader.get(listKey, "list" /* LIST */);
78946
+ const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
78947
+ const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
78948
+ if (!file) return void 0;
78949
+ const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name2}_variant`, void 0, "data", ".json", root);
78950
+ const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
78951
+ const assets = variant?.assets;
78952
+ const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
78953
+ if (typeof textureId !== "string") return void 0;
78954
+ const texture = AssetKey.parse("textures", textureId);
78955
+ texture.root = root;
78956
+ return texture;
78957
+ });
78958
+ }
78959
+ /** @deprecated Use getEntityList(); block entities share the entity dataset. */
78960
+ static getBlockList() {
78961
+ return this.getEntityList();
78962
+ }
78963
+ /** @deprecated Use getEntity(); block entities share the entity dataset. */
78964
+ static getBlock(modelKey, textureKey, options) {
78965
+ return this.getEntity(modelKey, textureKey, options);
78966
+ }
78967
+ };
78968
+ }
78969
+ });
78970
+
78971
+ // src/entity/EntityAnimation.ts
78972
+ function catmullRom(delta, p0, p1, p22, p32) {
78973
+ return 0.5 * (2 * p1 + (p22 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p22 - p32) * delta * delta + (3 * p1 - p0 - 3 * p22 + p32) * delta * delta * delta);
78974
+ }
78975
+ function sampleEntityKeyframes(keyframes, time) {
78976
+ if (keyframes.length === 0) return [0, 0, 0];
78977
+ let low = 0, high = keyframes.length;
78978
+ while (low < high) {
78979
+ const middle = low + high >>> 1;
78980
+ if (time <= keyframes[middle].time) high = middle;
78981
+ else low = middle + 1;
78982
+ }
78983
+ const a4 = Math.max(0, low - 1);
78984
+ const b4 = Math.min(keyframes.length - 1, a4 + 1);
78985
+ const from = keyframes[a4];
78986
+ const to = keyframes[b4];
78987
+ const delta = a4 === b4 ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
78988
+ if (to.interpolation === "catmullrom") {
78989
+ const before = keyframes[Math.max(0, a4 - 1)].value;
78990
+ const after = keyframes[Math.min(keyframes.length - 1, b4 + 1)].value;
78991
+ return [0, 1, 2].map((i4) => catmullRom(delta, before[i4], from.value[i4], to.value[i4], after[i4]));
78992
+ }
78993
+ const target = to.pre ?? to.value;
78994
+ return [0, 1, 2].map((i4) => from.value[i4] + (target[i4] - from.value[i4]) * delta);
78995
+ }
78996
+ function entityAnimationTime(animation, time, loop = animation.loop) {
78997
+ return loop && animation.length > 0 ? time % animation.length : time;
78998
+ }
78999
+ function sampleEntityAnimation(animation, time, loop = animation.loop) {
79000
+ const elapsed = entityAnimationTime(animation, time, loop);
79001
+ const pose = {};
79002
+ for (const [name2, bone] of Object.entries(animation.bones)) {
79003
+ const sampled = pose[name2] = {};
79004
+ for (const channel of ENTITY_ANIMATION_CHANNELS) {
79005
+ const keyframes = bone[channel];
79006
+ if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
79007
+ }
79008
+ }
79009
+ return pose;
79010
+ }
79011
+ var ENTITY_ANIMATION_CHANNELS;
79012
+ var init_EntityAnimation = __esm({
79013
+ "src/entity/EntityAnimation.ts"() {
79014
+ init_dirname();
79015
+ init_buffer2();
79016
+ init_process2();
79017
+ ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
79018
+ }
79019
+ });
79020
+
79021
+ // src/entity/scene/EntityAnimationPlayer.ts
79022
+ var ZERO, EntityAnimationPlayer;
79023
+ var init_EntityAnimationPlayer = __esm({
79024
+ "src/entity/scene/EntityAnimationPlayer.ts"() {
79025
+ init_dirname();
79026
+ init_buffer2();
79027
+ init_process2();
79028
+ init_EntityAnimation();
79029
+ ZERO = [0, 0, 0];
79030
+ EntityAnimationPlayer = class {
79031
+ constructor() {
79032
+ this.parts = [];
79033
+ this._time = 0;
79034
+ this.loop = false;
79035
+ this.speed = 1;
79036
+ }
79037
+ get animation() {
79038
+ return this._animation;
79039
+ }
79040
+ get time() {
79041
+ return this._time;
79042
+ }
79043
+ /**
79044
+ * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
79045
+ * bones without a matching part are skipped.
79046
+ */
79047
+ play(layers, animation, options = {}) {
79048
+ this.stop();
79049
+ this._animation = animation;
79050
+ this._time = options.time ?? 0;
79051
+ this.loop = options.loop ?? animation.loop;
79052
+ this.speed = options.speed ?? 1;
79053
+ for (const layer of layers) {
79054
+ for (const bone of Object.keys(animation.bones)) {
79055
+ const object = layer.getObjectByName(`group:${bone}`);
79056
+ if (!object) continue;
79057
+ this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
79058
+ }
79059
+ }
79060
+ this.apply();
79061
+ }
79062
+ /** Restores the default poses. Returns whether an animation was active. */
79063
+ stop() {
79064
+ if (!this._animation) return false;
79065
+ for (const part of this.parts) {
79066
+ part.object.position.copy(part.position);
79067
+ part.object.rotation.copy(part.rotation);
79068
+ part.object.scale.copy(part.scale);
79069
+ }
79070
+ this.clear();
79071
+ return true;
79072
+ }
79073
+ /** Forgets the animation without touching the parts, for parts that no longer exist. */
79074
+ clear() {
79075
+ this.parts = [];
79076
+ this._animation = void 0;
79077
+ this._time = 0;
79078
+ }
79079
+ setTime(seconds) {
79080
+ if (!this._animation) return false;
79081
+ this._time = seconds;
79082
+ this.apply();
79083
+ return true;
79084
+ }
79085
+ advance(deltaSeconds) {
79086
+ return this.setTime(this._time + deltaSeconds * this.speed);
79087
+ }
79088
+ apply() {
79089
+ const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
79090
+ for (const part of this.parts) {
79091
+ const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
79092
+ part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
79093
+ part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
79094
+ part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
79095
+ }
79096
+ }
79097
+ };
79098
+ }
79099
+ });
79100
+
78709
79101
  // src/instance/InstanceReference.ts
78710
79102
  function isInstanceReference(obj) {
78711
79103
  return obj.isInstanceReference;
@@ -79208,6 +79600,244 @@ ${key}` : key;
79208
79600
  }
79209
79601
  });
79210
79602
 
79603
+ // src/entity/scene/EntityObject.ts
79604
+ function isEntityObject(obj) {
79605
+ return obj.isEntityObject;
79606
+ }
79607
+ var import_ts_deepmerge4, _EntityObject, EntityObject;
79608
+ var init_EntityObject = __esm({
79609
+ "src/entity/scene/EntityObject.ts"() {
79610
+ init_dirname();
79611
+ init_buffer2();
79612
+ init_process2();
79613
+ init_SceneObject();
79614
+ init_Caching();
79615
+ import_ts_deepmerge4 = __toESM(require_dist());
79616
+ init_three_module();
79617
+ init_Ticker();
79618
+ init_model();
79619
+ init_ModelTextures();
79620
+ init_AssetKey();
79621
+ init_Materials();
79622
+ init_MinecraftCubeTexture();
79623
+ init_three();
79624
+ init_EntityAnimationPlayer();
79625
+ _EntityObject = class _EntityObject extends SceneObject {
79626
+ constructor(entity, options) {
79627
+ super();
79628
+ this.entity = entity;
79629
+ this.isEntityObject = true;
79630
+ this.meshesCreated = false;
79631
+ this.geometries = /* @__PURE__ */ new Set();
79632
+ this.disposeWireframes = [];
79633
+ /** Scrolling materials are owned: their texture offset follows this entity's age. */
79634
+ this.scrollMaterials = [];
79635
+ /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
79636
+ this.age = 0;
79637
+ this.animationPlayer = new EntityAnimationPlayer();
79638
+ this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
79639
+ this.addEventListener("added", () => this.updateScrollSubscription());
79640
+ this.addEventListener("removed", () => this.updateScrollSubscription());
79641
+ }
79642
+ async init() {
79643
+ this.createMeshes();
79644
+ await this.applyTextures();
79645
+ }
79646
+ dispose() {
79647
+ super.dispose();
79648
+ }
79649
+ disposeAndRemoveAllChildren() {
79650
+ this.clearScrollMaterials();
79651
+ for (const geometry of this.geometries) geometry.dispose();
79652
+ this.geometries.clear();
79653
+ for (const dispose of this.disposeWireframes.splice(0)) dispose();
79654
+ this.animationPlayer.clear();
79655
+ super.disposeAndRemoveAllChildren();
79656
+ }
79657
+ clearScrollMaterials() {
79658
+ Ticker.remove(this.scrollTicker);
79659
+ this.scrollTicker = void 0;
79660
+ for (const { material } of this.scrollMaterials.splice(0)) {
79661
+ material.map?.dispose();
79662
+ material.dispose();
79663
+ }
79664
+ }
79665
+ updateScrollSubscription() {
79666
+ if (this.parent && this.scrollMaterials.length) {
79667
+ if (this.scrollTicker === void 0) {
79668
+ this.scrollTicker = Ticker.add(() => {
79669
+ this.age++;
79670
+ this.updateScroll();
79671
+ });
79672
+ }
79673
+ } else {
79674
+ Ticker.remove(this.scrollTicker);
79675
+ this.scrollTicker = void 0;
79676
+ }
79677
+ }
79678
+ /** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
79679
+ updateScroll() {
79680
+ for (const { offset, speed } of this.scrollMaterials) {
79681
+ offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
79682
+ }
79683
+ this.notifyDirty();
79684
+ }
79685
+ //<editor-fold desc="ANIMATION">
79686
+ /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
79687
+ get animation() {
79688
+ return this.animationPlayer.animation;
79689
+ }
79690
+ /** Seconds since the animation started, before looping. */
79691
+ get animationTime() {
79692
+ return this.animationPlayer.time;
79693
+ }
79694
+ /**
79695
+ * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
79696
+ * Parts of every layer are matched by name and their current pose is the default the offsets add to.
79697
+ * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
79698
+ */
79699
+ playAnimation(animation, options) {
79700
+ this.createMeshes();
79701
+ const layers = Object.keys(this.entityLayers).map((name2) => this.getLayerGroup(name2)).filter((layer) => !!layer);
79702
+ this.animationPlayer.play(layers, animation, options);
79703
+ this.notifyDirty();
79704
+ }
79705
+ /** Stops the animation and restores the default pose. */
79706
+ stopAnimation() {
79707
+ if (this.animationPlayer.stop()) this.notifyDirty();
79708
+ }
79709
+ /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
79710
+ setAnimationTime(seconds) {
79711
+ if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
79712
+ }
79713
+ /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
79714
+ advanceAnimation(deltaSeconds) {
79715
+ if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
79716
+ }
79717
+ //</editor-fold>
79718
+ getLayerGroup(name2) {
79719
+ return super.getGroupByName(`layer:${name2}`);
79720
+ }
79721
+ getGroupByName(name2, layerName) {
79722
+ return layerName === void 0 ? super.getGroupByName(name2) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name2}`);
79723
+ }
79724
+ getMeshByName(name2, layerName) {
79725
+ return layerName === void 0 ? super.getMeshByName(name2) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name2}`);
79726
+ }
79727
+ get entityLayers() {
79728
+ return this.entity.layers ?? { main: this.entity };
79729
+ }
79730
+ getTextureKey(layer) {
79731
+ if (layer.texture) return layer.texture;
79732
+ const key = layer.key;
79733
+ return new AssetKey(
79734
+ key.namespace,
79735
+ isAssetKey(key) ? key.getFullPath() : key.path,
79736
+ "textures",
79737
+ "entity",
79738
+ "assets",
79739
+ ".png"
79740
+ );
79741
+ }
79742
+ async loadTextures(layer = this.entity) {
79743
+ return ModelTextures.get(this.getTextureKey(layer));
79744
+ }
79745
+ createMeshes(force = false) {
79746
+ if (this.meshesCreated && !force) return;
79747
+ const modelRoot = new Object3D();
79748
+ const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
79749
+ if (transform) {
79750
+ for (const op of transform) {
79751
+ const matrix = new Matrix4();
79752
+ if ("scale" in op) matrix.makeScale(...op.scale);
79753
+ else if ("translate" in op) matrix.makeTranslation(...op.translate);
79754
+ else matrix.makeRotationFromEuler(new Euler(...op.rotate, "ZYX"));
79755
+ modelRoot.matrix.multiply(matrix);
79756
+ }
79757
+ modelRoot.matrixAutoUpdate = false;
79758
+ } else if (this.options.flip ?? true) {
79759
+ modelRoot.scale.set(-1, -1, 1);
79760
+ }
79761
+ this.add(modelRoot);
79762
+ Object.entries(this.entityLayers).forEach(([name2, layer], index) => {
79763
+ const group = this.createGroup(`layer:${name2}`);
79764
+ modelRoot.add(group);
79765
+ const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
79766
+ this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
79767
+ });
79768
+ this.meshesCreated = true;
79769
+ }
79770
+ createPart(name2, part, parent, textureSize, material, renderOrder, inward = true) {
79771
+ const anchor = this.createGroup(name2);
79772
+ anchor.position.fromArray(part.pose.offset);
79773
+ anchor.rotation.set(...part.pose.rotation, "ZYX");
79774
+ anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
79775
+ parent.add(anchor);
79776
+ const size = part.texture ?? textureSize;
79777
+ for (const cube of part.cubes) {
79778
+ const [width, height, depth] = cube.size;
79779
+ const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
79780
+ const texture = new MinecraftCubeTexture(...cube.uv, ...size);
79781
+ const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
79782
+ const geometry = this._getBoxGeometryForDimensionsAndUv(
79783
+ width + growX * 2,
79784
+ height + growY * 2,
79785
+ depth + growZ * 2,
79786
+ uv
79787
+ ).clone();
79788
+ this.geometries.add(geometry);
79789
+ geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
79790
+ if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
79791
+ const index = Array.from(geometry.getIndex().array);
79792
+ geometry.setIndex(index.concat(index.slice().reverse()));
79793
+ }
79794
+ const mesh = this.createMesh(name2, geometry, material);
79795
+ mesh.renderOrder = renderOrder;
79796
+ anchor.add(mesh);
79797
+ if (this.options.wireframe) this.disposeWireframes.push(addWireframeToMesh(geometry, mesh));
79798
+ }
79799
+ for (const [childName, child] of Object.entries(part.children)) {
79800
+ this.createPart(childName, child, anchor, size, material, renderOrder, inward);
79801
+ }
79802
+ }
79803
+ async applyTextures() {
79804
+ this.clearScrollMaterials();
79805
+ await Promise.all(Object.entries(this.entityLayers).map(async ([name2, layer]) => {
79806
+ const mode2 = layer.render ?? layer.layer.render ?? "cutout";
79807
+ const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
79808
+ const scroll = Materials.entityModeScroll(mode2);
79809
+ const assetKeyStr = this.getTextureKey(layer).serialize();
79810
+ const keyStr = `entity:${mode2}:${tint === void 0 ? "" : new Color(tint).getHexString()}:${assetKeyStr}`;
79811
+ let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
79812
+ if (!mat) {
79813
+ const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
79814
+ const imageData = await this.loadTextures(layer);
79815
+ if (!imageData) return;
79816
+ const canvas = imageData.data.canvas;
79817
+ const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode2, tint);
79818
+ mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
79819
+ if (scroll) {
79820
+ this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
79821
+ }
79822
+ }
79823
+ this.getLayerGroup(name2)?.traverse((object) => {
79824
+ if (isMesh(object)) object.material = mat;
79825
+ });
79826
+ }));
79827
+ if (!this.children.length) {
79828
+ this.clearScrollMaterials();
79829
+ } else if (this.scrollMaterials.length) {
79830
+ this.updateScroll();
79831
+ }
79832
+ this.updateScrollSubscription();
79833
+ this.notifyDirty();
79834
+ }
79835
+ };
79836
+ _EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
79837
+ EntityObject = _EntityObject;
79838
+ }
79839
+ });
79840
+
79211
79841
  // src/three/BufferGeometryUtils.js
79212
79842
  function computeTangents(geometry) {
79213
79843
  geometry.computeTangents();
@@ -79792,6 +80422,125 @@ ${key}` : key;
79792
80422
  }
79793
80423
  });
79794
80424
 
80425
+ // src/model/SpecialItems.ts
80426
+ var SpecialItems;
80427
+ var init_SpecialItems = __esm({
80428
+ "src/model/SpecialItems.ts"() {
80429
+ init_dirname();
80430
+ init_buffer2();
80431
+ init_process2();
80432
+ init_three_module();
80433
+ init_AssetKey();
80434
+ init_Entities();
80435
+ SpecialItems = class {
80436
+ /** Resolves the static entity parts drawn by a special item renderer, in model units. */
80437
+ static async getParts(special, root) {
80438
+ const texture = (id, directory) => {
80439
+ const key = AssetKey.parse("textures", id);
80440
+ return new AssetKey(
80441
+ key.namespace,
80442
+ [directory, key.getFullPath()].filter(Boolean).join("/"),
80443
+ "textures",
80444
+ "entity",
80445
+ "assets",
80446
+ ".png",
80447
+ root
80448
+ );
80449
+ };
80450
+ const load = async (id, textureKey, transform, rotations = {}) => {
80451
+ const key = new AssetKey("minecraft", id, void 0, void 0, "entity-models", ".json", root);
80452
+ const model = await Entities.getEntity(key, textureKey, { layer: "main" });
80453
+ if (!model) throw new Error(`Missing entity model minecraft:${id} for special item ${special.type}`);
80454
+ return { model, transform, rotations };
80455
+ };
80456
+ switch (special.type) {
80457
+ case "minecraft:chest":
80458
+ case "chest": {
80459
+ const angle = -(special.openness ?? 0) * Math.PI / 2;
80460
+ const chest = await load("chest", texture(special.texture, "chest"), new Matrix4(), {
80461
+ lid: [angle, 0, 0],
80462
+ lock: [angle, 0, 0]
80463
+ });
80464
+ chest.model = { ...chest.model, render: "solid", layers: void 0 };
80465
+ return [chest];
80466
+ }
80467
+ case "minecraft:bed":
80468
+ case "bed": {
80469
+ const transform = new Matrix4().makeTranslation(0, 9, 0).multiply(new Matrix4().makeRotationX(Math.PI / 2)).multiply(new Matrix4().makeTranslation(8, 8, 8)).multiply(new Matrix4().makeRotationZ(Math.PI)).multiply(new Matrix4().makeTranslation(-8, -8, -8));
80470
+ const key = texture(special.texture, "bed");
80471
+ return Promise.all([
80472
+ load("bed_head", key, transform),
80473
+ load("bed_foot", key, new Matrix4().makeTranslation(0, 0, -16).multiply(transform))
80474
+ ]);
80475
+ }
80476
+ case "minecraft:head":
80477
+ case "head": {
80478
+ const models = {
80479
+ skeleton: "skeleton_skull",
80480
+ wither_skeleton: "wither_skeleton_skull",
80481
+ zombie: "zombie_head",
80482
+ creeper: "creeper_head",
80483
+ dragon: "dragon_skull",
80484
+ piglin: "piglin_head"
80485
+ };
80486
+ const id = Object.prototype.hasOwnProperty.call(models, special.kind) ? models[special.kind] : void 0;
80487
+ if (!id) throw new Error(`Unsupported special item head kind ${special.kind}`);
80488
+ const animation = (special.animation ?? 0) * Math.PI * 0.2;
80489
+ const rotations = { head: [0, Math.PI, 0] };
80490
+ if (special.kind === "dragon") rotations.jaw = [(Math.sin(animation) + 1) * 0.2, 0, 0];
80491
+ if (special.kind === "piglin") {
80492
+ rotations.left_ear = [0, 0, -(Math.cos(animation * 1.2) + 2.5) * 0.2];
80493
+ rotations.right_ear = [0, 0, (Math.cos(animation) + 2.5) * 0.2];
80494
+ }
80495
+ return [await load(
80496
+ id,
80497
+ special.texture ? texture(special.texture, "") : void 0,
80498
+ new Matrix4().makeTranslation(8, 0, 8).multiply(new Matrix4().makeScale(-1, -1, 1)),
80499
+ rotations
80500
+ )];
80501
+ }
80502
+ }
80503
+ }
80504
+ /** An owned material with model-preview shading; its entity texture remains shared. */
80505
+ static createMaterial(source, shade) {
80506
+ const material = source.clone();
80507
+ if (shade) {
80508
+ material.onBeforeCompile = (shader) => {
80509
+ shader.vertexShader = `varying float itemLight;
80510
+ ${shader.vertexShader}`.replace("#include <begin_vertex>", `
80511
+ #include <begin_vertex>
80512
+ vec3 N = inverseTransformDirection(normalMatrix * normal, viewMatrix);
80513
+ itemLight = (1.0 + N.y) * 0.25 - N.x * N.x * 0.15 + N.z * N.z * 0.05 + 0.5;
80514
+ `);
80515
+ shader.fragmentShader = `varying float itemLight;
80516
+ ${shader.fragmentShader}`.replace(
80517
+ "#include <color_fragment>",
80518
+ "#include <color_fragment>\ndiffuseColor.rgb *= itemLight;"
80519
+ );
80520
+ };
80521
+ material.customProgramCacheKey = () => "special-item-side";
80522
+ }
80523
+ return material;
80524
+ }
80525
+ };
80526
+ }
80527
+ });
80528
+
80529
+ // src/model/GuiLight.ts
80530
+ var GuiLight;
80531
+ var init_GuiLight = __esm({
80532
+ "src/model/GuiLight.ts"() {
80533
+ init_dirname();
80534
+ init_buffer2();
80535
+ init_process2();
80536
+ GuiLight = /* @__PURE__ */ ((GuiLight2) => {
80537
+ GuiLight2["FRONT"] = "front";
80538
+ GuiLight2["SIDE"] = "side";
80539
+ return GuiLight2;
80540
+ })(GuiLight || {});
80541
+ }
80542
+ });
80543
+
79795
80544
  // src/model/scene/ModelObject.ts
79796
80545
  function isModelObject(obj) {
79797
80546
  return obj.isModelObject;
@@ -79811,21 +80560,60 @@ ${key}` : key;
79811
80560
  import_ts_deepmerge5 = __toESM(require_dist());
79812
80561
  init_log();
79813
80562
  init_CubeFace();
80563
+ init_DisplayPosition();
79814
80564
  init_DisplayTransforms();
79815
80565
  init_ModelCulling();
80566
+ init_SpecialItems();
80567
+ init_EntityObject();
80568
+ init_GuiLight();
79816
80569
  p10 = prefix("ModelObject");
79817
80570
  _ModelObject = class _ModelObject extends SceneObject {
79818
80571
  constructor(originalModel, options) {
79819
80572
  super(options);
79820
80573
  this.originalModel = originalModel;
79821
80574
  this.isModelObject = true;
80575
+ this.specialMaterials = /* @__PURE__ */ new Map();
79822
80576
  this.meshesCreated = false;
79823
80577
  this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
80578
+ if (originalModel.special) this.options.instanceMeshes = false;
79824
80579
  if (this.options.tints) this.options.tints = { ...this.options.tints };
79825
80580
  this.addEventListener("added", () => this.updateAnimationSubscription());
79826
80581
  this.addEventListener("removed", () => this.updateAnimationSubscription());
79827
80582
  }
79828
80583
  async init() {
80584
+ const special = this.originalModel.special;
80585
+ if (special) {
80586
+ const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
80587
+ const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new Matrix4();
80588
+ transform.multiply(new Matrix4().makeTranslation(-8, -8, -8));
80589
+ try {
80590
+ for (const part of parts) {
80591
+ const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
80592
+ object.matrix.copy(transform).multiply(part.transform);
80593
+ object.matrixAutoUpdate = false;
80594
+ this.add(object);
80595
+ await object.init();
80596
+ object.iterateAllMeshes((mesh) => {
80597
+ const source = mesh.material;
80598
+ let material = this.specialMaterials.get(source);
80599
+ if (!material) {
80600
+ const front = this.options.displayPosition === "gui" /* GUI */ && this.originalModel.gui_light === "front" /* FRONT */;
80601
+ material = SpecialItems.createMaterial(source, !front);
80602
+ this.specialMaterials.set(source, material);
80603
+ }
80604
+ mesh.material = material;
80605
+ });
80606
+ for (const [name2, rotation] of Object.entries(part.rotations)) {
80607
+ object.getGroupByName(name2)?.rotation.set(...rotation, "ZYX");
80608
+ }
80609
+ }
80610
+ } catch (error) {
80611
+ this.disposeAndRemoveAllChildren();
80612
+ throw error;
80613
+ }
80614
+ this.notifyDirty();
80615
+ return;
80616
+ }
79829
80617
  await this.loadTextures();
79830
80618
  this.createMeshes();
79831
80619
  this.applyTextures();
@@ -79970,6 +80758,8 @@ ${key}` : key;
79970
80758
  this.atlasMaterial?.dispose();
79971
80759
  this.atlasTexture = void 0;
79972
80760
  this.atlasMaterial = void 0;
80761
+ for (const material of this.specialMaterials.values()) material.dispose();
80762
+ this.specialMaterials.clear();
79973
80763
  super.disposeAndRemoveAllChildren();
79974
80764
  }
79975
80765
  };
@@ -83124,6 +83914,7 @@ ${key}` : key;
83124
83914
  SkinPart: () => SkinPart,
83125
83915
  SkinTextures: () => SkinTextures,
83126
83916
  Skins: () => Skins,
83917
+ SpecialItems: () => SpecialItems,
83127
83918
  StructureParser: () => StructureParser,
83128
83919
  TextureAtlas: () => TextureAtlas,
83129
83920
  TextureLoader: () => TextureLoader,
@@ -83401,99 +84192,8 @@ ${key}` : key;
83401
84192
  init_buffer2();
83402
84193
  init_process2();
83403
84194
 
83404
- // src/MinecraftCubeTexture.ts
83405
- init_dirname();
83406
- init_buffer2();
83407
- init_process2();
83408
- init_UVMapper();
83409
- init_CubeFace();
83410
- var MinecraftCubeTexture = class {
83411
- constructor(u4, v5, width, height) {
83412
- this.u = u4;
83413
- this.v = v5;
83414
- this.width = width;
83415
- this.height = height;
83416
- }
83417
- mapW(x4) {
83418
- return x4 / this.width;
83419
- }
83420
- mapH(x4) {
83421
- return 1 - x4 / this.height;
83422
- }
83423
- getUvEast(w4, h5, l4) {
83424
- return [
83425
- [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4 + h5)],
83426
- [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4 + h5)],
83427
- [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4)],
83428
- [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)]
83429
- ];
83430
- }
83431
- getUvWest(w4, h5, l4) {
83432
- return [
83433
- [this.mapW(this.u + l4), this.mapH(this.v + l4 + h5)],
83434
- [this.mapW(this.u), this.mapH(this.v + l4 + h5)],
83435
- [this.mapW(this.u + l4), this.mapH(this.v + l4)],
83436
- [this.mapW(this.u), this.mapH(this.v + l4)]
83437
- ];
83438
- }
83439
- getUvUp(w4, h5, l4) {
83440
- return [
83441
- [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)],
83442
- [this.mapW(this.u + l4 + w4 + w4), this.mapH(this.v + l4)],
83443
- [this.mapW(this.u + l4 + w4), this.mapH(this.v)],
83444
- [this.mapW(this.u + l4 + w4 + w4), this.mapH(this.v)]
83445
- ];
83446
- }
83447
- getUvDown(w4, h5, l4) {
83448
- return [
83449
- [this.mapW(this.u + l4), this.mapH(this.v)],
83450
- [this.mapW(this.u + l4 + w4), this.mapH(this.v)],
83451
- [this.mapW(this.u + l4), this.mapH(this.v + l4)],
83452
- [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)]
83453
- ];
83454
- }
83455
- getUvSouth(w4, h5, l4) {
83456
- return [
83457
- [this.mapW(this.u + l4 + w4 + l4 + w4), this.mapH(this.v + l4 + h5)],
83458
- [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4 + h5)],
83459
- [this.mapW(this.u + l4 + w4 + l4 + w4), this.mapH(this.v + l4)],
83460
- [this.mapW(this.u + l4 + w4 + l4), this.mapH(this.v + l4)]
83461
- ];
83462
- }
83463
- getUvNorth(w4, h5, l4) {
83464
- return [
83465
- [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4 + h5)],
83466
- [this.mapW(this.u + l4), this.mapH(this.v + l4 + h5)],
83467
- [this.mapW(this.u + l4 + w4), this.mapH(this.v + l4)],
83468
- [this.mapW(this.u + l4), this.mapH(this.v + l4)]
83469
- ];
83470
- }
83471
- getFaceUv(face, w4, h5, l4) {
83472
- switch (face) {
83473
- case "east" /* EAST */:
83474
- return this.getUvEast(w4, h5, l4);
83475
- case "west" /* WEST */:
83476
- return this.getUvWest(w4, h5, l4);
83477
- case "up" /* UP */:
83478
- return this.getUvUp(w4, h5, l4);
83479
- case "down" /* DOWN */:
83480
- return this.getUvDown(w4, h5, l4);
83481
- case "south" /* SOUTH */:
83482
- return this.getUvSouth(w4, h5, l4);
83483
- case "north" /* NORTH */:
83484
- return this.getUvNorth(w4, h5, l4);
83485
- }
83486
- }
83487
- toUvArray(w4, h5, l4, mirror = false) {
83488
- const uv = [];
83489
- for (let i4 = 0; i4 < CUBE_FACES.length; i4++) {
83490
- const face = mirror && i4 < 2 ? CUBE_FACES[1 - i4] : CUBE_FACES[i4];
83491
- const corners = this.getFaceUv(face, w4, h5, l4);
83492
- UVMapper.setFaceUvInArray(uv, i4 * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
83493
- }
83494
- return uv;
83495
- }
83496
- };
84195
+ // src/index.ts
84196
+ init_MinecraftCubeTexture();
83497
84197
 
83498
84198
  // src/MinecraftTextureMeta.ts
83499
84199
  init_dirname();
@@ -83615,119 +84315,7 @@ ${key}` : key;
83615
84315
 
83616
84316
  // src/assets/index.ts
83617
84317
  init_BlockStates();
83618
-
83619
- // src/assets/Entities.ts
83620
- init_dirname();
83621
- init_buffer2();
83622
- init_process2();
83623
- init_AssetKey();
83624
- init_AssetLoader();
83625
- init_source();
83626
- init_Caching();
83627
- init_Assets();
83628
- init_MineRenderError();
83629
- init_ModelTextures();
83630
- var Entities = class {
83631
- static async getEntityList() {
83632
- const collect = async (path) => {
83633
- const prefix2 = path ? `${path}/` : "";
83634
- const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
83635
- const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
83636
- if (!list) return [];
83637
- const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
83638
- const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
83639
- return [...files, ...children.flat()];
83640
- };
83641
- return collect("");
83642
- }
83643
- static async getModelFile(modelKey) {
83644
- const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
83645
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
83646
- return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
83647
- }
83648
- static async getLayerList(modelKey) {
83649
- return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
83650
- }
83651
- /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
83652
- static async getPassList(modelKey) {
83653
- return (await this.getModelFile(modelKey))?.passes ?? [];
83654
- }
83655
- static async getEntity(modelKey, textureKey, options) {
83656
- const model = await this.getModelFile(modelKey);
83657
- if (!model) return void 0;
83658
- const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
83659
- const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
83660
- if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
83661
- draws.push(...passes);
83662
- const names = [];
83663
- const selected = draws.map((pass) => {
83664
- const layer = model.layers[pass.layer];
83665
- if (!layer) {
83666
- throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
83667
- }
83668
- let name2 = pass.layer;
83669
- for (let n4 = 2; names.includes(name2); n4++) name2 = `${pass.layer}#${n4}`;
83670
- names.push(name2);
83671
- return { name: name2, layer, pass };
83672
- });
83673
- const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name: name2, layer, pass }, index) => {
83674
- const override = options?.textures?.[name2] ?? (index === 0 ? textureKey : void 0);
83675
- const textureLocation = pass.textureLocation ?? layer.textureLocation;
83676
- let texture;
83677
- if (override) {
83678
- const path = isAssetKey(override) ? override.getFullPath() : override.path;
83679
- texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
83680
- } else if (textureLocation !== void 0) {
83681
- texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
83682
- } else {
83683
- texture = await this.resolveTexture(modelKey);
83684
- }
83685
- const render = pass.render ?? layer.render;
83686
- return [name2, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
83687
- })));
83688
- return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
83689
- }
83690
- /**
83691
- * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
83692
- */
83693
- static async getAnimations(modelKey) {
83694
- const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
83695
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
83696
- const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
83697
- return file?.animations;
83698
- }
83699
- static async resolveTexture(modelKey) {
83700
- const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
83701
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
83702
- return Caching.entityTextureCache.get(key.serialize(), async () => {
83703
- const name2 = path.split("/").pop();
83704
- for (const candidate of [path, `${path}/${name2}`]) {
83705
- const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
83706
- if (await ModelTextures.get(texture)) return texture;
83707
- }
83708
- const listKey = new AssetKey(modelKey.namespace, "_list", `${name2}_variant`, void 0, "data", ".json");
83709
- const list = await AssetLoader.get(listKey, "list" /* LIST */);
83710
- const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
83711
- const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
83712
- if (!file) return void 0;
83713
- const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name2}_variant`, void 0, "data", ".json");
83714
- const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
83715
- const assets = variant?.assets;
83716
- const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
83717
- return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
83718
- });
83719
- }
83720
- /** @deprecated Use getEntityList(); block entities share the entity dataset. */
83721
- static getBlockList() {
83722
- return this.getEntityList();
83723
- }
83724
- /** @deprecated Use getEntity(); block entities share the entity dataset. */
83725
- static getBlock(modelKey, textureKey, options) {
83726
- return this.getEntity(modelKey, textureKey, options);
83727
- }
83728
- };
83729
-
83730
- // src/assets/index.ts
84318
+ init_Entities();
83731
84319
  init_ModelTextures();
83732
84320
  init_Models();
83733
84321
  init_source();
@@ -83810,51 +84398,7 @@ ${key}` : key;
83810
84398
  init_dirname();
83811
84399
  init_buffer2();
83812
84400
  init_process2();
83813
-
83814
- // src/entity/EntityAnimation.ts
83815
- init_dirname();
83816
- init_buffer2();
83817
- init_process2();
83818
- var ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
83819
- function catmullRom(delta, p0, p1, p22, p32) {
83820
- return 0.5 * (2 * p1 + (p22 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p22 - p32) * delta * delta + (3 * p1 - p0 - 3 * p22 + p32) * delta * delta * delta);
83821
- }
83822
- function sampleEntityKeyframes(keyframes, time) {
83823
- if (keyframes.length === 0) return [0, 0, 0];
83824
- let low = 0, high = keyframes.length;
83825
- while (low < high) {
83826
- const middle = low + high >>> 1;
83827
- if (time <= keyframes[middle].time) high = middle;
83828
- else low = middle + 1;
83829
- }
83830
- const a4 = Math.max(0, low - 1);
83831
- const b4 = Math.min(keyframes.length - 1, a4 + 1);
83832
- const from = keyframes[a4];
83833
- const to = keyframes[b4];
83834
- const delta = a4 === b4 ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
83835
- if (to.interpolation === "catmullrom") {
83836
- const before = keyframes[Math.max(0, a4 - 1)].value;
83837
- const after = keyframes[Math.min(keyframes.length - 1, b4 + 1)].value;
83838
- return [0, 1, 2].map((i4) => catmullRom(delta, before[i4], from.value[i4], to.value[i4], after[i4]));
83839
- }
83840
- const target = to.pre ?? to.value;
83841
- return [0, 1, 2].map((i4) => from.value[i4] + (target[i4] - from.value[i4]) * delta);
83842
- }
83843
- function entityAnimationTime(animation, time, loop = animation.loop) {
83844
- return loop && animation.length > 0 ? time % animation.length : time;
83845
- }
83846
- function sampleEntityAnimation(animation, time, loop = animation.loop) {
83847
- const elapsed = entityAnimationTime(animation, time, loop);
83848
- const pose = {};
83849
- for (const [name2, bone] of Object.entries(animation.bones)) {
83850
- const sampled = pose[name2] = {};
83851
- for (const channel of ENTITY_ANIMATION_CHANNELS) {
83852
- const keyframes = bone[channel];
83853
- if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
83854
- }
83855
- }
83856
- return pose;
83857
- }
84401
+ init_EntityAnimation();
83858
84402
 
83859
84403
  // src/entity/EntityModel.ts
83860
84404
  init_dirname();
@@ -83865,311 +84409,8 @@ ${key}` : key;
83865
84409
  init_dirname();
83866
84410
  init_buffer2();
83867
84411
  init_process2();
83868
-
83869
- // src/entity/scene/EntityAnimationPlayer.ts
83870
- init_dirname();
83871
- init_buffer2();
83872
- init_process2();
83873
- var ZERO = [0, 0, 0];
83874
- var EntityAnimationPlayer = class {
83875
- constructor() {
83876
- this.parts = [];
83877
- this._time = 0;
83878
- this.loop = false;
83879
- this.speed = 1;
83880
- }
83881
- get animation() {
83882
- return this._animation;
83883
- }
83884
- get time() {
83885
- return this._time;
83886
- }
83887
- /**
83888
- * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
83889
- * bones without a matching part are skipped.
83890
- */
83891
- play(layers, animation, options = {}) {
83892
- this.stop();
83893
- this._animation = animation;
83894
- this._time = options.time ?? 0;
83895
- this.loop = options.loop ?? animation.loop;
83896
- this.speed = options.speed ?? 1;
83897
- for (const layer of layers) {
83898
- for (const bone of Object.keys(animation.bones)) {
83899
- const object = layer.getObjectByName(`group:${bone}`);
83900
- if (!object) continue;
83901
- this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
83902
- }
83903
- }
83904
- this.apply();
83905
- }
83906
- /** Restores the default poses. Returns whether an animation was active. */
83907
- stop() {
83908
- if (!this._animation) return false;
83909
- for (const part of this.parts) {
83910
- part.object.position.copy(part.position);
83911
- part.object.rotation.copy(part.rotation);
83912
- part.object.scale.copy(part.scale);
83913
- }
83914
- this.clear();
83915
- return true;
83916
- }
83917
- /** Forgets the animation without touching the parts, for parts that no longer exist. */
83918
- clear() {
83919
- this.parts = [];
83920
- this._animation = void 0;
83921
- this._time = 0;
83922
- }
83923
- setTime(seconds) {
83924
- if (!this._animation) return false;
83925
- this._time = seconds;
83926
- this.apply();
83927
- return true;
83928
- }
83929
- advance(deltaSeconds) {
83930
- return this.setTime(this._time + deltaSeconds * this.speed);
83931
- }
83932
- apply() {
83933
- const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
83934
- for (const part of this.parts) {
83935
- const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
83936
- part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
83937
- part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
83938
- part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
83939
- }
83940
- }
83941
- };
83942
-
83943
- // src/entity/scene/EntityObject.ts
83944
- init_dirname();
83945
- init_buffer2();
83946
- init_process2();
83947
- init_SceneObject();
83948
- init_Caching();
83949
- var import_ts_deepmerge4 = __toESM(require_dist());
83950
- init_three_module();
83951
- init_Ticker();
83952
- init_model();
83953
- init_ModelTextures();
83954
- init_AssetKey();
83955
- init_Materials();
83956
- init_three();
83957
- var _EntityObject = class _EntityObject extends SceneObject {
83958
- constructor(entity, options) {
83959
- super();
83960
- this.entity = entity;
83961
- this.isEntityObject = true;
83962
- this.meshesCreated = false;
83963
- this.geometries = /* @__PURE__ */ new Set();
83964
- this.disposeWireframes = [];
83965
- /** Scrolling materials are owned: their texture offset follows this entity's age. */
83966
- this.scrollMaterials = [];
83967
- /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
83968
- this.age = 0;
83969
- this.animationPlayer = new EntityAnimationPlayer();
83970
- this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
83971
- this.addEventListener("added", () => this.updateScrollSubscription());
83972
- this.addEventListener("removed", () => this.updateScrollSubscription());
83973
- }
83974
- async init() {
83975
- this.createMeshes();
83976
- await this.applyTextures();
83977
- }
83978
- dispose() {
83979
- super.dispose();
83980
- }
83981
- disposeAndRemoveAllChildren() {
83982
- this.clearScrollMaterials();
83983
- for (const geometry of this.geometries) geometry.dispose();
83984
- this.geometries.clear();
83985
- for (const dispose of this.disposeWireframes.splice(0)) dispose();
83986
- this.animationPlayer.clear();
83987
- super.disposeAndRemoveAllChildren();
83988
- }
83989
- clearScrollMaterials() {
83990
- Ticker.remove(this.scrollTicker);
83991
- this.scrollTicker = void 0;
83992
- for (const { material } of this.scrollMaterials.splice(0)) {
83993
- material.map?.dispose();
83994
- material.dispose();
83995
- }
83996
- }
83997
- updateScrollSubscription() {
83998
- if (this.parent && this.scrollMaterials.length) {
83999
- if (this.scrollTicker === void 0) {
84000
- this.scrollTicker = Ticker.add(() => {
84001
- this.age++;
84002
- this.updateScroll();
84003
- });
84004
- }
84005
- } else {
84006
- Ticker.remove(this.scrollTicker);
84007
- this.scrollTicker = void 0;
84008
- }
84009
- }
84010
- /** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
84011
- updateScroll() {
84012
- for (const { offset, speed } of this.scrollMaterials) {
84013
- offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
84014
- }
84015
- this.notifyDirty();
84016
- }
84017
- //<editor-fold desc="ANIMATION">
84018
- /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
84019
- get animation() {
84020
- return this.animationPlayer.animation;
84021
- }
84022
- /** Seconds since the animation started, before looping. */
84023
- get animationTime() {
84024
- return this.animationPlayer.time;
84025
- }
84026
- /**
84027
- * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
84028
- * Parts of every layer are matched by name and their current pose is the default the offsets add to.
84029
- * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
84030
- */
84031
- playAnimation(animation, options) {
84032
- this.createMeshes();
84033
- const layers = Object.keys(this.entityLayers).map((name2) => this.getLayerGroup(name2)).filter((layer) => !!layer);
84034
- this.animationPlayer.play(layers, animation, options);
84035
- this.notifyDirty();
84036
- }
84037
- /** Stops the animation and restores the default pose. */
84038
- stopAnimation() {
84039
- if (this.animationPlayer.stop()) this.notifyDirty();
84040
- }
84041
- /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
84042
- setAnimationTime(seconds) {
84043
- if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
84044
- }
84045
- /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
84046
- advanceAnimation(deltaSeconds) {
84047
- if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
84048
- }
84049
- //</editor-fold>
84050
- getLayerGroup(name2) {
84051
- return super.getGroupByName(`layer:${name2}`);
84052
- }
84053
- getGroupByName(name2, layerName) {
84054
- return layerName === void 0 ? super.getGroupByName(name2) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name2}`);
84055
- }
84056
- getMeshByName(name2, layerName) {
84057
- return layerName === void 0 ? super.getMeshByName(name2) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name2}`);
84058
- }
84059
- get entityLayers() {
84060
- return this.entity.layers ?? { main: this.entity };
84061
- }
84062
- getTextureKey(layer) {
84063
- if (layer.texture) return layer.texture;
84064
- const key = layer.key;
84065
- return new AssetKey(
84066
- key.namespace,
84067
- isAssetKey(key) ? key.getFullPath() : key.path,
84068
- "textures",
84069
- "entity",
84070
- "assets",
84071
- ".png"
84072
- );
84073
- }
84074
- async loadTextures(layer = this.entity) {
84075
- return ModelTextures.get(this.getTextureKey(layer));
84076
- }
84077
- createMeshes(force = false) {
84078
- if (this.meshesCreated && !force) return;
84079
- const modelRoot = new Object3D();
84080
- const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
84081
- if (transform) {
84082
- for (const op of transform) {
84083
- const matrix = new Matrix4();
84084
- if ("scale" in op) matrix.makeScale(...op.scale);
84085
- else if ("translate" in op) matrix.makeTranslation(...op.translate);
84086
- else matrix.makeRotationFromEuler(new Euler(...op.rotate, "ZYX"));
84087
- modelRoot.matrix.multiply(matrix);
84088
- }
84089
- modelRoot.matrixAutoUpdate = false;
84090
- } else if (this.options.flip ?? true) {
84091
- modelRoot.scale.set(-1, -1, 1);
84092
- }
84093
- this.add(modelRoot);
84094
- Object.entries(this.entityLayers).forEach(([name2, layer], index) => {
84095
- const group = this.createGroup(`layer:${name2}`);
84096
- modelRoot.add(group);
84097
- const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
84098
- this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
84099
- });
84100
- this.meshesCreated = true;
84101
- }
84102
- createPart(name2, part, parent, textureSize, material, renderOrder, inward = true) {
84103
- const anchor = this.createGroup(name2);
84104
- anchor.position.fromArray(part.pose.offset);
84105
- anchor.rotation.set(...part.pose.rotation, "ZYX");
84106
- anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
84107
- parent.add(anchor);
84108
- const size = part.texture ?? textureSize;
84109
- for (const cube of part.cubes) {
84110
- const [width, height, depth] = cube.size;
84111
- const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
84112
- const texture = new MinecraftCubeTexture(...cube.uv, ...size);
84113
- const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
84114
- const geometry = this._getBoxGeometryForDimensionsAndUv(
84115
- width + growX * 2,
84116
- height + growY * 2,
84117
- depth + growZ * 2,
84118
- uv
84119
- ).clone();
84120
- this.geometries.add(geometry);
84121
- geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
84122
- if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
84123
- const index = Array.from(geometry.getIndex().array);
84124
- geometry.setIndex(index.concat(index.slice().reverse()));
84125
- }
84126
- const mesh = this.createMesh(name2, geometry, material);
84127
- mesh.renderOrder = renderOrder;
84128
- anchor.add(mesh);
84129
- if (this.options.wireframe) this.disposeWireframes.push(addWireframeToMesh(geometry, mesh));
84130
- }
84131
- for (const [childName, child] of Object.entries(part.children)) {
84132
- this.createPart(childName, child, anchor, size, material, renderOrder, inward);
84133
- }
84134
- }
84135
- async applyTextures() {
84136
- this.clearScrollMaterials();
84137
- await Promise.all(Object.entries(this.entityLayers).map(async ([name2, layer]) => {
84138
- const mode2 = layer.render ?? layer.layer.render ?? "cutout";
84139
- const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
84140
- const scroll = Materials.entityModeScroll(mode2);
84141
- const assetKeyStr = this.getTextureKey(layer).serialize();
84142
- const keyStr = `entity:${mode2}:${tint === void 0 ? "" : new Color(tint).getHexString()}:${assetKeyStr}`;
84143
- let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
84144
- if (!mat) {
84145
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
84146
- const imageData = await this.loadTextures(layer);
84147
- if (!imageData) return;
84148
- const canvas = imageData.data.canvas;
84149
- const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode2, tint);
84150
- mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
84151
- if (scroll) {
84152
- this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
84153
- }
84154
- }
84155
- this.getLayerGroup(name2)?.traverse((object) => {
84156
- if (isMesh(object)) object.material = mat;
84157
- });
84158
- }));
84159
- if (!this.children.length) {
84160
- this.clearScrollMaterials();
84161
- } else if (this.scrollMaterials.length) {
84162
- this.updateScroll();
84163
- }
84164
- this.updateScrollSubscription();
84165
- this.notifyDirty();
84166
- }
84167
- };
84168
- _EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
84169
- var EntityObject = _EntityObject;
84170
- function isEntityObject(obj) {
84171
- return obj.isEntityObject;
84172
- }
84412
+ init_EntityAnimationPlayer();
84413
+ init_EntityObject();
84173
84414
 
84174
84415
  // src/error/index.ts
84175
84416
  init_dirname();
@@ -86798,18 +87039,7 @@ property list uchar int vertex_index
86798
87039
  init_Materials();
86799
87040
  init_ModelObject();
86800
87041
  init_DisplayPosition();
86801
-
86802
- // src/model/GuiLight.ts
86803
- init_dirname();
86804
- init_buffer2();
86805
- init_process2();
86806
- var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
86807
- GuiLight2["FRONT"] = "front";
86808
- GuiLight2["SIDE"] = "side";
86809
- return GuiLight2;
86810
- })(GuiLight || {});
86811
-
86812
- // src/gui/scene/GuiObject.ts
87042
+ init_GuiLight();
86813
87043
  var GuiObject = class extends SceneObject {
86814
87044
  constructor(textureLayers, options) {
86815
87045
  super({ ...options, instanceMeshes: false, mergeMeshes: false });
@@ -86832,13 +87062,13 @@ property list uchar int vertex_index
86832
87062
  const item = await this.createItem(layer, index);
86833
87063
  item.position.set(x4 + width2 / 2, -y5 - height2 / 2, 0);
86834
87064
  item.scale.set(width2 / 16, height2 / 16, width2 / 16);
86835
- item.updateMatrix();
87065
+ item.updateWorldMatrix(true, true);
87066
+ const inverse = this.matrixWorld.clone().invert();
86836
87067
  const bounds = new Box3();
86837
87068
  item.iterateAllMeshes((mesh2) => {
86838
87069
  mesh2.geometry.computeBoundingBox();
86839
- bounds.union(mesh2.geometry.boundingBox);
87070
+ bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
86840
87071
  });
86841
- bounds.applyMatrix4(item.matrix);
86842
87072
  item.position.z = depth - bounds.min.z;
86843
87073
  depth += bounds.max.z - bounds.min.z + 0.01;
86844
87074
  this.bounds.expandByPoint(new Vector2(x4, y5));
@@ -86893,7 +87123,7 @@ property list uchar int vertex_index
86893
87123
  this.add(item);
86894
87124
  await item.init();
86895
87125
  item.iterateAllMeshes((mesh) => {
86896
- this.geometries.add(mesh.geometry);
87126
+ if (!model.special) this.geometries.add(mesh.geometry);
86897
87127
  mesh.name = `mesh:${layer.name ?? index}`;
86898
87128
  mesh.renderOrder = index;
86899
87129
  for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
@@ -87382,25 +87612,9 @@ property list uchar int vertex_index
87382
87612
  init_buffer2();
87383
87613
  init_process2();
87384
87614
 
87385
- // src/model/Model.ts
87386
- init_dirname();
87387
- init_buffer2();
87388
- init_process2();
87389
- var ITEM_GENERATED = "item/generated";
87390
- var BUILTIN_GENERATED = "builtin/generated";
87391
- var BUILTIN_ENTITY = "builtin/entity";
87392
- var DEFAULT_ELEMENTS = [];
87393
- function isDoubleArray(obj) {
87394
- return Array.isArray(obj) && obj.length === 2;
87395
- }
87396
- function isTripleArray(obj) {
87397
- return Array.isArray(obj) && obj.length === 3;
87398
- }
87399
- function isQuadArray(obj) {
87400
- return Array.isArray(obj) && obj.length === 4;
87401
- }
87402
-
87403
87615
  // src/model/index.ts
87616
+ init_GuiLight();
87617
+ init_Model();
87404
87618
  init_ModelCulling();
87405
87619
 
87406
87620
  // src/model/ModelElement.ts
@@ -87411,6 +87625,7 @@ property list uchar int vertex_index
87411
87625
  // src/model/index.ts
87412
87626
  init_ModelGenerator();
87413
87627
  init_ModelMerger();
87628
+ init_SpecialItems();
87414
87629
 
87415
87630
  // src/model/block/index.ts
87416
87631
  init_dirname();
@@ -87638,6 +87853,7 @@ property list uchar int vertex_index
87638
87853
  init_AssetKey();
87639
87854
  init_ModelCulling();
87640
87855
  init_FluidGeometry();
87856
+ init_Entities();
87641
87857
  var _BlockObject = class _BlockObject extends SceneObject {
87642
87858
  constructor(blockState, options) {
87643
87859
  super(options);
@@ -90928,6 +91144,7 @@ property list uchar int vertex_index
90928
91144
  };
90929
91145
 
90930
91146
  // src/renderer/MineRenderScene.ts
91147
+ init_EntityObject();
90931
91148
  var _MineRenderScene = class _MineRenderScene extends Scene {
90932
91149
  constructor(options) {
90933
91150
  super();
@@ -92834,6 +93051,7 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
92834
93051
 
92835
93052
  // src/renderer/Renderer.ts
92836
93053
  init_util();
93054
+ init_Model();
92837
93055
  init_three();
92838
93056
 
92839
93057
  // src/three/OrbitControls.js
@@ -94379,6 +94597,7 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
94379
94597
  init_buffer2();
94380
94598
  init_process2();
94381
94599
  init_three_module();
94600
+ init_Model();
94382
94601
  init_BatchedExecutor();
94383
94602
  init_AssetKey();
94384
94603
  init_BlockStates();
@@ -94701,6 +94920,9 @@ uniform float opacity;varying vec2 vUv;void main(){vec4 texel=texture2D(inputBuf
94701
94920
  }
94702
94921
  };
94703
94922
 
94923
+ // src/world/Chunk.ts
94924
+ init_Model();
94925
+
94704
94926
  // src/world/SectionMesh.ts
94705
94927
  init_dirname();
94706
94928
  init_buffer2();