minerender 2.1.0-alpha.79 → 2.1.0-alpha.80

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
@@ -43066,6 +43066,7 @@ void main() {
43066
43066
  }
43067
43067
  merged.hierarchy = models.map((m4) => m4.parent).filter((p13) => `${p13}`);
43068
43068
  merged.hierarchy.push(`${merged.parent}`);
43069
+ if (model.components) merged.components = model.components;
43069
43070
  return merged;
43070
43071
  }
43071
43072
  static async collectAllParents(model) {
@@ -43147,10 +43148,10 @@ void main() {
43147
43148
  const preview = this.snapshotContext(key, context);
43148
43149
  const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
43149
43150
  const cacheKey = itemKey.serialize() + this.contextKey(preview);
43150
- const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v3:${AssetLoader.persistentKey(cacheKey)}`, async () => {
43151
+ const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v4:${AssetLoader.persistentKey(cacheKey)}`, async () => {
43151
43152
  const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
43152
43153
  if (!result) return void 0;
43153
- if (result.key.assetType !== "items") return { ...result.asset, key };
43154
+ if (result.key.assetType !== "items") return { ...result.asset, key, components: preview.components };
43154
43155
  const load = async (selected) => {
43155
43156
  if ("parts" in selected) {
43156
43157
  return { key, parts: await Promise.all(selected.parts.map(load)) };
@@ -43164,7 +43165,7 @@ void main() {
43164
43165
  modelKey.root = key.root;
43165
43166
  const model2 = await this.getRaw(modelKey);
43166
43167
  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
+ return { ...model2, components: preview.components, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
43168
43169
  };
43169
43170
  return load(this.selectItemModel(result.asset.model, key, preview));
43170
43171
  });
@@ -43222,7 +43223,7 @@ void main() {
43222
43223
  }
43223
43224
  static contextKey(context) {
43224
43225
  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
+ return `|item-v4:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;
43226
43227
  }
43227
43228
  static snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
43228
43229
  if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return value;
@@ -90538,6 +90539,7 @@ ${shader.fragmentShader}`.replace(
90538
90539
  static async get(model, tints) {
90539
90540
  const sources = model.tints;
90540
90541
  if (!sources?.length) return tints;
90542
+ const components = model.components ?? {};
90541
90543
  const colors = { ...tints };
90542
90544
  await Promise.all(sources.map(async (source, index) => {
90543
90545
  if (colors[index] !== void 0) return;
@@ -90552,27 +90554,71 @@ ${shader.fragmentShader}`.replace(
90552
90554
  break;
90553
90555
  case "dye":
90554
90556
  case "minecraft:dye":
90557
+ colors[index] = this.colorOrDefault(components["minecraft:dyed_color"], source.default, true);
90558
+ break;
90555
90559
  case "potion":
90556
- case "minecraft:potion":
90560
+ case "minecraft:potion": {
90561
+ const value = typeof components["minecraft:potion_contents"] === "string" ? void 0 : this.componentField(components, "potion_contents", "custom_color");
90562
+ colors[index] = this.colorOrDefault(value, source.default);
90563
+ break;
90564
+ }
90557
90565
  case "map_color":
90558
90566
  case "minecraft:map_color":
90567
+ colors[index] = this.colorOrDefault(components["minecraft:map_color"], source.default);
90568
+ break;
90559
90569
  case "firework":
90560
- case "minecraft:firework":
90570
+ case "minecraft:firework": {
90571
+ const values = this.componentField(components, "firework_explosion", "colors");
90572
+ if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint firework_explosion.colors must be an array");
90573
+ if (!values?.length) {
90574
+ colors[index] = this.rgb(source.default);
90575
+ break;
90576
+ }
90577
+ const rgb = values.map((value) => this.componentColor(value));
90578
+ const red = Math.floor(rgb.reduce((sum, color3) => sum + (color3 >> 16 & 255), 0) / rgb.length);
90579
+ const green = Math.floor(rgb.reduce((sum, color3) => sum + (color3 >> 8 & 255), 0) / rgb.length);
90580
+ const blue = Math.floor(rgb.reduce((sum, color3) => sum + (color3 & 255), 0) / rgb.length);
90581
+ colors[index] = red << 16 | green << 8 | blue;
90582
+ break;
90583
+ }
90561
90584
  case "team":
90562
90585
  case "minecraft:team":
90563
- case "custom_model_data":
90564
- case "minecraft:custom_model_data":
90565
90586
  colors[index] = this.rgb(source.default);
90566
90587
  break;
90588
+ case "custom_model_data":
90589
+ case "minecraft:custom_model_data": {
90590
+ const colorIndex = source.index ?? 0;
90591
+ if (!Number.isSafeInteger(colorIndex) || colorIndex < 0) throw new MineRenderError("Item tint custom_model_data index must be a nonnegative integer");
90592
+ const values = this.componentField(components, "custom_model_data", "colors");
90593
+ if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint custom_model_data.colors must be an array");
90594
+ colors[index] = this.colorOrDefault(values?.[colorIndex], source.default, true);
90595
+ break;
90596
+ }
90567
90597
  default:
90568
90598
  throw new MineRenderError(`Unsupported item tint source ${source.type}`);
90569
90599
  }
90570
90600
  }));
90571
90601
  return colors;
90572
90602
  }
90603
+ static componentField(components, id, field) {
90604
+ const value = components[`minecraft:${id}`];
90605
+ if (value === void 0) return void 0;
90606
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new MineRenderError(`Item tint ${id} must be an object`);
90607
+ return value[field];
90608
+ }
90609
+ static colorOrDefault(value, fallback, allowTriple = false) {
90610
+ return value === void 0 ? this.rgb(fallback) : this.componentColor(value, allowTriple);
90611
+ }
90612
+ static componentColor(value, allowTriple = false) {
90613
+ if (typeof value === "number" && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) return this.rgb(value);
90614
+ if (allowTriple && Array.isArray(value) && value.length === 3 && value.every((channel) => typeof channel === "number" && Number.isFinite(channel))) {
90615
+ return this.rgb(value) & 16777215;
90616
+ }
90617
+ throw new MineRenderError(`Item tint component color must be a packed integer${allowTriple ? " or RGB triple" : ""}`);
90618
+ }
90573
90619
  static rgb(color3) {
90574
90620
  if (!Array.isArray(color3)) return color3 & 16777215;
90575
- const [red, green, blue] = color3.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)));
90621
+ const [red, green, blue] = color3.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)) & 255);
90576
90622
  return red << 16 | green << 8 | blue;
90577
90623
  }
90578
90624
  };
@@ -98074,7 +98120,7 @@ property list uchar int vertex_index
98074
98120
  }
98075
98121
  async createItem(layer, index) {
98076
98122
  const key = typeof layer.item === "string" ? AssetKey.parse("models", layer.item) : layer.item;
98077
- const model = await Models.getMerged(key);
98123
+ const model = await Models.getMerged(key, { ...layer.context, displayContext: "gui" /* GUI */ });
98078
98124
  if (!model) throw new Error(`Could not load GUI item ${key.toNamespacedString()}`);
98079
98125
  const item = new ModelObject(model, {
98080
98126
  displayPosition: "gui" /* GUI */,
@@ -102227,6 +102273,7 @@ property list uchar int vertex_index
102227
102273
  async addSceneObject(asset2, objectSupplier, _options, parent = this) {
102228
102274
  this.dirty = true;
102229
102275
  const obj = await objectSupplier();
102276
+ if (isModelObject(obj)) obj.options.tints = await ItemTints.get(obj.originalModel, obj.options.tints);
102230
102277
  if (obj?.options?.instanceMeshes && asset2.key && asset2.key?.assetType === "models") {
102231
102278
  let key = asset2.key.serialize();
102232
102279
  if (isModelObject(obj)) {
@@ -102260,7 +102307,6 @@ property list uchar int vertex_index
102260
102307
  * @returns The model, or a reference to one placement of a shared model.
102261
102308
  */
102262
102309
  async addModel(model, options, parent = this) {
102263
- options = { ...options, tints: await ItemTints.get(model, options?.tints) };
102264
102310
  return this.addSceneObject(model, () => new ModelObject(model, options), options, parent);
102265
102311
  }
102266
102312
  /**