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/browser/index.d.mts +9 -2
- package/dist/browser/index.d.ts +9 -2
- package/dist/browser/index.js +57 -11
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.mjs +57 -11
- package/dist/browser/index.mjs.map +1 -1
- package/dist/bundle.js +57 -11
- package/dist/bundle.js.map +1 -1
- package/dist/node/index.d.mts +9 -2
- package/dist/node/index.d.ts +9 -2
- package/dist/node/index.js +57 -11
- package/dist/node/index.js.map +1 -1
- package/dist/node/index.mjs +57 -11
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/browser/index.d.mts
CHANGED
|
@@ -523,12 +523,14 @@ interface ItemModel extends Model {
|
|
|
523
523
|
gui_light?: GuiLight;
|
|
524
524
|
special?: SpecialItemRenderer;
|
|
525
525
|
tints?: ItemTintSource[];
|
|
526
|
+
/** Stack-component snapshot with namespaced IDs, used to resolve this item's tint sources. */
|
|
527
|
+
components?: Record<string, unknown>;
|
|
526
528
|
/** Ordered composite children, each with its own textures, display pose, and tint sources. */
|
|
527
529
|
parts?: ItemModel[];
|
|
528
530
|
}
|
|
529
531
|
/** An sRGB packed `0xRRGGBB` value or an RGB triple with components from 0 to 1. */
|
|
530
532
|
type ItemTintColor = number | TripleArray;
|
|
531
|
-
/** A vanilla item color source.
|
|
533
|
+
/** A vanilla item color source. Missing component values and unsupported gameplay state use the declared default. */
|
|
532
534
|
type ItemTintSource = {
|
|
533
535
|
type: "constant" | "minecraft:constant";
|
|
534
536
|
value: ItemTintColor;
|
|
@@ -1242,10 +1244,13 @@ declare class DisplayTransforms {
|
|
|
1242
1244
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1243
1245
|
}
|
|
1244
1246
|
|
|
1245
|
-
/** Resolves
|
|
1247
|
+
/** Resolves item-preview colors from vanilla tint definitions, stack components, and caller overrides. */
|
|
1246
1248
|
declare class ItemTints {
|
|
1247
1249
|
/** Resolves preview colors from item definitions; explicit per-index colors take precedence. */
|
|
1248
1250
|
static get(model: Model, tints?: Record<number, number>): Promise<Record<number, number> | undefined>;
|
|
1251
|
+
private static componentField;
|
|
1252
|
+
private static colorOrDefault;
|
|
1253
|
+
private static componentColor;
|
|
1249
1254
|
private static rgb;
|
|
1250
1255
|
}
|
|
1251
1256
|
|
|
@@ -1662,6 +1667,8 @@ interface GuiTextureLayer extends GuiLayerLayout {
|
|
|
1662
1667
|
interface GuiItemLayer extends GuiLayerLayout {
|
|
1663
1668
|
/** Model key, such as minecraft:item/stone; uses the model's GUI display pose. */
|
|
1664
1669
|
item: AssetKey | string;
|
|
1670
|
+
/** Supplied item state. GUI layers always select models in the GUI display context. */
|
|
1671
|
+
context?: Omit<ItemModelContext, "displayContext">;
|
|
1665
1672
|
/** sRGB 0xRRGGBB colors by face tint index, overriding the item's automatic preview colors. */
|
|
1666
1673
|
tints?: Record<number, number>;
|
|
1667
1674
|
}
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -523,12 +523,14 @@ interface ItemModel extends Model {
|
|
|
523
523
|
gui_light?: GuiLight;
|
|
524
524
|
special?: SpecialItemRenderer;
|
|
525
525
|
tints?: ItemTintSource[];
|
|
526
|
+
/** Stack-component snapshot with namespaced IDs, used to resolve this item's tint sources. */
|
|
527
|
+
components?: Record<string, unknown>;
|
|
526
528
|
/** Ordered composite children, each with its own textures, display pose, and tint sources. */
|
|
527
529
|
parts?: ItemModel[];
|
|
528
530
|
}
|
|
529
531
|
/** An sRGB packed `0xRRGGBB` value or an RGB triple with components from 0 to 1. */
|
|
530
532
|
type ItemTintColor = number | TripleArray;
|
|
531
|
-
/** A vanilla item color source.
|
|
533
|
+
/** A vanilla item color source. Missing component values and unsupported gameplay state use the declared default. */
|
|
532
534
|
type ItemTintSource = {
|
|
533
535
|
type: "constant" | "minecraft:constant";
|
|
534
536
|
value: ItemTintColor;
|
|
@@ -1242,10 +1244,13 @@ declare class DisplayTransforms {
|
|
|
1242
1244
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1243
1245
|
}
|
|
1244
1246
|
|
|
1245
|
-
/** Resolves
|
|
1247
|
+
/** Resolves item-preview colors from vanilla tint definitions, stack components, and caller overrides. */
|
|
1246
1248
|
declare class ItemTints {
|
|
1247
1249
|
/** Resolves preview colors from item definitions; explicit per-index colors take precedence. */
|
|
1248
1250
|
static get(model: Model, tints?: Record<number, number>): Promise<Record<number, number> | undefined>;
|
|
1251
|
+
private static componentField;
|
|
1252
|
+
private static colorOrDefault;
|
|
1253
|
+
private static componentColor;
|
|
1249
1254
|
private static rgb;
|
|
1250
1255
|
}
|
|
1251
1256
|
|
|
@@ -1662,6 +1667,8 @@ interface GuiTextureLayer extends GuiLayerLayout {
|
|
|
1662
1667
|
interface GuiItemLayer extends GuiLayerLayout {
|
|
1663
1668
|
/** Model key, such as minecraft:item/stone; uses the model's GUI display pose. */
|
|
1664
1669
|
item: AssetKey | string;
|
|
1670
|
+
/** Supplied item state. GUI layers always select models in the GUI display context. */
|
|
1671
|
+
context?: Omit<ItemModelContext, "displayContext">;
|
|
1665
1672
|
/** sRGB 0xRRGGBB colors by face tint index, overriding the item's automatic preview colors. */
|
|
1666
1673
|
tints?: Record<number, number>;
|
|
1667
1674
|
}
|
package/dist/browser/index.js
CHANGED
|
@@ -1491,6 +1491,7 @@ var init_ModelMerger = __esm({
|
|
|
1491
1491
|
}
|
|
1492
1492
|
merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
|
|
1493
1493
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1494
|
+
if (model.components) merged.components = model.components;
|
|
1494
1495
|
return merged;
|
|
1495
1496
|
}
|
|
1496
1497
|
static async collectAllParents(model) {
|
|
@@ -1566,10 +1567,10 @@ var init_Models = __esm({
|
|
|
1566
1567
|
const preview = this.snapshotContext(key, context);
|
|
1567
1568
|
const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
|
|
1568
1569
|
const cacheKey = itemKey.serialize() + this.contextKey(preview);
|
|
1569
|
-
const model = await this.PERSISTENT_CACHE.getOrLoad(`item-
|
|
1570
|
+
const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v4:${AssetLoader.persistentKey(cacheKey)}`, async () => {
|
|
1570
1571
|
const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
|
|
1571
1572
|
if (!result) return void 0;
|
|
1572
|
-
if (result.key.assetType !== "items") return { ...result.asset, key };
|
|
1573
|
+
if (result.key.assetType !== "items") return { ...result.asset, key, components: preview.components };
|
|
1573
1574
|
const load = async (selected) => {
|
|
1574
1575
|
if ("parts" in selected) {
|
|
1575
1576
|
return { key, parts: await Promise.all(selected.parts.map(load)) };
|
|
@@ -1583,7 +1584,7 @@ var init_Models = __esm({
|
|
|
1583
1584
|
modelKey.root = key.root;
|
|
1584
1585
|
const model2 = await this.getRaw(modelKey);
|
|
1585
1586
|
if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
|
|
1586
|
-
return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
|
|
1587
|
+
return { ...model2, components: preview.components, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
|
|
1587
1588
|
};
|
|
1588
1589
|
return load(this.selectItemModel(result.asset.model, key, preview));
|
|
1589
1590
|
});
|
|
@@ -1641,7 +1642,7 @@ var init_Models = __esm({
|
|
|
1641
1642
|
}
|
|
1642
1643
|
static contextKey(context) {
|
|
1643
1644
|
const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));
|
|
1644
|
-
return `|item-
|
|
1645
|
+
return `|item-v4:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;
|
|
1645
1646
|
}
|
|
1646
1647
|
static snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
1647
1648
|
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return value;
|
|
@@ -5572,6 +5573,7 @@ var init_ItemTints = __esm({
|
|
|
5572
5573
|
static async get(model, tints) {
|
|
5573
5574
|
const sources = model.tints;
|
|
5574
5575
|
if (!sources?.length) return tints;
|
|
5576
|
+
const components = model.components ?? {};
|
|
5575
5577
|
const colors = { ...tints };
|
|
5576
5578
|
await Promise.all(sources.map(async (source, index) => {
|
|
5577
5579
|
if (colors[index] !== void 0) return;
|
|
@@ -5586,27 +5588,71 @@ var init_ItemTints = __esm({
|
|
|
5586
5588
|
break;
|
|
5587
5589
|
case "dye":
|
|
5588
5590
|
case "minecraft:dye":
|
|
5591
|
+
colors[index] = this.colorOrDefault(components["minecraft:dyed_color"], source.default, true);
|
|
5592
|
+
break;
|
|
5589
5593
|
case "potion":
|
|
5590
|
-
case "minecraft:potion":
|
|
5594
|
+
case "minecraft:potion": {
|
|
5595
|
+
const value = typeof components["minecraft:potion_contents"] === "string" ? void 0 : this.componentField(components, "potion_contents", "custom_color");
|
|
5596
|
+
colors[index] = this.colorOrDefault(value, source.default);
|
|
5597
|
+
break;
|
|
5598
|
+
}
|
|
5591
5599
|
case "map_color":
|
|
5592
5600
|
case "minecraft:map_color":
|
|
5601
|
+
colors[index] = this.colorOrDefault(components["minecraft:map_color"], source.default);
|
|
5602
|
+
break;
|
|
5593
5603
|
case "firework":
|
|
5594
|
-
case "minecraft:firework":
|
|
5604
|
+
case "minecraft:firework": {
|
|
5605
|
+
const values = this.componentField(components, "firework_explosion", "colors");
|
|
5606
|
+
if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint firework_explosion.colors must be an array");
|
|
5607
|
+
if (!values?.length) {
|
|
5608
|
+
colors[index] = this.rgb(source.default);
|
|
5609
|
+
break;
|
|
5610
|
+
}
|
|
5611
|
+
const rgb = values.map((value) => this.componentColor(value));
|
|
5612
|
+
const red = Math.floor(rgb.reduce((sum, color2) => sum + (color2 >> 16 & 255), 0) / rgb.length);
|
|
5613
|
+
const green = Math.floor(rgb.reduce((sum, color2) => sum + (color2 >> 8 & 255), 0) / rgb.length);
|
|
5614
|
+
const blue = Math.floor(rgb.reduce((sum, color2) => sum + (color2 & 255), 0) / rgb.length);
|
|
5615
|
+
colors[index] = red << 16 | green << 8 | blue;
|
|
5616
|
+
break;
|
|
5617
|
+
}
|
|
5595
5618
|
case "team":
|
|
5596
5619
|
case "minecraft:team":
|
|
5597
|
-
case "custom_model_data":
|
|
5598
|
-
case "minecraft:custom_model_data":
|
|
5599
5620
|
colors[index] = this.rgb(source.default);
|
|
5600
5621
|
break;
|
|
5622
|
+
case "custom_model_data":
|
|
5623
|
+
case "minecraft:custom_model_data": {
|
|
5624
|
+
const colorIndex = source.index ?? 0;
|
|
5625
|
+
if (!Number.isSafeInteger(colorIndex) || colorIndex < 0) throw new MineRenderError("Item tint custom_model_data index must be a nonnegative integer");
|
|
5626
|
+
const values = this.componentField(components, "custom_model_data", "colors");
|
|
5627
|
+
if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint custom_model_data.colors must be an array");
|
|
5628
|
+
colors[index] = this.colorOrDefault(values?.[colorIndex], source.default, true);
|
|
5629
|
+
break;
|
|
5630
|
+
}
|
|
5601
5631
|
default:
|
|
5602
5632
|
throw new MineRenderError(`Unsupported item tint source ${source.type}`);
|
|
5603
5633
|
}
|
|
5604
5634
|
}));
|
|
5605
5635
|
return colors;
|
|
5606
5636
|
}
|
|
5637
|
+
static componentField(components, id, field) {
|
|
5638
|
+
const value = components[`minecraft:${id}`];
|
|
5639
|
+
if (value === void 0) return void 0;
|
|
5640
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new MineRenderError(`Item tint ${id} must be an object`);
|
|
5641
|
+
return value[field];
|
|
5642
|
+
}
|
|
5643
|
+
static colorOrDefault(value, fallback, allowTriple = false) {
|
|
5644
|
+
return value === void 0 ? this.rgb(fallback) : this.componentColor(value, allowTriple);
|
|
5645
|
+
}
|
|
5646
|
+
static componentColor(value, allowTriple = false) {
|
|
5647
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) return this.rgb(value);
|
|
5648
|
+
if (allowTriple && Array.isArray(value) && value.length === 3 && value.every((channel) => typeof channel === "number" && Number.isFinite(channel))) {
|
|
5649
|
+
return this.rgb(value) & 16777215;
|
|
5650
|
+
}
|
|
5651
|
+
throw new MineRenderError(`Item tint component color must be a packed integer${allowTriple ? " or RGB triple" : ""}`);
|
|
5652
|
+
}
|
|
5607
5653
|
static rgb(color2) {
|
|
5608
5654
|
if (!Array.isArray(color2)) return color2 & 16777215;
|
|
5609
|
-
const [red, green, blue] = color2.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)));
|
|
5655
|
+
const [red, green, blue] = color2.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)) & 255);
|
|
5610
5656
|
return red << 16 | green << 8 | blue;
|
|
5611
5657
|
}
|
|
5612
5658
|
};
|
|
@@ -10116,7 +10162,7 @@ var GuiObject = class extends SceneObject {
|
|
|
10116
10162
|
}
|
|
10117
10163
|
async createItem(layer, index) {
|
|
10118
10164
|
const key = typeof layer.item === "string" ? AssetKey.parse("models", layer.item) : layer.item;
|
|
10119
|
-
const model = await Models.getMerged(key);
|
|
10165
|
+
const model = await Models.getMerged(key, { ...layer.context, displayContext: "gui" /* GUI */ });
|
|
10120
10166
|
if (!model) throw new Error(`Could not load GUI item ${key.toNamespacedString()}`);
|
|
10121
10167
|
const item = new ModelObject(model, {
|
|
10122
10168
|
displayPosition: "gui" /* GUI */,
|
|
@@ -14145,6 +14191,7 @@ var _MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
14145
14191
|
async addSceneObject(asset2, objectSupplier, _options, parent = this) {
|
|
14146
14192
|
this.dirty = true;
|
|
14147
14193
|
const obj = await objectSupplier();
|
|
14194
|
+
if (isModelObject(obj)) obj.options.tints = await ItemTints.get(obj.originalModel, obj.options.tints);
|
|
14148
14195
|
if (obj?.options?.instanceMeshes && asset2.key && asset2.key?.assetType === "models") {
|
|
14149
14196
|
let key = asset2.key.serialize();
|
|
14150
14197
|
if (isModelObject(obj)) {
|
|
@@ -14178,7 +14225,6 @@ var _MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
14178
14225
|
* @returns The model, or a reference to one placement of a shared model.
|
|
14179
14226
|
*/
|
|
14180
14227
|
async addModel(model, options, parent = this) {
|
|
14181
|
-
options = { ...options, tints: await ItemTints.get(model, options?.tints) };
|
|
14182
14228
|
return this.addSceneObject(model, () => new ModelObject(model, options), options, parent);
|
|
14183
14229
|
}
|
|
14184
14230
|
/**
|