minerender 2.1.0-alpha.20 → 2.1.0-alpha.21

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.
@@ -401,6 +401,9 @@ var Caching = class _Caching {
401
401
  static {
402
402
  this.defaultBlockStatesCache = _Caching.createAssetCache();
403
403
  }
404
+ static {
405
+ this.blockTintCache = _Caching.createAssetCache();
406
+ }
404
407
  static {
405
408
  this.entityModelsCache = _Caching.createAssetCache();
406
409
  }
@@ -426,6 +429,7 @@ var Caching = class _Caching {
426
429
  this.blockStateCache,
427
430
  this.listAssetCache,
428
431
  this.defaultBlockStatesCache,
432
+ this.blockTintCache,
429
433
  this.entityModelsCache
430
434
  ];
431
435
  }
@@ -3661,6 +3665,91 @@ function isQuadArray(obj) {
3661
3665
  return Array.isArray(obj) && obj.length === 4;
3662
3666
  }
3663
3667
 
3668
+ // src/model/block/blockTints.json
3669
+ var blockTints_default = {
3670
+ "minecraft:large_fern": { source: "grass" },
3671
+ "minecraft:tall_grass": { source: "grass" },
3672
+ "minecraft:grass_block": { source: "grass" },
3673
+ "minecraft:fern": { source: "grass" },
3674
+ "minecraft:grass": { source: "grass" },
3675
+ "minecraft:short_grass": { source: "grass" },
3676
+ "minecraft:potted_fern": { source: "grass" },
3677
+ "minecraft:bush": { source: "grass" },
3678
+ "minecraft:pink_petals": { source: "grass", untinted: [0] },
3679
+ "minecraft:wildflowers": { source: "grass", untinted: [0] },
3680
+ "minecraft:spruce_leaves": { source: "constant", color: 6396257 },
3681
+ "minecraft:birch_leaves": { source: "constant", color: 8431445 },
3682
+ "minecraft:oak_leaves": { source: "constant", color: 4764952 },
3683
+ "minecraft:jungle_leaves": { source: "constant", color: 4764952 },
3684
+ "minecraft:acacia_leaves": { source: "constant", color: 4764952 },
3685
+ "minecraft:dark_oak_leaves": { source: "constant", color: 4764952 },
3686
+ "minecraft:vine": { source: "constant", color: 4764952 },
3687
+ "minecraft:mangrove_leaves": { source: "constant", color: 4764952 },
3688
+ "minecraft:leaf_litter": { source: "constant", color: 6044722 },
3689
+ "minecraft:water_cauldron": { source: "constant", color: 4159204 },
3690
+ "minecraft:redstone_wire": { source: "redstone" },
3691
+ "minecraft:attached_melon_stem": { source: "constant", color: 14731036 },
3692
+ "minecraft:attached_pumpkin_stem": { source: "constant", color: 14731036 },
3693
+ "minecraft:melon_stem": { source: "stem" },
3694
+ "minecraft:pumpkin_stem": { source: "stem" },
3695
+ "minecraft:lily_pad": { source: "constant", color: 7455580 }
3696
+ };
3697
+
3698
+ // src/model/block/BlockTints.ts
3699
+ var rules = blockTints_default;
3700
+ var BlockTints = class {
3701
+ /** Resolves block preview colors without biome context; explicit tints take precedence. */
3702
+ static async get(key, state, model, tints) {
3703
+ const rule = key && rules[key.toNamespacedString()];
3704
+ if (!key || !rule) return tints;
3705
+ const indices = /* @__PURE__ */ new Set();
3706
+ for (const element of model.elements ?? []) {
3707
+ for (const face of Object.values(element.faces)) {
3708
+ const index = face?.tintindex;
3709
+ if (index !== void 0 && index >= 0 && tints?.[index] === void 0 && !rule.untinted?.includes(index)) {
3710
+ indices.add(index);
3711
+ }
3712
+ }
3713
+ }
3714
+ if (!indices.size) return tints;
3715
+ let color;
3716
+ switch (rule.source) {
3717
+ case "constant":
3718
+ color = rule.color;
3719
+ break;
3720
+ case "grass":
3721
+ color = await this.grassColor(key);
3722
+ break;
3723
+ case "redstone": {
3724
+ const power = Number(state.power ?? 0) / 15;
3725
+ const red = power * 0.6 + (power > 0 ? 0.4 : 0.3);
3726
+ const green = Math.max(0, power * power * 0.7 - 0.5);
3727
+ const blue = Math.max(0, power * power * 0.6 - 0.7);
3728
+ color = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
3729
+ break;
3730
+ }
3731
+ case "stem": {
3732
+ const age = Number(state.age ?? 0);
3733
+ color = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
3734
+ break;
3735
+ }
3736
+ }
3737
+ return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
3738
+ }
3739
+ static async grassColor(origin) {
3740
+ const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
3741
+ return await Caching.blockTintCache.get(key.serialize(), async () => {
3742
+ const image = await ModelTextures.get(key);
3743
+ if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
3744
+ if (image.width !== 256 || image.height !== 256) {
3745
+ throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
3746
+ }
3747
+ const [red, green, blue] = image.data.getImageData(127, 127, 1, 1).data;
3748
+ return red << 16 | green << 8 | blue;
3749
+ });
3750
+ }
3751
+ };
3752
+
3664
3753
  // src/model/scene/ModelObject.ts
3665
3754
  import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler4, Matrix4 as Matrix45 } from "three";
3666
3755
 
@@ -4511,6 +4600,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4511
4600
  const model = await Models.getMerged(AssetKey.parse("models", variant.model));
4512
4601
  const options = {
4513
4602
  ...this.options,
4603
+ tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
4514
4604
  uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
4515
4605
  };
4516
4606
  const obj = await this.scene.addModel(model, options);
@@ -7035,6 +7125,7 @@ export {
7035
7125
  BlockEntityModels,
7036
7126
  BlockObject,
7037
7127
  BlockStates,
7128
+ BlockTints,
7038
7129
  BrowserArchiveProxy,
7039
7130
  CUBE_FACES,
7040
7131
  Caching,