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.
package/dist/bundle.js CHANGED
@@ -43053,6 +43053,8 @@ void main() {
43053
43053
  ModelMerger = class {
43054
43054
  /** Loads the parent chain and returns a merged model without modifying the supplied definition. */
43055
43055
  static async mergeWithParents(model) {
43056
+ const parts = model.parts;
43057
+ if (parts) return { ...model, parts: await Promise.all(parts.map((part) => this.mergeWithParents(part))) };
43056
43058
  const models = await this.collectAllParents(model);
43057
43059
  let merged = {};
43058
43060
  for (const source of [...models, model]) {
@@ -43119,6 +43121,7 @@ void main() {
43119
43121
  init_PersistentCache();
43120
43122
  init_AssetKey();
43121
43123
  init_AssetParsers();
43124
+ init_DisplayPosition();
43122
43125
  Models = class _Models {
43123
43126
  // opened lazily: touching the store at import time would hit IndexedDB/disk just for loading
43124
43127
  // the library, and would require an EnvProvider before any entry has had a chance to register
@@ -43133,34 +43136,174 @@ void main() {
43133
43136
  return (await AssetLoader.getFirst([key, legacyKey], "list" /* LIST */))?.asset;
43134
43137
  }).then((r5) => r5?.files ?? []);
43135
43138
  }
43136
- static async loadAndMerge(key) {
43137
- const model = key.type === "item" ? await this.getItemModel(key) : await this.getRaw(key);
43139
+ static async loadAndMerge(key, context = {}) {
43140
+ const model = key.type === "item" ? await this.getItemModel(key, context) : await this.getRaw(key);
43138
43141
  if (!model) {
43139
43142
  return void 0;
43140
43143
  }
43141
43144
  return ModelMerger.mergeWithParents(model);
43142
43145
  }
43143
- static async getItemModel(key) {
43146
+ static async getItemModel(key, context = {}) {
43147
+ const preview = this.snapshotContext(key, context);
43144
43148
  const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
43145
- const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v2:${AssetLoader.persistentKey(itemKey.serialize())}`, async () => {
43149
+ const cacheKey = itemKey.serialize() + this.contextKey(preview);
43150
+ const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v3:${AssetLoader.persistentKey(cacheKey)}`, async () => {
43146
43151
  const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
43147
43152
  if (!result) return void 0;
43148
43153
  if (result.key.assetType !== "items") return { ...result.asset, key };
43149
- const selected = this.defaultItemModel(result.asset.model, key);
43150
- const modelKey = AssetKey.parse("models", selected.model);
43151
- modelKey.root = key.root;
43152
- const model2 = await this.getRaw(modelKey);
43153
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
43154
- return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
43154
+ const load = async (selected) => {
43155
+ if ("parts" in selected) {
43156
+ return { key, parts: await Promise.all(selected.parts.map(load)) };
43157
+ }
43158
+ if ("item" in selected) {
43159
+ const model3 = await this.getItemModel(selected.item, { displayContext: preview.displayContext });
43160
+ if (!model3) throw new Error(`Item ${key.toNamespacedString()} references missing item ${selected.item.toNamespacedString()}`);
43161
+ return model3;
43162
+ }
43163
+ const modelKey = AssetKey.parse("models", selected.model);
43164
+ modelKey.root = key.root;
43165
+ const model2 = await this.getRaw(modelKey);
43166
+ if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
43167
+ return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
43168
+ };
43169
+ return load(this.selectItemModel(result.asset.model, key, preview));
43170
+ });
43171
+ const restore = (model2) => ({
43172
+ ...model2,
43173
+ key: Object.assign(new AssetKey("", ""), model2.key),
43174
+ ...model2.parts && { parts: model2.parts.map(restore) }
43155
43175
  });
43156
- return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
43176
+ return model ? restore(model) : void 0;
43177
+ }
43178
+ static contextIdentifier(id) {
43179
+ if (typeof id !== "string" || !/^(?:[a-z0-9_.-]+:)?[a-z0-9_./-]+$/.test(id)) {
43180
+ throw new Error(`Invalid item-preview identifier: ${id}`);
43181
+ }
43182
+ return id.includes(":") ? id : `minecraft:${id}`;
43183
+ }
43184
+ static snapshotContext(key, context) {
43185
+ const displayContext = context.displayContext ?? "gui" /* GUI */;
43186
+ if (displayContext !== "none" && !Object.values(DisplayPosition).includes(displayContext)) {
43187
+ throw new Error(`Unsupported item display context: ${displayContext}`);
43188
+ }
43189
+ for (const map of [context.properties, context.components, context.itemReferences]) {
43190
+ if (map !== void 0 && (!map || typeof map !== "object" || Array.isArray(map))) {
43191
+ throw new Error("Item-preview properties, components, and references must be objects keyed by identifier");
43192
+ }
43193
+ }
43194
+ const count = context.count === void 0 ? 1 : context.count;
43195
+ if (!Number.isSafeInteger(count) || count < 0) throw new Error("Item-preview count must be a nonnegative safe integer");
43196
+ const properties = {};
43197
+ for (const [id, value] of Object.entries(context.properties ?? {})) {
43198
+ const property = this.contextIdentifier(id);
43199
+ if (!["boolean", "string", "number"].includes(typeof value) || typeof value === "number" && !Number.isFinite(value)) {
43200
+ throw new Error(`Item-preview property ${property} must be a boolean, string, or finite number`);
43201
+ }
43202
+ if (Object.prototype.hasOwnProperty.call(properties, property)) throw new Error(`Duplicate item-preview property: ${property}`);
43203
+ properties[property] = value;
43204
+ }
43205
+ const components = {};
43206
+ for (const [id, value] of Object.entries(context.components ?? {})) {
43207
+ const component = this.contextIdentifier(id);
43208
+ if (Object.prototype.hasOwnProperty.call(components, component)) throw new Error(`Duplicate item-preview component: ${component}`);
43209
+ components[component] = this.snapshotJson(value);
43210
+ }
43211
+ const itemReferences = {};
43212
+ for (const [id, value] of Object.entries(context.itemReferences ?? {})) {
43213
+ const reference = this.contextIdentifier(id);
43214
+ if (!isAssetKey(value) || value.assetType !== "models" || value.type !== "item") {
43215
+ throw new Error(`Item-preview reference ${reference} must be an item-model AssetKey`);
43216
+ }
43217
+ this.contextIdentifier(`${value.namespace}:${value.path}`);
43218
+ if (Object.prototype.hasOwnProperty.call(itemReferences, reference)) throw new Error(`Duplicate item-preview reference: ${reference}`);
43219
+ itemReferences[reference] = Object.assign(new AssetKey("", ""), value, { root: value.root ?? key.root });
43220
+ }
43221
+ return { displayContext, properties, components, count, itemReferences };
43222
+ }
43223
+ static contextKey(context) {
43224
+ const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));
43225
+ return `|item-v3:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;
43226
+ }
43227
+ static snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
43228
+ if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return value;
43229
+ if (typeof value !== "object" || ancestors.has(value) || !Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
43230
+ throw new Error("Item-preview components must contain finite JSON values without circular references");
43231
+ }
43232
+ ancestors.add(value);
43233
+ 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)]));
43234
+ ancestors.delete(value);
43235
+ return copy;
43236
+ }
43237
+ static propertyValue(node, context) {
43238
+ const kind = node.type.replace(/^minecraft:/, "");
43239
+ const property = node.property ? this.contextIdentifier(node.property) : void 0;
43240
+ if (kind === "select" && property === "minecraft:display_context") return context.displayContext;
43241
+ if (property && Object.prototype.hasOwnProperty.call(context.properties, property)) return context.properties[property];
43242
+ const fallback = kind === "condition" ? false : kind === "range_dispatch" ? 0 : void 0;
43243
+ const component = (id) => context.components[this.contextIdentifier(id)];
43244
+ if (property === "minecraft:custom_model_data") {
43245
+ const index = node.index ?? 0;
43246
+ if (!Number.isSafeInteger(index) || index < 0) throw new Error("Item-model custom_model_data index must be a nonnegative integer");
43247
+ const data = component("custom_model_data");
43248
+ if (data === void 0) return fallback;
43249
+ if (!data || typeof data !== "object" || Array.isArray(data)) throw new Error("Item-preview custom_model_data must be an object");
43250
+ const field = kind === "condition" ? "flags" : kind === "select" ? "strings" : "floats";
43251
+ const values = data[field];
43252
+ if (values === void 0) return fallback;
43253
+ if (!Array.isArray(values)) throw new Error(`Item-preview custom_model_data.${field} must be an array`);
43254
+ return index < values.length ? values[index] : fallback;
43255
+ }
43256
+ if (kind === "condition" && property === "minecraft:has_component") {
43257
+ if (node.ignore_default) throw new Error("Item-preview has_component with ignore_default requires an explicit properties override; item defaults are unavailable");
43258
+ return Object.prototype.hasOwnProperty.call(context.components, this.contextIdentifier(node.component));
43259
+ }
43260
+ if (kind === "select") {
43261
+ switch (property) {
43262
+ case "minecraft:component":
43263
+ return component(node.component);
43264
+ case "minecraft:block_state": {
43265
+ const state = component("block_state");
43266
+ if (state === void 0) return void 0;
43267
+ if (!state || typeof state !== "object" || Array.isArray(state)) throw new Error("Item-preview block_state must be an object");
43268
+ if (typeof node.block_state_property !== "string") throw new Error("Item-model block_state requires block_state_property");
43269
+ return Object.prototype.hasOwnProperty.call(state, node.block_state_property) ? state[node.block_state_property] : void 0;
43270
+ }
43271
+ case "minecraft:charge_type": {
43272
+ const projectiles = component("charged_projectiles");
43273
+ if (projectiles === void 0) return "none";
43274
+ if (!Array.isArray(projectiles)) throw new Error("Item-preview charged_projectiles must be an array of item stacks");
43275
+ const ids = projectiles.map((stack) => {
43276
+ if (!stack || typeof stack !== "object" || Array.isArray(stack)) throw new Error("Item-preview charged_projectiles must contain item-stack objects");
43277
+ return this.contextIdentifier(stack.id);
43278
+ });
43279
+ return !ids.length ? "none" : ids.includes("minecraft:firework_rocket") ? "rocket" : "arrow";
43280
+ }
43281
+ }
43282
+ }
43283
+ if (kind === "range_dispatch" && (property === "minecraft:damage" || property === "minecraft:count")) {
43284
+ const damage = property === "minecraft:damage";
43285
+ const maximumComponent = component(damage ? "max_damage" : "max_stack_size");
43286
+ const maximum = maximumComponent === void 0 ? damage ? 0 : 1 : maximumComponent;
43287
+ const damageComponent = component("damage");
43288
+ const value = damage ? damageComponent === void 0 ? 0 : damageComponent : context.count;
43289
+ if (typeof value !== "number" || typeof maximum !== "number" || maximum < 0) throw new Error(`Item-preview ${property} requires numeric components and a nonnegative maximum`);
43290
+ const clamped = Math.max(0, Math.min(maximum, value));
43291
+ return node.normalize === false ? clamped : clamped / maximum;
43292
+ }
43293
+ return fallback;
43157
43294
  }
43158
- // Item previews use the GUI context, false conditions, and zero numeric properties.
43159
- static defaultItemModel(node, key) {
43295
+ static selectItemModel(node, key, context) {
43160
43296
  if (!node || typeof node.type !== "string") {
43161
43297
  throw new Error(`Unsupported item model definition for ${key.toNamespacedString()}`);
43162
43298
  }
43163
43299
  switch (node.type.replace(/^minecraft:/, "")) {
43300
+ case "composite":
43301
+ if (Array.isArray(node.models)) return { parts: node.models.map((child) => this.selectItemModel(child, key, context)) };
43302
+ break;
43303
+ case "bundle/selected_item": {
43304
+ const item = context.itemReferences["minecraft:bundle/selected_item"];
43305
+ return item ? { item } : { parts: [] };
43306
+ }
43164
43307
  case "model":
43165
43308
  if (typeof node.model === "string" && node.model) return { model: node.model, tints: node.tints };
43166
43309
  break;
@@ -43181,17 +43324,29 @@ void main() {
43181
43324
  }
43182
43325
  throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);
43183
43326
  }
43184
- case "condition":
43185
- return this.defaultItemModel(node.on_false, key);
43327
+ case "condition": {
43328
+ const value = this.propertyValue(node, context);
43329
+ if (typeof value !== "boolean") throw new Error(`Item-preview condition ${node.property} requires a boolean`);
43330
+ return this.selectItemModel(value ? node.on_true : node.on_false, key, context);
43331
+ }
43186
43332
  case "select": {
43187
- 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;
43188
- return this.defaultItemModel(selected ?? node.fallback, key);
43333
+ const value = this.propertyValue(node, context);
43334
+ const component = node.property && this.contextIdentifier(node.property) === "minecraft:component";
43335
+ if (!component && value !== void 0 && typeof value !== "string") throw new Error(`Item-preview selector ${node.property} requires a string`);
43336
+ const matches = (candidate) => component ? JSON.stringify(this.snapshotJson(candidate)) === JSON.stringify(this.snapshotJson(value)) : candidate === value;
43337
+ const selected = value === void 0 ? void 0 : node.cases?.find((entry) => matches(entry.when) || Array.isArray(entry.when) && entry.when.some(matches))?.model;
43338
+ return this.selectItemModel(selected ?? node.fallback, key, context);
43189
43339
  }
43190
43340
  case "range_dispatch": {
43341
+ const value = this.propertyValue(node, context);
43342
+ if (typeof value !== "number") throw new Error(`Item-preview range ${node.property} requires a number`);
43343
+ if (Number.isNaN(value)) return this.selectItemModel(node.fallback, key, context);
43344
+ const scaled = value * (node.scale ?? 1);
43345
+ if (!Number.isFinite(scaled)) throw new Error(`Item-preview range ${node.property} requires a finite value and scale`);
43191
43346
  const selected = node.entries?.reduce((match, entry) => {
43192
- return entry.threshold <= 0 && (!match || entry.threshold >= match.threshold) ? entry : match;
43347
+ return entry.threshold <= scaled && (!match || entry.threshold >= match.threshold) ? entry : match;
43193
43348
  }, void 0);
43194
- return this.defaultItemModel(selected?.model ?? node.fallback, key);
43349
+ return this.selectItemModel(selected?.model ?? node.fallback, key, context);
43195
43350
  }
43196
43351
  }
43197
43352
  throw new Error(`Unsupported item model ${node?.type ?? "definition"} for ${key.toNamespacedString()}`);
@@ -43218,25 +43373,28 @@ void main() {
43218
43373
  }
43219
43374
  /**
43220
43375
  * Loads a model and resolves its parent chain. Returns `undefined` when the model is missing.
43221
- * Item keys use GUI context, false conditions, and zero numeric properties.
43376
+ * Item keys default to GUI context and a stack count of 1. Unresolved conditions are false and numeric properties are zero.
43377
+ * Pass `context` to supply component values, property overrides, and item references for a preview.
43378
+ * Composite items retain independently merged children in `ItemModel.parts`.
43222
43379
  *
43223
43380
  * @param key - Model key, for example `AssetKey.parse("models", "minecraft:item/diamond_sword")`.
43224
43381
  */
43225
- static async getMerged(key) {
43382
+ static async getMerged(key, context = {}) {
43226
43383
  if (!key.assetType) {
43227
43384
  key.assetType = "models";
43228
43385
  }
43229
43386
  if (!key.extension) {
43230
43387
  key.extension = ".json";
43231
43388
  }
43232
- const keyStr = key.serialize();
43389
+ const preview = this.snapshotContext(key, context);
43390
+ const keyStr = key.serialize() + (key.type === "item" ? this.contextKey(preview) : "");
43233
43391
  return Caching.mergedModelCache.get(keyStr, (k4) => {
43234
- return _Models.loadAndMerge(key);
43392
+ return _Models.loadAndMerge(key, preview);
43235
43393
  });
43236
43394
  }
43237
43395
  /** Alias for {@link getMerged}. */
43238
- static async get(key) {
43239
- return this.getMerged(key);
43396
+ static async get(key, context = {}) {
43397
+ return this.getMerged(key, context);
43240
43398
  }
43241
43399
  /** Clears persisted models. Use {@link Caching.clear} to also discard in-memory assets. */
43242
43400
  static async clearCache() {
@@ -90454,22 +90612,45 @@ ${shader.fragmentShader}`.replace(
90454
90612
  this.originalModel = originalModel;
90455
90613
  this.isModelObject = true;
90456
90614
  this.specialMaterials = /* @__PURE__ */ new Map();
90615
+ this.geometries = /* @__PURE__ */ new Set();
90457
90616
  this.meshesCreated = false;
90458
90617
  this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
90459
- if (originalModel.special) this.options.instanceMeshes = false;
90618
+ if (originalModel.special || originalModel.parts) this.options.instanceMeshes = false;
90460
90619
  if (this.options.tints) this.options.tints = { ...this.options.tints };
90461
90620
  this.addEventListener("added", () => this.updateAnimationSubscription());
90462
90621
  this.addEventListener("removed", () => this.updateAnimationSubscription());
90463
90622
  }
90464
90623
  async init() {
90624
+ const parts = this.originalModel.parts;
90625
+ if (parts) {
90626
+ try {
90627
+ for (const part of parts) {
90628
+ const object3 = new _ModelObject(part, { ...this.options, instanceMeshes: false });
90629
+ this.add(object3);
90630
+ await object3.init();
90631
+ }
90632
+ let order = 0;
90633
+ this.iterateAllMeshes((mesh) => {
90634
+ mesh.renderOrder = order++;
90635
+ for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
90636
+ material.transparent = true;
90637
+ }
90638
+ });
90639
+ } catch (error2) {
90640
+ this.disposeAndRemoveAllChildren();
90641
+ throw error2;
90642
+ }
90643
+ this.notifyDirty();
90644
+ return;
90645
+ }
90465
90646
  this.options.tints = await ItemTints.get(this.originalModel, this.options.tints);
90466
90647
  const special = this.originalModel.special;
90467
90648
  if (special) {
90468
- const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
90649
+ const parts2 = await SpecialItems.getParts(special, this.originalModel.key?.root);
90469
90650
  const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new Matrix4();
90470
90651
  transform.multiply(new Matrix4().makeTranslation(-8, -8, -8));
90471
90652
  try {
90472
- for (const part of parts) {
90653
+ for (const part of parts2) {
90473
90654
  const object3 = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
90474
90655
  object3.matrix.copy(transform).multiply(part.transform);
90475
90656
  object3.matrixWorldNeedsUpdate = true;
@@ -90520,6 +90701,7 @@ ${shader.fragmentShader}`.replace(
90520
90701
  if (this.atlas.model.elements) {
90521
90702
  this.atlas.model.elements?.forEach((el) => {
90522
90703
  const elGeo = this._getBoxGeometryFromElement(el).clone();
90704
+ this.geometries.add(elGeo);
90523
90705
  if (this.options.cullMask) {
90524
90706
  const indices = Array.from(elGeo.getIndex().array);
90525
90707
  elGeo.setIndex(indices.filter((_4, index) => {
@@ -90573,10 +90755,14 @@ ${shader.fragmentShader}`.replace(
90573
90755
  let combinedGeo;
90574
90756
  if (allGeos.length > 0) {
90575
90757
  combinedGeo = mergeBufferGeometries(allGeos);
90758
+ for (const geometry of allGeos) {
90759
+ this.geometries.delete(geometry);
90760
+ }
90576
90761
  } else {
90577
90762
  combinedGeo = new BoxGeometry(16, 16, 16);
90578
90763
  if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
90579
90764
  }
90765
+ this.geometries.add(combinedGeo);
90580
90766
  combinedGeo.computeBoundingBox();
90581
90767
  let mesh;
90582
90768
  if (this.options.instanceMeshes) {
@@ -90601,6 +90787,9 @@ ${shader.fragmentShader}`.replace(
90601
90787
  const mat = Materials.createShadedCanvasMaterial(this.atlas.image.canvas, this.atlas.hasTransparency, false, true);
90602
90788
  this.atlasMaterial = mat;
90603
90789
  this.atlasTexture = mat.uniforms?.map?.value ?? mat.map;
90790
+ if (this.options.displayPosition === "gui" /* GUI */ && this.originalModel.gui_light === "front" /* FRONT */ && mat.uniforms?.SHADE) {
90791
+ mat.uniforms.SHADE.value = false;
90792
+ }
90604
90793
  this.iterateAllMeshes((mesh) => {
90605
90794
  if (mesh.geometry.hasAttribute("color")) mat.vertexColors = true;
90606
90795
  mesh.material = mat;
@@ -90609,7 +90798,9 @@ ${shader.fragmentShader}`.replace(
90609
90798
  }
90610
90799
  }
90611
90800
  updateAnimationSubscription() {
90612
- const active = !!this.parent && (!this.isInstanced || this.instanceCounter > 0);
90801
+ let root = this;
90802
+ while (root.parent && isModelObject(root.parent)) root = root.parent;
90803
+ const active = !!root.parent && (!this.isInstanced || this.instanceCounter > 0);
90613
90804
  if (active && this.atlas?.hasAnimation && this.atlasTexture) {
90614
90805
  if (!this.unsubscribeAtlas) {
90615
90806
  this.atlasTexture.needsUpdate = true;
@@ -90625,6 +90816,9 @@ ${shader.fragmentShader}`.replace(
90625
90816
  this.unsubscribeAtlas?.();
90626
90817
  this.unsubscribeAtlas = void 0;
90627
90818
  }
90819
+ for (const child of this.children) {
90820
+ if (isModelObject(child)) child.updateAnimationSubscription();
90821
+ }
90628
90822
  }
90629
90823
  nextInstance() {
90630
90824
  const reference = super.nextInstance();
@@ -90644,6 +90838,8 @@ ${shader.fragmentShader}`.replace(
90644
90838
  this.atlasMaterial = void 0;
90645
90839
  for (const material of this.specialMaterials.values()) material.dispose();
90646
90840
  this.specialMaterials.clear();
90841
+ for (const geometry of this.geometries) geometry.dispose();
90842
+ this.geometries.clear();
90647
90843
  super.disposeAndRemoveAllChildren();
90648
90844
  }
90649
90845
  };
@@ -97773,7 +97969,6 @@ property list uchar int vertex_index
97773
97969
  init_Materials();
97774
97970
  init_ModelObject();
97775
97971
  init_DisplayPosition();
97776
- init_GuiLight();
97777
97972
  var GuiObject = class extends SceneObject {
97778
97973
  constructor(textureLayers, options) {
97779
97974
  super({ ...options, instanceMeshes: false, mergeMeshes: false });
@@ -97841,12 +98036,16 @@ property list uchar int vertex_index
97841
98036
  mesh2.geometry.computeBoundingBox();
97842
98037
  bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
97843
98038
  });
97844
- item.position.z = depth - bounds.min.z;
97845
- depth += bounds.max.z - bounds.min.z + 0.01;
98039
+ item.position.z = depth;
98040
+ if (!bounds.isEmpty()) {
98041
+ item.position.z -= bounds.min.z;
98042
+ depth += bounds.max.z - bounds.min.z;
98043
+ this.bounds.expandByPoint(new Vector2(bounds.min.x, -bounds.max.y));
98044
+ this.bounds.expandByPoint(new Vector2(bounds.max.x, -bounds.min.y));
98045
+ }
98046
+ depth += 0.01;
97846
98047
  this.bounds.expandByPoint(new Vector2(x4, y5));
97847
98048
  this.bounds.expandByPoint(new Vector2(x4 + width2, y5 + height2));
97848
- this.bounds.expandByPoint(new Vector2(bounds.min.x, -bounds.max.y));
97849
- this.bounds.expandByPoint(new Vector2(bounds.max.x, -bounds.min.y));
97850
98049
  continue;
97851
98050
  }
97852
98051
  const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
@@ -97886,15 +98085,13 @@ property list uchar int vertex_index
97886
98085
  item.name = `group:${layer.name ?? index}`;
97887
98086
  this.add(item);
97888
98087
  await item.init();
97889
- item.iterateAllMeshes((mesh) => {
97890
- if (!model.special) this.geometries.add(mesh.geometry);
98088
+ const meshes = [];
98089
+ item.iterateAllMeshes((mesh) => meshes.push(mesh));
98090
+ meshes.forEach((mesh, partIndex) => {
97891
98091
  mesh.name = `mesh:${layer.name ?? index}`;
97892
- mesh.renderOrder = index;
98092
+ mesh.renderOrder = index + partIndex / (meshes.length + 1) * 0.5;
97893
98093
  for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
97894
98094
  material.transparent = true;
97895
- if (model.gui_light === "front" /* FRONT */ && material.uniforms?.SHADE) {
97896
- material.uniforms.SHADE.value = false;
97897
- }
97898
98095
  }
97899
98096
  });
97900
98097
  return item;