minerender 2.1.0-alpha.78 → 2.1.0-alpha.79

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.
@@ -1527,6 +1527,8 @@ var init_ModelMerger = __esm({
1527
1527
  ModelMerger = class {
1528
1528
  /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
1529
1529
  static async mergeWithParents(model) {
1530
+ const parts = model.parts;
1531
+ if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
1530
1532
  const models = await this.collectAllParents(model);
1531
1533
  let merged = {};
1532
1534
  for (const source of [...models, model]) {
@@ -1587,6 +1589,7 @@ var init_Models = __esm({
1587
1589
  init_PersistentCache();
1588
1590
  init_AssetKey();
1589
1591
  init_AssetParsers();
1592
+ init_DisplayPosition();
1590
1593
  Models = class _Models {
1591
1594
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
1592
1595
  // the library, and would require an EnvProvider before any entry has had a chance to register
@@ -1601,34 +1604,174 @@ var init_Models = __esm({
1601
1604
  return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
1602
1605
  }).then((r) => r?.files ?? []);
1603
1606
  }
1604
- static async loadAndMerge(key) {
1605
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
1607
+ static async loadAndMerge(key, context = {}) {
1608
+ const model = key.type === "item" ? await this.getItemModel(key, context) : await this.getRaw(key);
1606
1609
  if (!model) {
1607
1610
  return void 0;
1608
1611
  }
1609
1612
  return ModelMerger.mergeWithParents(model);
1610
1613
  }
1611
- static async getItemModel(key) {
1614
+ static async getItemModel(key, context = {}) {
1615
+ const preview = this.snapshotContext(key, context);
1612
1616
  const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1613
- const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v2:${AssetLoader.persistentKey(itemKey.serialize())}`, async () => {
1617
+ const cacheKey = itemKey.serialize() + this.contextKey(preview);
1618
+ const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v3:${AssetLoader.persistentKey(cacheKey)}`, async () => {
1614
1619
  const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1615
1620
  if (!result) return void 0;
1616
1621
  if (result.key.assetType !== "items") return { ...result.asset, key };
1617
- const selected = this.defaultItemModel(result.asset.model, key);
1618
- const modelKey = AssetKey.parse("models", selected.model);
1619
- modelKey.root = key.root;
1620
- const model2 = await this.getRaw(modelKey);
1621
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
1622
- return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
1622
+ const load = async (selected) => {
1623
+ if ("parts" in selected) {
1624
+ return { key, parts: await Promise.all(selected.parts.map(load)) };
1625
+ }
1626
+ if ("item" in selected) {
1627
+ const model3 = await this.getItemModel(selected.item, { displayContext: preview.displayContext });
1628
+ if (!model3) throw new Error(`Item ${key.toNamespacedString()} references missing item ${selected.item.toNamespacedString()}`);
1629
+ return model3;
1630
+ }
1631
+ const modelKey = AssetKey.parse("models", selected.model);
1632
+ modelKey.root = key.root;
1633
+ const model2 = await this.getRaw(modelKey);
1634
+ if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
1635
+ return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
1636
+ };
1637
+ return load(this.selectItemModel(result.asset.model, key, preview));
1623
1638
  });
1624
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1639
+ const restore = (model2) => ({
1640
+ ...model2,
1641
+ key: Object.assign(new AssetKey("", ""), model2.key),
1642
+ ...model2.parts && { parts: model2.parts.map(restore) }
1643
+ });
1644
+ return model ? restore(model) : void 0;
1645
+ }
1646
+ static contextIdentifier(id) {
1647
+ if (typeof id !== "string" || !/^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(id)) {
1648
+ throw new Error(`Invalid item-preview identifier: ${id}`);
1649
+ }
1650
+ return id.includes(":") ? id : `minecraft:${id}`;
1651
+ }
1652
+ static snapshotContext(key, context) {
1653
+ const displayContext = context.displayContext ?? "gui" /* GUI */;
1654
+ if (displayContext !== "none" && !Object.values(DisplayPosition).includes(displayContext)) {
1655
+ throw new Error(`Unsupported item display context: ${displayContext}`);
1656
+ }
1657
+ for (const map of [context.properties, context.components, context.itemReferences]) {
1658
+ if (map !== void 0 && (!map || typeof map !== "object" || Array.isArray(map))) {
1659
+ throw new Error("Item-preview properties, components, and references must be objects keyed by identifier");
1660
+ }
1661
+ }
1662
+ const count = context.count === void 0 ? 1 : context.count;
1663
+ if (!Number.isSafeInteger(count) || count < 0) throw new Error("Item-preview count must be a nonnegative safe integer");
1664
+ const properties = {};
1665
+ for (const [id, value] of Object.entries(context.properties ?? {})) {
1666
+ const property = this.contextIdentifier(id);
1667
+ if (!["boolean", "string", "number"].includes(typeof value) || typeof value === "number" && !Number.isFinite(value)) {
1668
+ throw new Error(`Item-preview property ${property} must be a boolean, string, or finite number`);
1669
+ }
1670
+ if (Object.prototype.hasOwnProperty.call(properties, property)) throw new Error(`Duplicate item-preview property: ${property}`);
1671
+ properties[property] = value;
1672
+ }
1673
+ const components = {};
1674
+ for (const [id, value] of Object.entries(context.components ?? {})) {
1675
+ const component = this.contextIdentifier(id);
1676
+ if (Object.prototype.hasOwnProperty.call(components, component)) throw new Error(`Duplicate item-preview component: ${component}`);
1677
+ components[component] = this.snapshotJson(value);
1678
+ }
1679
+ const itemReferences = {};
1680
+ for (const [id, value] of Object.entries(context.itemReferences ?? {})) {
1681
+ const reference = this.contextIdentifier(id);
1682
+ if (!isAssetKey(value) || value.assetType !== "models" || value.type !== "item") {
1683
+ throw new Error(`Item-preview reference ${reference} must be an item-model AssetKey`);
1684
+ }
1685
+ this.contextIdentifier(`${value.namespace}:${value.path}`);
1686
+ if (Object.prototype.hasOwnProperty.call(itemReferences, reference)) throw new Error(`Duplicate item-preview reference: ${reference}`);
1687
+ itemReferences[reference] = Object.assign(new AssetKey("", ""), value, { root: value.root ?? key.root });
1688
+ }
1689
+ return { displayContext, properties, components, count, itemReferences };
1690
+ }
1691
+ static contextKey(context) {
1692
+ const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));
1693
+ return `|item-v3:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;
1625
1694
  }
1626
- // Item previews use the GUI context, false conditions, and zero numeric properties.
1627
- static defaultItemModel(node, key) {
1695
+ static snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
1696
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return value;
1697
+ if (typeof value !== "object" || ancestors.has(value) || !Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
1698
+ throw new Error("Item-preview components must contain finite JSON values without circular references");
1699
+ }
1700
+ ancestors.add(value);
1701
+ const copy = Array.isArray(value) ? Array.from(value, (entry) => this.snapshotJson(entry, ancestors)) : Object.fromEntries(Object.keys(value).sort().map((key) => [key, this.snapshotJson(value[key], ancestors)]));
1702
+ ancestors.delete(value);
1703
+ return copy;
1704
+ }
1705
+ static propertyValue(node, context) {
1706
+ const kind = node.type.replace(/^minecraft:/, "");
1707
+ const property = node.property ? this.contextIdentifier(node.property) : void 0;
1708
+ if (kind === "select" && property === "minecraft:display_context") return context.displayContext;
1709
+ if (property && Object.prototype.hasOwnProperty.call(context.properties, property)) return context.properties[property];
1710
+ const fallback = kind === "condition" ? false : kind === "range_dispatch" ? 0 : void 0;
1711
+ const component = (id) => context.components[this.contextIdentifier(id)];
1712
+ if (property === "minecraft:custom_model_data") {
1713
+ const index = node.index ?? 0;
1714
+ if (!Number.isSafeInteger(index) || index < 0) throw new Error("Item-model custom_model_data index must be a nonnegative integer");
1715
+ const data = component("custom_model_data");
1716
+ if (data === void 0) return fallback;
1717
+ if (!data || typeof data !== "object" || Array.isArray(data)) throw new Error("Item-preview custom_model_data must be an object");
1718
+ const field = kind === "condition" ? "flags" : kind === "select" ? "strings" : "floats";
1719
+ const values = data[field];
1720
+ if (values === void 0) return fallback;
1721
+ if (!Array.isArray(values)) throw new Error(`Item-preview custom_model_data.${field} must be an array`);
1722
+ return index < values.length ? values[index] : fallback;
1723
+ }
1724
+ if (kind === "condition" && property === "minecraft:has_component") {
1725
+ if (node.ignore_default) throw new Error("Item-preview has_component with ignore_default requires an explicit properties override; item defaults are unavailable");
1726
+ return Object.prototype.hasOwnProperty.call(context.components, this.contextIdentifier(node.component));
1727
+ }
1728
+ if (kind === "select") {
1729
+ switch (property) {
1730
+ case "minecraft:component":
1731
+ return component(node.component);
1732
+ case "minecraft:block_state": {
1733
+ const state = component("block_state");
1734
+ if (state === void 0) return void 0;
1735
+ if (!state || typeof state !== "object" || Array.isArray(state)) throw new Error("Item-preview block_state must be an object");
1736
+ if (typeof node.block_state_property !== "string") throw new Error("Item-model block_state requires block_state_property");
1737
+ return Object.prototype.hasOwnProperty.call(state, node.block_state_property) ? state[node.block_state_property] : void 0;
1738
+ }
1739
+ case "minecraft:charge_type": {
1740
+ const projectiles = component("charged_projectiles");
1741
+ if (projectiles === void 0) return "none";
1742
+ if (!Array.isArray(projectiles)) throw new Error("Item-preview charged_projectiles must be an array of item stacks");
1743
+ const ids = projectiles.map((stack) => {
1744
+ if (!stack || typeof stack !== "object" || Array.isArray(stack)) throw new Error("Item-preview charged_projectiles must contain item-stack objects");
1745
+ return this.contextIdentifier(stack.id);
1746
+ });
1747
+ return !ids.length ? "none" : ids.includes("minecraft:firework_rocket") ? "rocket" : "arrow";
1748
+ }
1749
+ }
1750
+ }
1751
+ if (kind === "range_dispatch" && (property === "minecraft:damage" || property === "minecraft:count")) {
1752
+ const damage = property === "minecraft:damage";
1753
+ const maximumComponent = component(damage ? "max_damage" : "max_stack_size");
1754
+ const maximum = maximumComponent === void 0 ? damage ? 0 : 1 : maximumComponent;
1755
+ const damageComponent = component("damage");
1756
+ const value = damage ? damageComponent === void 0 ? 0 : damageComponent : context.count;
1757
+ if (typeof value !== "number" || typeof maximum !== "number" || maximum < 0) throw new Error(`Item-preview ${property} requires numeric components and a nonnegative maximum`);
1758
+ const clamped = Math.max(0, Math.min(maximum, value));
1759
+ return node.normalize === false ? clamped : clamped / maximum;
1760
+ }
1761
+ return fallback;
1762
+ }
1763
+ static selectItemModel(node, key, context) {
1628
1764
  if (!node || typeof node.type !== "string") {
1629
1765
  throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
1630
1766
  }
1631
1767
  switch (node.type.replace(/^minecraft:/, "")) {
1768
+ case "composite":
1769
+ if (Array.isArray(node.models)) return { parts: node.models.map((child) => this.selectItemModel(child, key, context)) };
1770
+ break;
1771
+ case "bundle/selected_item": {
1772
+ const item = context.itemReferences["minecraft:bundle/selected_item"];
1773
+ return item ? { item } : { parts: [] };
1774
+ }
1632
1775
  case "model":
1633
1776
  if (typeof node.model === "string" && node.model) return { model: node.model, tints: node.tints };
1634
1777
  break;
@@ -1649,17 +1792,29 @@ var init_Models = __esm({
1649
1792
  }
1650
1793
  throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);
1651
1794
  }
1652
- case "condition":
1653
- return this.defaultItemModel(node.on_false, key);
1795
+ case "condition": {
1796
+ const value = this.propertyValue(node, context);
1797
+ if (typeof value !== "boolean") throw new Error(`Item-preview condition ${node.property} requires a boolean`);
1798
+ return this.selectItemModel(value ? node.on_true : node.on_false, key, context);
1799
+ }
1654
1800
  case "select": {
1655
- const selected = node.property?.replace(/^minecraft:/, "") === "display_context" ? node.cases?.find((entry) => Array.isArray(entry.when) ? entry.when.includes("gui") : entry.when === "gui")?.model : void 0;
1656
- return this.defaultItemModel(selected ?? node.fallback, key);
1801
+ const value = this.propertyValue(node, context);
1802
+ const component = node.property && this.contextIdentifier(node.property) === "minecraft:component";
1803
+ if (!component && value !== void 0 && typeof value !== "string") throw new Error(`Item-preview selector ${node.property} requires a string`);
1804
+ const matches = (candidate) => component ? JSON.stringify(this.snapshotJson(candidate)) === JSON.stringify(this.snapshotJson(value)) : candidate === value;
1805
+ const selected = value === void 0 ? void 0 : node.cases?.find((entry) => matches(entry.when) || Array.isArray(entry.when) && entry.when.some(matches))?.model;
1806
+ return this.selectItemModel(selected ?? node.fallback, key, context);
1657
1807
  }
1658
1808
  case "range_dispatch": {
1809
+ const value = this.propertyValue(node, context);
1810
+ if (typeof value !== "number") throw new Error(`Item-preview range ${node.property} requires a number`);
1811
+ if (Number.isNaN(value)) return this.selectItemModel(node.fallback, key, context);
1812
+ const scaled = value * (node.scale ?? 1);
1813
+ if (!Number.isFinite(scaled)) throw new Error(`Item-preview range ${node.property} requires a finite value and scale`);
1659
1814
  const selected = node.entries?.reduce((match, entry) => {
1660
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
1815
+ return entry.threshold <= scaled && (!match || entry.threshold >= match.threshold) ? entry : match;
1661
1816
  }, void 0);
1662
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
1817
+ return this.selectItemModel(selected?.model ?? node.fallback, key, context);
1663
1818
  }
1664
1819
  }
1665
1820
  throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
@@ -1686,25 +1841,28 @@ var init_Models = __esm({
1686
1841
  }
1687
1842
  /**
1688
1843
  * Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.
1689
- * Item keys use GUI context, false conditions, and zero numeric properties.
1844
+ * Item keys default to GUI context and a stack count of 1. Unresolved conditions are false and numeric properties are zero.
1845
+ * Pass `context` to supply component values, property overrides, and item references for a preview.
1846
+ * Composite items retain independently merged children in `ItemModel.parts`.
1690
1847
  *
1691
1848
  * @param key - Model key, for example `AssetKey.parse("models", "minecraft:item/diamond_sword")`.
1692
1849
  */
1693
- static async getMerged(key) {
1850
+ static async getMerged(key, context = {}) {
1694
1851
  if (!key.assetType) {
1695
1852
  key.assetType = "models";
1696
1853
  }
1697
1854
  if (!key.extension) {
1698
1855
  key.extension = ".json";
1699
1856
  }
1700
- const keyStr = key.serialize();
1857
+ const preview = this.snapshotContext(key, context);
1858
+ const keyStr = key.serialize() + (key.type === "item" ? this.contextKey(preview) : "");
1701
1859
  return Caching.mergedModelCache.get(keyStr, (k) => {
1702
- return _Models.loadAndMerge(key);
1860
+ return _Models.loadAndMerge(key, preview);
1703
1861
  });
1704
1862
  }
1705
1863
  /** Alias for {@link getMerged}. */
1706
- static async get(key) {
1707
- return this.getMerged(key);
1864
+ static async get(key, context = {}) {
1865
+ return this.getMerged(key, context);
1708
1866
  }
1709
1867
  /** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */
1710
1868
  static async clearCache() {
@@ -5583,9 +5741,10 @@ var init_ModelObject = __esm({
5583
5741
  this.originalModel = originalModel;
5584
5742
  this.isModelObject = true;
5585
5743
  this.specialMaterials = /* @__PURE__ */ new Map();
5744
+ this.geometries = /* @__PURE__ */ new Set();
5586
5745
  this.meshesCreated = false;
5587
5746
  this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
5588
- if (originalModel.special) this.options.instanceMeshes = false;
5747
+ if (originalModel.special || originalModel.parts) this.options.instanceMeshes = false;
5589
5748
  if (this.options.tints) this.options.tints = { ...this.options.tints };
5590
5749
  this.addEventListener("added", () => this.updateAnimationSubscription());
5591
5750
  this.addEventListener("removed", () => this.updateAnimationSubscription());
@@ -5594,14 +5753,36 @@ var init_ModelObject = __esm({
5594
5753
  this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
5595
5754
  }
5596
5755
  async init() {
5756
+ const parts = this.originalModel.parts;
5757
+ if (parts) {
5758
+ try {
5759
+ for (const part of parts) {
5760
+ const object3 = new _ModelObject(part, { ...this.options, instanceMeshes: false });
5761
+ this.add(object3);
5762
+ await object3.init();
5763
+ }
5764
+ let order = 0;
5765
+ this.iterateAllMeshes((mesh) => {
5766
+ mesh.renderOrder = order++;
5767
+ for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
5768
+ material.transparent = true;
5769
+ }
5770
+ });
5771
+ } catch (error) {
5772
+ this.disposeAndRemoveAllChildren();
5773
+ throw error;
5774
+ }
5775
+ this.notifyDirty();
5776
+ return;
5777
+ }
5597
5778
  this.options.tints = await ItemTints.get(this.originalModel, this.options.tints);
5598
5779
  const special = this.originalModel.special;
5599
5780
  if (special) {
5600
- const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
5781
+ const parts2 = await SpecialItems.getParts(special, this.originalModel.key?.root);
5601
5782
  const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new Matrix49();
5602
5783
  transform.multiply(new Matrix49().makeTranslation(-8, -8, -8));
5603
5784
  try {
5604
- for (const part of parts) {
5785
+ for (const part of parts2) {
5605
5786
  const object3 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
5606
5787
  object3.matrix.copy(transform).multiply(part.transform);
5607
5788
  object3.matrixWorldNeedsUpdate = true;
@@ -5652,6 +5833,7 @@ var init_ModelObject = __esm({
5652
5833
  if (this.atlas.model.elements) {
5653
5834
  this.atlas.model.elements?.forEach((el) => {
5654
5835
  const elGeo = this._getBoxGeometryFromElement(el).clone();
5836
+ this.geometries.add(elGeo);
5655
5837
  if (this.options.cullMask) {
5656
5838
  const indices = Array.from(elGeo.getIndex().array);
5657
5839
  elGeo.setIndex(indices.filter((_, index) => {
@@ -5705,10 +5887,14 @@ var init_ModelObject = __esm({
5705
5887
  let combinedGeo;
5706
5888
  if (allGeos.length > 0) {
5707
5889
  combinedGeo = mergeBufferGeometries(allGeos);
5890
+ for (const geometry of allGeos) {
5891
+ this.geometries.delete(geometry);
5892
+ }
5708
5893
  } else {
5709
5894
  combinedGeo = new BoxGeometry5(16, 16, 16);
5710
5895
  if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
5711
5896
  }
5897
+ this.geometries.add(combinedGeo);
5712
5898
  combinedGeo.computeBoundingBox();
5713
5899
  let mesh;
5714
5900
  if (this.options.instanceMeshes) {
@@ -5733,6 +5919,9 @@ var init_ModelObject = __esm({
5733
5919
  const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas, this.atlas.hasTransparency, false, true);
5734
5920
  this.atlasMaterial = mat;
5735
5921
  this.atlasTexture = mat.uniforms?.map?.value ?? mat.map;
5922
+ if (this.options.displayPosition === "gui" /* GUI */ && this.originalModel.gui_light === "front" /* FRONT */ && mat.uniforms?.SHADE) {
5923
+ mat.uniforms.SHADE.value = false;
5924
+ }
5736
5925
  this.iterateAllMeshes((mesh) => {
5737
5926
  if (mesh.geometry.hasAttribute("color")) mat.vertexColors = true;
5738
5927
  mesh.material = mat;
@@ -5741,7 +5930,9 @@ var init_ModelObject = __esm({
5741
5930
  }
5742
5931
  }
5743
5932
  updateAnimationSubscription() {
5744
- const active = !!this.parent && (!this.isInstanced || this.instanceCounter > 0);
5933
+ let root = this;
5934
+ while (root.parent && isModelObject(root.parent)) root = root.parent;
5935
+ const active = !!root.parent && (!this.isInstanced || this.instanceCounter > 0);
5745
5936
  if (active && this.atlas?.hasAnimation && this.atlasTexture) {
5746
5937
  if (!this.unsubscribeAtlas) {
5747
5938
  this.atlasTexture.needsUpdate = true;
@@ -5757,6 +5948,9 @@ var init_ModelObject = __esm({
5757
5948
  this.unsubscribeAtlas?.();
5758
5949
  this.unsubscribeAtlas = void 0;
5759
5950
  }
5951
+ for (const child of this.children) {
5952
+ if (isModelObject(child)) child.updateAnimationSubscription();
5953
+ }
5760
5954
  }
5761
5955
  nextInstance() {
5762
5956
  const reference = super.nextInstance();
@@ -5776,6 +5970,8 @@ var init_ModelObject = __esm({
5776
5970
  this.atlasMaterial = void 0;
5777
5971
  for (const material of this.specialMaterials.values()) material.dispose();
5778
5972
  this.specialMaterials.clear();
5973
+ for (const geometry of this.geometries) geometry.dispose();
5974
+ this.geometries.clear();
5779
5975
  super.disposeAndRemoveAllChildren();
5780
5976
  }
5781
5977
  };
@@ -9729,7 +9925,6 @@ init_SceneObject();
9729
9925
  init_Materials();
9730
9926
  init_ModelObject();
9731
9927
  init_DisplayPosition();
9732
- init_GuiLight();
9733
9928
  import { Box2, Box3 as Box32, DoubleSide as DoubleSide3, Group, Matrix4 as Matrix410, Mesh as Mesh6, MeshBasicMaterial as MeshBasicMaterial5, Vector2 as Vector23 } from "three";
9734
9929
  var GuiObject = class extends SceneObject {
9735
9930
  constructor(textureLayers, options) {
@@ -9798,12 +9993,16 @@ var GuiObject = class extends SceneObject {
9798
9993
  mesh2.geometry.computeBoundingBox();
9799
9994
  bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new Matrix410().multiplyMatrices(inverse, mesh2.matrixWorld)));
9800
9995
  });
9801
- item.position.z = depth - bounds.min.z;
9802
- depth += bounds.max.z - bounds.min.z + 0.01;
9996
+ item.position.z = depth;
9997
+ if (!bounds.isEmpty()) {
9998
+ item.position.z -= bounds.min.z;
9999
+ depth += bounds.max.z - bounds.min.z;
10000
+ this.bounds.expandByPoint(new Vector23(bounds.min.x, -bounds.max.y));
10001
+ this.bounds.expandByPoint(new Vector23(bounds.max.x, -bounds.min.y));
10002
+ }
10003
+ depth += 0.01;
9803
10004
  this.bounds.expandByPoint(new Vector23(x, y));
9804
10005
  this.bounds.expandByPoint(new Vector23(x + width2, y + height2));
9805
- this.bounds.expandByPoint(new Vector23(bounds.min.x, -bounds.max.y));
9806
- this.bounds.expandByPoint(new Vector23(bounds.max.x, -bounds.min.y));
9807
10006
  continue;
9808
10007
  }
9809
10008
  const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
@@ -9843,15 +10042,13 @@ var GuiObject = class extends SceneObject {
9843
10042
  item.name = `group:${layer.name ?? index}`;
9844
10043
  this.add(item);
9845
10044
  await item.init();
9846
- item.iterateAllMeshes((mesh) => {
9847
- if (!model.special) this.geometries.add(mesh.geometry);
10045
+ const meshes = [];
10046
+ item.iterateAllMeshes((mesh) => meshes.push(mesh));
10047
+ meshes.forEach((mesh, partIndex) => {
9848
10048
  mesh.name = `mesh:${layer.name ?? index}`;
9849
- mesh.renderOrder = index;
10049
+ mesh.renderOrder = index + partIndex / (meshes.length + 1) * 0.5;
9850
10050
  for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
9851
10051
  material.transparent = true;
9852
- if (model.gui_light === "front" /* FRONT */ && material.uniforms?.SHADE) {
9853
- material.uniforms.SHADE.value = false;
9854
- }
9855
10052
  }
9856
10053
  });
9857
10054
  return item;