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/node/index.d.mts
CHANGED
|
@@ -524,12 +524,14 @@ interface ItemModel extends Model {
|
|
|
524
524
|
gui_light?: GuiLight;
|
|
525
525
|
special?: SpecialItemRenderer;
|
|
526
526
|
tints?: ItemTintSource[];
|
|
527
|
+
/** Stack-component snapshot with namespaced IDs, used to resolve this item's tint sources. */
|
|
528
|
+
components?: Record<string, unknown>;
|
|
527
529
|
/** Ordered composite children, each with its own textures, display pose, and tint sources. */
|
|
528
530
|
parts?: ItemModel[];
|
|
529
531
|
}
|
|
530
532
|
/** An sRGB packed `0xRRGGBB` value or an RGB triple with components from 0 to 1. */
|
|
531
533
|
type ItemTintColor = number | TripleArray;
|
|
532
|
-
/** A vanilla item color source.
|
|
534
|
+
/** A vanilla item color source. Missing component values and unsupported gameplay state use the declared default. */
|
|
533
535
|
type ItemTintSource = {
|
|
534
536
|
type: "constant" | "minecraft:constant";
|
|
535
537
|
value: ItemTintColor;
|
|
@@ -1243,10 +1245,13 @@ declare class DisplayTransforms {
|
|
|
1243
1245
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1244
1246
|
}
|
|
1245
1247
|
|
|
1246
|
-
/** Resolves
|
|
1248
|
+
/** Resolves item-preview colors from vanilla tint definitions, stack components, and caller overrides. */
|
|
1247
1249
|
declare class ItemTints {
|
|
1248
1250
|
/** Resolves preview colors from item definitions; explicit per-index colors take precedence. */
|
|
1249
1251
|
static get(model: Model, tints?: Record<number, number>): Promise<Record<number, number> | undefined>;
|
|
1252
|
+
private static componentField;
|
|
1253
|
+
private static colorOrDefault;
|
|
1254
|
+
private static componentColor;
|
|
1250
1255
|
private static rgb;
|
|
1251
1256
|
}
|
|
1252
1257
|
|
|
@@ -1663,6 +1668,8 @@ interface GuiTextureLayer extends GuiLayerLayout {
|
|
|
1663
1668
|
interface GuiItemLayer extends GuiLayerLayout {
|
|
1664
1669
|
/** Model key, such as minecraft:item/stone; uses the model's GUI display pose. */
|
|
1665
1670
|
item: AssetKey | string;
|
|
1671
|
+
/** Supplied item state. GUI layers always select models in the GUI display context. */
|
|
1672
|
+
context?: Omit<ItemModelContext, "displayContext">;
|
|
1666
1673
|
/** sRGB 0xRRGGBB colors by face tint index, overriding the item's automatic preview colors. */
|
|
1667
1674
|
tints?: Record<number, number>;
|
|
1668
1675
|
}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -524,12 +524,14 @@ interface ItemModel extends Model {
|
|
|
524
524
|
gui_light?: GuiLight;
|
|
525
525
|
special?: SpecialItemRenderer;
|
|
526
526
|
tints?: ItemTintSource[];
|
|
527
|
+
/** Stack-component snapshot with namespaced IDs, used to resolve this item's tint sources. */
|
|
528
|
+
components?: Record<string, unknown>;
|
|
527
529
|
/** Ordered composite children, each with its own textures, display pose, and tint sources. */
|
|
528
530
|
parts?: ItemModel[];
|
|
529
531
|
}
|
|
530
532
|
/** An sRGB packed `0xRRGGBB` value or an RGB triple with components from 0 to 1. */
|
|
531
533
|
type ItemTintColor = number | TripleArray;
|
|
532
|
-
/** A vanilla item color source.
|
|
534
|
+
/** A vanilla item color source. Missing component values and unsupported gameplay state use the declared default. */
|
|
533
535
|
type ItemTintSource = {
|
|
534
536
|
type: "constant" | "minecraft:constant";
|
|
535
537
|
value: ItemTintColor;
|
|
@@ -1243,10 +1245,13 @@ declare class DisplayTransforms {
|
|
|
1243
1245
|
static apply(geometry: BufferGeometry, matrix: Matrix4): void;
|
|
1244
1246
|
}
|
|
1245
1247
|
|
|
1246
|
-
/** Resolves
|
|
1248
|
+
/** Resolves item-preview colors from vanilla tint definitions, stack components, and caller overrides. */
|
|
1247
1249
|
declare class ItemTints {
|
|
1248
1250
|
/** Resolves preview colors from item definitions; explicit per-index colors take precedence. */
|
|
1249
1251
|
static get(model: Model, tints?: Record<number, number>): Promise<Record<number, number> | undefined>;
|
|
1252
|
+
private static componentField;
|
|
1253
|
+
private static colorOrDefault;
|
|
1254
|
+
private static componentColor;
|
|
1250
1255
|
private static rgb;
|
|
1251
1256
|
}
|
|
1252
1257
|
|
|
@@ -1663,6 +1668,8 @@ interface GuiTextureLayer extends GuiLayerLayout {
|
|
|
1663
1668
|
interface GuiItemLayer extends GuiLayerLayout {
|
|
1664
1669
|
/** Model key, such as minecraft:item/stone; uses the model's GUI display pose. */
|
|
1665
1670
|
item: AssetKey | string;
|
|
1671
|
+
/** Supplied item state. GUI layers always select models in the GUI display context. */
|
|
1672
|
+
context?: Omit<ItemModelContext, "displayContext">;
|
|
1666
1673
|
/** sRGB 0xRRGGBB colors by face tint index, overriding the item's automatic preview colors. */
|
|
1667
1674
|
tints?: Record<number, number>;
|
|
1668
1675
|
}
|
package/dist/node/index.js
CHANGED
|
@@ -1541,6 +1541,7 @@ var init_ModelMerger = __esm({
|
|
|
1541
1541
|
}
|
|
1542
1542
|
merged.hierarchy = models.map((m) => m.parent).filter((p10) => `${p10}`);
|
|
1543
1543
|
merged.hierarchy.push(`${merged.parent}`);
|
|
1544
|
+
if (model.components) merged.components = model.components;
|
|
1544
1545
|
return merged;
|
|
1545
1546
|
}
|
|
1546
1547
|
static async collectAllParents(model) {
|
|
@@ -1616,10 +1617,10 @@ var init_Models = __esm({
|
|
|
1616
1617
|
const preview = this.snapshotContext(key, context);
|
|
1617
1618
|
const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
|
|
1618
1619
|
const cacheKey = itemKey.serialize() + this.contextKey(preview);
|
|
1619
|
-
const model = await this.PERSISTENT_CACHE.getOrLoad(`item-
|
|
1620
|
+
const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v4:${AssetLoader.persistentKey(cacheKey)}`, async () => {
|
|
1620
1621
|
const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
|
|
1621
1622
|
if (!result) return void 0;
|
|
1622
|
-
if (result.key.assetType !== "items") return { ...result.asset, key };
|
|
1623
|
+
if (result.key.assetType !== "items") return { ...result.asset, key, components: preview.components };
|
|
1623
1624
|
const load = async (selected) => {
|
|
1624
1625
|
if ("parts" in selected) {
|
|
1625
1626
|
return { key, parts: await Promise.all(selected.parts.map(load)) };
|
|
@@ -1633,7 +1634,7 @@ var init_Models = __esm({
|
|
|
1633
1634
|
modelKey.root = key.root;
|
|
1634
1635
|
const model2 = await this.getRaw(modelKey);
|
|
1635
1636
|
if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
|
|
1636
|
-
return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
|
|
1637
|
+
return { ...model2, components: preview.components, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
|
|
1637
1638
|
};
|
|
1638
1639
|
return load(this.selectItemModel(result.asset.model, key, preview));
|
|
1639
1640
|
});
|
|
@@ -1691,7 +1692,7 @@ var init_Models = __esm({
|
|
|
1691
1692
|
}
|
|
1692
1693
|
static contextKey(context) {
|
|
1693
1694
|
const itemReferences = Object.fromEntries(Object.entries(context.itemReferences).map(([id, key]) => [id, key.serialize()]));
|
|
1694
|
-
return `|item-
|
|
1695
|
+
return `|item-v4:${JSON.stringify(this.snapshotJson({ ...context, itemReferences }))}`;
|
|
1695
1696
|
}
|
|
1696
1697
|
static snapshotJson(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
1697
1698
|
if (value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value)) return value;
|
|
@@ -5663,6 +5664,7 @@ var init_ItemTints = __esm({
|
|
|
5663
5664
|
static async get(model, tints) {
|
|
5664
5665
|
const sources = model.tints;
|
|
5665
5666
|
if (!sources?.length) return tints;
|
|
5667
|
+
const components = model.components ?? {};
|
|
5666
5668
|
const colors = { ...tints };
|
|
5667
5669
|
await Promise.all(sources.map(async (source, index) => {
|
|
5668
5670
|
if (colors[index] !== void 0) return;
|
|
@@ -5677,27 +5679,71 @@ var init_ItemTints = __esm({
|
|
|
5677
5679
|
break;
|
|
5678
5680
|
case "dye":
|
|
5679
5681
|
case "minecraft:dye":
|
|
5682
|
+
colors[index] = this.colorOrDefault(components["minecraft:dyed_color"], source.default, true);
|
|
5683
|
+
break;
|
|
5680
5684
|
case "potion":
|
|
5681
|
-
case "minecraft:potion":
|
|
5685
|
+
case "minecraft:potion": {
|
|
5686
|
+
const value = typeof components["minecraft:potion_contents"] === "string" ? void 0 : this.componentField(components, "potion_contents", "custom_color");
|
|
5687
|
+
colors[index] = this.colorOrDefault(value, source.default);
|
|
5688
|
+
break;
|
|
5689
|
+
}
|
|
5682
5690
|
case "map_color":
|
|
5683
5691
|
case "minecraft:map_color":
|
|
5692
|
+
colors[index] = this.colorOrDefault(components["minecraft:map_color"], source.default);
|
|
5693
|
+
break;
|
|
5684
5694
|
case "firework":
|
|
5685
|
-
case "minecraft:firework":
|
|
5695
|
+
case "minecraft:firework": {
|
|
5696
|
+
const values = this.componentField(components, "firework_explosion", "colors");
|
|
5697
|
+
if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint firework_explosion.colors must be an array");
|
|
5698
|
+
if (!values?.length) {
|
|
5699
|
+
colors[index] = this.rgb(source.default);
|
|
5700
|
+
break;
|
|
5701
|
+
}
|
|
5702
|
+
const rgb = values.map((value) => this.componentColor(value));
|
|
5703
|
+
const red = Math.floor(rgb.reduce((sum, color2) => sum + (color2 >> 16 & 255), 0) / rgb.length);
|
|
5704
|
+
const green = Math.floor(rgb.reduce((sum, color2) => sum + (color2 >> 8 & 255), 0) / rgb.length);
|
|
5705
|
+
const blue = Math.floor(rgb.reduce((sum, color2) => sum + (color2 & 255), 0) / rgb.length);
|
|
5706
|
+
colors[index] = red << 16 | green << 8 | blue;
|
|
5707
|
+
break;
|
|
5708
|
+
}
|
|
5686
5709
|
case "team":
|
|
5687
5710
|
case "minecraft:team":
|
|
5688
|
-
case "custom_model_data":
|
|
5689
|
-
case "minecraft:custom_model_data":
|
|
5690
5711
|
colors[index] = this.rgb(source.default);
|
|
5691
5712
|
break;
|
|
5713
|
+
case "custom_model_data":
|
|
5714
|
+
case "minecraft:custom_model_data": {
|
|
5715
|
+
const colorIndex = source.index ?? 0;
|
|
5716
|
+
if (!Number.isSafeInteger(colorIndex) || colorIndex < 0) throw new MineRenderError("Item tint custom_model_data index must be a nonnegative integer");
|
|
5717
|
+
const values = this.componentField(components, "custom_model_data", "colors");
|
|
5718
|
+
if (values !== void 0 && !Array.isArray(values)) throw new MineRenderError("Item tint custom_model_data.colors must be an array");
|
|
5719
|
+
colors[index] = this.colorOrDefault(values?.[colorIndex], source.default, true);
|
|
5720
|
+
break;
|
|
5721
|
+
}
|
|
5692
5722
|
default:
|
|
5693
5723
|
throw new MineRenderError(`Unsupported item tint source ${source.type}`);
|
|
5694
5724
|
}
|
|
5695
5725
|
}));
|
|
5696
5726
|
return colors;
|
|
5697
5727
|
}
|
|
5728
|
+
static componentField(components, id, field) {
|
|
5729
|
+
const value = components[`minecraft:${id}`];
|
|
5730
|
+
if (value === void 0) return void 0;
|
|
5731
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new MineRenderError(`Item tint ${id} must be an object`);
|
|
5732
|
+
return value[field];
|
|
5733
|
+
}
|
|
5734
|
+
static colorOrDefault(value, fallback, allowTriple = false) {
|
|
5735
|
+
return value === void 0 ? this.rgb(fallback) : this.componentColor(value, allowTriple);
|
|
5736
|
+
}
|
|
5737
|
+
static componentColor(value, allowTriple = false) {
|
|
5738
|
+
if (typeof value === "number" && Number.isInteger(value) && value >= -2147483648 && value <= 2147483647) return this.rgb(value);
|
|
5739
|
+
if (allowTriple && Array.isArray(value) && value.length === 3 && value.every((channel) => typeof channel === "number" && Number.isFinite(channel))) {
|
|
5740
|
+
return this.rgb(value) & 16777215;
|
|
5741
|
+
}
|
|
5742
|
+
throw new MineRenderError(`Item tint component color must be a packed integer${allowTriple ? " or RGB triple" : ""}`);
|
|
5743
|
+
}
|
|
5698
5744
|
static rgb(color2) {
|
|
5699
5745
|
if (!Array.isArray(color2)) return color2 & 16777215;
|
|
5700
|
-
const [red, green, blue] = color2.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)));
|
|
5746
|
+
const [red, green, blue] = color2.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)) & 255);
|
|
5701
5747
|
return red << 16 | green << 8 | blue;
|
|
5702
5748
|
}
|
|
5703
5749
|
};
|
|
@@ -10169,7 +10215,7 @@ var GuiObject = class extends SceneObject {
|
|
|
10169
10215
|
}
|
|
10170
10216
|
async createItem(layer, index) {
|
|
10171
10217
|
const key = typeof layer.item === "string" ? AssetKey.parse("models", layer.item) : layer.item;
|
|
10172
|
-
const model = await Models.getMerged(key);
|
|
10218
|
+
const model = await Models.getMerged(key, { ...layer.context, displayContext: "gui" /* GUI */ });
|
|
10173
10219
|
if (!model) throw new Error(`Could not load GUI item ${key.toNamespacedString()}`);
|
|
10174
10220
|
const item = new ModelObject(model, {
|
|
10175
10221
|
displayPosition: "gui" /* GUI */,
|
|
@@ -14202,6 +14248,7 @@ var MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
14202
14248
|
async addSceneObject(asset2, objectSupplier, _options, parent = this) {
|
|
14203
14249
|
this.dirty = true;
|
|
14204
14250
|
const obj = await objectSupplier();
|
|
14251
|
+
if (isModelObject(obj)) obj.options.tints = await ItemTints.get(obj.originalModel, obj.options.tints);
|
|
14205
14252
|
if (obj?.options?.instanceMeshes && asset2.key && asset2.key?.assetType === "models") {
|
|
14206
14253
|
let key = asset2.key.serialize();
|
|
14207
14254
|
if (isModelObject(obj)) {
|
|
@@ -14235,7 +14282,6 @@ var MineRenderScene = class _MineRenderScene extends import_three34.Scene {
|
|
|
14235
14282
|
* @returns The model, or a reference to one placement of a shared model.
|
|
14236
14283
|
*/
|
|
14237
14284
|
async addModel(model, options, parent = this) {
|
|
14238
|
-
options = { ...options, tints: await ItemTints.get(model, options?.tints) };
|
|
14239
14285
|
return this.addSceneObject(model, () => new ModelObject(model, options), options, parent);
|
|
14240
14286
|
}
|
|
14241
14287
|
/**
|