minerender 2.1.0-alpha.20 → 2.1.0-alpha.22

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
  }
@@ -1094,7 +1098,7 @@ var Meshes = class _Meshes {
1094
1098
  };
1095
1099
 
1096
1100
  // src/UVMapper.ts
1097
- import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector33 } from "three";
1101
+ import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector34 } from "three";
1098
1102
 
1099
1103
  // src/model/ModelMerger.ts
1100
1104
  var import_ts_deepmerge = __toESM(require_dist());
@@ -1185,15 +1189,77 @@ function isAssetKey(obj) {
1185
1189
  return isBasicAssetKey(obj) && obj.isAssetKey === true;
1186
1190
  }
1187
1191
 
1192
+ // src/model/DisplayTransforms.ts
1193
+ import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
1194
+
1195
+ // src/model/DisplayPosition.ts
1196
+ var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
1197
+ DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1198
+ DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1199
+ DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1200
+ DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1201
+ DisplayPosition2["GUI"] = "gui";
1202
+ DisplayPosition2["HEAD"] = "head";
1203
+ DisplayPosition2["GROUND"] = "ground";
1204
+ DisplayPosition2["FIXED"] = "fixed";
1205
+ DisplayPosition2["ON_SHELF"] = "on_shelf";
1206
+ return DisplayPosition2;
1207
+ })(DisplayPosition || {});
1208
+ var DISPLAY_POSITIONS = Object.values(DisplayPosition);
1209
+
1210
+ // src/model/DisplayTransforms.ts
1211
+ var DisplayTransforms = class {
1212
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1213
+ static withHandFallbacks(display) {
1214
+ if (!display) return void 0;
1215
+ const resolved = { ...display };
1216
+ for (const [left, right] of [
1217
+ ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1218
+ ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1219
+ ]) {
1220
+ if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1221
+ }
1222
+ return resolved;
1223
+ }
1224
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1225
+ static getMatrix(display, position) {
1226
+ const transform = this.withHandFallbacks(display)?.[position] ?? {};
1227
+ const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1228
+ const sign = left ? -1 : 1;
1229
+ const [x, y, z] = transform.rotation ?? [0, 0, 0];
1230
+ const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1231
+ const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1232
+ translation.x *= sign;
1233
+ const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1234
+ return new Matrix4().compose(translation, rotation, scale);
1235
+ }
1236
+ static apply(geometry, matrix) {
1237
+ geometry.applyMatrix4(matrix);
1238
+ if (matrix.determinant() < 0) {
1239
+ if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1240
+ const index = geometry.index;
1241
+ for (let i = 0; i < index.count; i += 3) {
1242
+ const second = index.getX(i + 1);
1243
+ index.setX(i + 1, index.getX(i + 2));
1244
+ index.setX(i + 2, second);
1245
+ }
1246
+ index.needsUpdate = true;
1247
+ }
1248
+ }
1249
+ };
1250
+
1188
1251
  // src/model/ModelMerger.ts
1189
1252
  var ModelMerger = class {
1190
1253
  static async mergeWithParents(model) {
1191
1254
  const models = await this.collectAllParents(model);
1192
1255
  let merged = {};
1193
- for (let parentModel of models) {
1194
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1256
+ for (const source of [...models, model]) {
1257
+ const inheritedDisplay = merged.display;
1258
+ merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1259
+ if (source.display) {
1260
+ merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1261
+ }
1195
1262
  }
1196
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1197
1263
  merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
1198
1264
  merged.hierarchy.push(`${merged.parent}`);
1199
1265
  return merged;
@@ -1448,9 +1514,9 @@ var BatchedExecutor = class {
1448
1514
  };
1449
1515
 
1450
1516
  // src/util/model.ts
1451
- import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1517
+ import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector33 } from "three";
1452
1518
  function applyElementRotation(rotation, geometry) {
1453
- const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1519
+ const origin = new Vector33(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1454
1520
  geometry.translate(-origin.x, -origin.y, -origin.z);
1455
1521
  switch (rotation.axis) {
1456
1522
  case "x" /* X */:
@@ -1475,7 +1541,7 @@ function applyElementRotation(rotation, geometry) {
1475
1541
  geometry.translate(origin.x, origin.y, origin.z);
1476
1542
  }
1477
1543
  function applyModelPartRotation(modelPart, geometry) {
1478
- const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1544
+ const origin = new Vector33(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1479
1545
  geometry.translate(-origin.x, -origin.y, -origin.z);
1480
1546
  geometry.rotateX(toRadians(modelPart.pitch));
1481
1547
  geometry.rotateY(toRadians(modelPart.yaw));
@@ -1485,18 +1551,18 @@ function applyModelPartRotation(modelPart, geometry) {
1485
1551
  function applyGenericRotation(axis, rotation, obj) {
1486
1552
  switch (axis) {
1487
1553
  case "x" /* X */:
1488
- obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1554
+ obj.rotateOnAxis(new Vector33(1, 0, 0), toRadians(rotation));
1489
1555
  break;
1490
1556
  case "y" /* Y */:
1491
- obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1557
+ obj.rotateOnAxis(new Vector33(0, 1, 0), toRadians(rotation));
1492
1558
  break;
1493
1559
  case "z" /* Z */:
1494
- obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1560
+ obj.rotateOnAxis(new Vector33(0, 0, 1), toRadians(rotation));
1495
1561
  break;
1496
1562
  }
1497
1563
  }
1498
1564
  function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1499
- let size = new Vector32();
1565
+ let size = new Vector33();
1500
1566
  box.getSize(size);
1501
1567
  let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1502
1568
  let wireGeo = new EdgesGeometry(boxGeo);
@@ -2099,12 +2165,12 @@ var X = 0;
2099
2165
  var Y = 1;
2100
2166
  var Z = 2;
2101
2167
  var FACE_UV_AXES = {
2102
- east: [new Vector33(0, 0, -1), new Vector33(0, -1, 0)],
2103
- west: [new Vector33(0, 0, 1), new Vector33(0, -1, 0)],
2104
- up: [new Vector33(1, 0, 0), new Vector33(0, 0, 1)],
2105
- down: [new Vector33(1, 0, 0), new Vector33(0, 0, -1)],
2106
- south: [new Vector33(1, 0, 0), new Vector33(0, -1, 0)],
2107
- north: [new Vector33(-1, 0, 0), new Vector33(0, -1, 0)]
2168
+ east: [new Vector34(0, 0, -1), new Vector34(0, -1, 0)],
2169
+ west: [new Vector34(0, 0, 1), new Vector34(0, -1, 0)],
2170
+ up: [new Vector34(1, 0, 0), new Vector34(0, 0, 1)],
2171
+ down: [new Vector34(1, 0, 0), new Vector34(0, 0, -1)],
2172
+ south: [new Vector34(1, 0, 0), new Vector34(0, -1, 0)],
2173
+ north: [new Vector34(-1, 0, 0), new Vector34(0, -1, 0)]
2108
2174
  };
2109
2175
  var UVMapper = class {
2110
2176
  static makeUv(uvCoord, originalTextureSize, actualTextureSize) {
@@ -2685,7 +2751,7 @@ var BlockEntityModels = class {
2685
2751
  };
2686
2752
 
2687
2753
  // src/renderer/SceneObject.ts
2688
- import { Euler as Euler2, InstancedMesh, MathUtils, Matrix4 as Matrix42, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion2, Vector3 as Vector34 } from "three";
2754
+ import { Euler as Euler3, InstancedMesh, MathUtils, Matrix4 as Matrix43, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector35 } from "three";
2689
2755
 
2690
2756
  // src/instance/InstanceReference.ts
2691
2757
  var InstanceReference = class {
@@ -2930,7 +2996,7 @@ var SceneObject = class _SceneObject extends Object3D2 {
2930
2996
  nextInstance() {
2931
2997
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2932
2998
  const i = this._instanceCounter++;
2933
- this.setMatrixAt(i, new Matrix42());
2999
+ this.setMatrixAt(i, new Matrix43());
2934
3000
  const mesh = this.children[0];
2935
3001
  if (mesh && isInstancedMesh(mesh)) {
2936
3002
  mesh.count = Math.min(this._instanceCounter, mesh.instanceMatrix.count);
@@ -2947,7 +3013,7 @@ var SceneObject = class _SceneObject extends Object3D2 {
2947
3013
  }
2948
3014
  //</editor-fold>
2949
3015
  //<editor-fold desc="TRANSFORMATION">
2950
- getMatrixAt(index, matrix = new Matrix42()) {
3016
+ getMatrixAt(index, matrix = new Matrix43()) {
2951
3017
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2952
3018
  const child = this.children[0];
2953
3019
  if (child && isInstancedMesh(child)) {
@@ -2966,16 +3032,16 @@ var SceneObject = class _SceneObject extends Object3D2 {
2966
3032
  }
2967
3033
  setPositionRotationScaleAt(index, position, rotation, scale) {
2968
3034
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2969
- const oldPosition = new Vector34();
2970
- const oldRotation = new Quaternion2();
2971
- const oldScale = new Vector34();
2972
- const matrix = new Matrix42();
3035
+ const oldPosition = new Vector35();
3036
+ const oldRotation = new Quaternion3();
3037
+ const oldScale = new Vector35();
3038
+ const matrix = new Matrix43();
2973
3039
  if (!scale || !rotation || !position) {
2974
3040
  this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
2975
3041
  }
2976
3042
  matrix.compose(
2977
3043
  position ? position : oldPosition,
2978
- rotation ? new Quaternion2().setFromEuler(rotation) : oldRotation,
3044
+ rotation ? new Quaternion3().setFromEuler(rotation) : oldRotation,
2979
3045
  scale ? scale : oldScale
2980
3046
  );
2981
3047
  this.setMatrixAt(index, matrix);
@@ -2984,7 +3050,7 @@ var SceneObject = class _SceneObject extends Object3D2 {
2984
3050
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2985
3051
  this.setPositionRotationScaleAt(index, position);
2986
3052
  }
2987
- getPositionAt(index, vector = new Vector34()) {
3053
+ getPositionAt(index, vector = new Vector35()) {
2988
3054
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2989
3055
  const matrix = this.getMatrixAt(index);
2990
3056
  vector.setFromMatrixPosition(matrix);
@@ -2994,7 +3060,7 @@ var SceneObject = class _SceneObject extends Object3D2 {
2994
3060
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2995
3061
  this.setPositionRotationScaleAt(index, void 0, rotation, void 0);
2996
3062
  }
2997
- getRotationAt(index, euler = new Euler2()) {
3063
+ getRotationAt(index, euler = new Euler3()) {
2998
3064
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2999
3065
  const matrix = this.getMatrixAt(index);
3000
3066
  euler.setFromRotationMatrix(matrix);
@@ -3004,7 +3070,7 @@ var SceneObject = class _SceneObject extends Object3D2 {
3004
3070
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3005
3071
  this.setPositionRotationScaleAt(index, void 0, void 0, scale);
3006
3072
  }
3007
- getScaleAt(index, vector = new Vector34()) {
3073
+ getScaleAt(index, vector = new Vector35()) {
3008
3074
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3009
3075
  const matrix = this.getMatrixAt(index);
3010
3076
  vector.setFromMatrixScale(matrix);
@@ -3625,20 +3691,6 @@ function isInstanceable(obj) {
3625
3691
  return "nextInstance" in obj;
3626
3692
  }
3627
3693
 
3628
- // src/model/DisplayPosition.ts
3629
- var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
3630
- DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
3631
- DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
3632
- DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
3633
- DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
3634
- DisplayPosition2["GUI"] = "gui";
3635
- DisplayPosition2["HEAD"] = "head";
3636
- DisplayPosition2["GROUND"] = "ground";
3637
- DisplayPosition2["FIXED"] = "fixed";
3638
- return DisplayPosition2;
3639
- })(DisplayPosition || {});
3640
- var DISPLAY_POSITIONS = Object.values(DisplayPosition);
3641
-
3642
3694
  // src/model/GuiLight.ts
3643
3695
  var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
3644
3696
  GuiLight2["FRONT"] = "front";
@@ -3661,8 +3713,93 @@ function isQuadArray(obj) {
3661
3713
  return Array.isArray(obj) && obj.length === 4;
3662
3714
  }
3663
3715
 
3716
+ // src/model/block/blockTints.json
3717
+ var blockTints_default = {
3718
+ "minecraft:large_fern": { source: "grass" },
3719
+ "minecraft:tall_grass": { source: "grass" },
3720
+ "minecraft:grass_block": { source: "grass" },
3721
+ "minecraft:fern": { source: "grass" },
3722
+ "minecraft:grass": { source: "grass" },
3723
+ "minecraft:short_grass": { source: "grass" },
3724
+ "minecraft:potted_fern": { source: "grass" },
3725
+ "minecraft:bush": { source: "grass" },
3726
+ "minecraft:pink_petals": { source: "grass", untinted: [0] },
3727
+ "minecraft:wildflowers": { source: "grass", untinted: [0] },
3728
+ "minecraft:spruce_leaves": { source: "constant", color: 6396257 },
3729
+ "minecraft:birch_leaves": { source: "constant", color: 8431445 },
3730
+ "minecraft:oak_leaves": { source: "constant", color: 4764952 },
3731
+ "minecraft:jungle_leaves": { source: "constant", color: 4764952 },
3732
+ "minecraft:acacia_leaves": { source: "constant", color: 4764952 },
3733
+ "minecraft:dark_oak_leaves": { source: "constant", color: 4764952 },
3734
+ "minecraft:vine": { source: "constant", color: 4764952 },
3735
+ "minecraft:mangrove_leaves": { source: "constant", color: 4764952 },
3736
+ "minecraft:leaf_litter": { source: "constant", color: 6044722 },
3737
+ "minecraft:water_cauldron": { source: "constant", color: 4159204 },
3738
+ "minecraft:redstone_wire": { source: "redstone" },
3739
+ "minecraft:attached_melon_stem": { source: "constant", color: 14731036 },
3740
+ "minecraft:attached_pumpkin_stem": { source: "constant", color: 14731036 },
3741
+ "minecraft:melon_stem": { source: "stem" },
3742
+ "minecraft:pumpkin_stem": { source: "stem" },
3743
+ "minecraft:lily_pad": { source: "constant", color: 7455580 }
3744
+ };
3745
+
3746
+ // src/model/block/BlockTints.ts
3747
+ var rules = blockTints_default;
3748
+ var BlockTints = class {
3749
+ /** Resolves block preview colors without biome context; explicit tints take precedence. */
3750
+ static async get(key, state, model, tints) {
3751
+ const rule = key && rules[key.toNamespacedString()];
3752
+ if (!key || !rule) return tints;
3753
+ const indices = /* @__PURE__ */ new Set();
3754
+ for (const element of model.elements ?? []) {
3755
+ for (const face of Object.values(element.faces)) {
3756
+ const index = face?.tintindex;
3757
+ if (index !== void 0 && index >= 0 && tints?.[index] === void 0 && !rule.untinted?.includes(index)) {
3758
+ indices.add(index);
3759
+ }
3760
+ }
3761
+ }
3762
+ if (!indices.size) return tints;
3763
+ let color;
3764
+ switch (rule.source) {
3765
+ case "constant":
3766
+ color = rule.color;
3767
+ break;
3768
+ case "grass":
3769
+ color = await this.grassColor(key);
3770
+ break;
3771
+ case "redstone": {
3772
+ const power = Number(state.power ?? 0) / 15;
3773
+ const red = power * 0.6 + (power > 0 ? 0.4 : 0.3);
3774
+ const green = Math.max(0, power * power * 0.7 - 0.5);
3775
+ const blue = Math.max(0, power * power * 0.6 - 0.7);
3776
+ color = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
3777
+ break;
3778
+ }
3779
+ case "stem": {
3780
+ const age = Number(state.age ?? 0);
3781
+ color = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
3782
+ break;
3783
+ }
3784
+ }
3785
+ return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
3786
+ }
3787
+ static async grassColor(origin) {
3788
+ const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
3789
+ return await Caching.blockTintCache.get(key.serialize(), async () => {
3790
+ const image = await ModelTextures.get(key);
3791
+ if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
3792
+ if (image.width !== 256 || image.height !== 256) {
3793
+ throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
3794
+ }
3795
+ const [red, green, blue] = image.data.getImageData(127, 127, 1, 1).data;
3796
+ return red << 16 | green << 8 | blue;
3797
+ });
3798
+ }
3799
+ };
3800
+
3664
3801
  // src/model/scene/ModelObject.ts
3665
- import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler4, Matrix4 as Matrix45 } from "three";
3802
+ import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler5, Matrix4 as Matrix46 } from "three";
3666
3803
 
3667
3804
  // src/three/BufferGeometryUtils.js
3668
3805
  import {
@@ -3674,7 +3811,7 @@ import {
3674
3811
  TriangleFanDrawMode,
3675
3812
  TriangleStripDrawMode,
3676
3813
  TrianglesDrawMode,
3677
- Vector3 as Vector36
3814
+ Vector3 as Vector37
3678
3815
  } from "three";
3679
3816
  function computeTangents(geometry) {
3680
3817
  geometry.computeTangents();
@@ -3993,15 +4130,15 @@ function computeMorphedAttributes(object) {
3993
4130
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
3994
4131
  return null;
3995
4132
  }
3996
- const _vA = new Vector36();
3997
- const _vB = new Vector36();
3998
- const _vC = new Vector36();
3999
- const _tempA = new Vector36();
4000
- const _tempB = new Vector36();
4001
- const _tempC = new Vector36();
4002
- const _morphA = new Vector36();
4003
- const _morphB = new Vector36();
4004
- const _morphC = new Vector36();
4133
+ const _vA = new Vector37();
4134
+ const _vB = new Vector37();
4135
+ const _vC = new Vector37();
4136
+ const _tempA = new Vector37();
4137
+ const _tempB = new Vector37();
4138
+ const _tempC = new Vector37();
4139
+ const _morphA = new Vector37();
4140
+ const _morphB = new Vector37();
4141
+ const _morphC = new Vector37();
4005
4142
  function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4006
4143
  _vA.fromBufferAttribute(attribute, a2);
4007
4144
  _vB.fromBufferAttribute(attribute, b2);
@@ -4241,13 +4378,14 @@ var ModelObject = class _ModelObject extends SceneObject {
4241
4378
  createMeshes(force = false) {
4242
4379
  if (this.meshesCreated && !force) return;
4243
4380
  const mat = Materials.MISSING_TEXTURE;
4381
+ const displayTransform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : void 0;
4244
4382
  let allGeos = [];
4245
4383
  if (this.atlas) {
4246
4384
  if (this.atlas.model.elements) {
4247
4385
  this.atlas.model.elements?.forEach((el) => {
4248
4386
  const elGeo = this._getBoxGeometryFromElement(el).clone();
4249
4387
  if (this.options.uvLockRotation) {
4250
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler4(...this.options.uvLockRotation));
4388
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler5(...this.options.uvLockRotation));
4251
4389
  }
4252
4390
  if (this.options.tints) {
4253
4391
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -4263,12 +4401,13 @@ var ModelObject = class _ModelObject extends SceneObject {
4263
4401
  }
4264
4402
  elGeo.setAttribute("color", new BufferAttribute4(colors, 3));
4265
4403
  }
4266
- elGeo.applyMatrix4(new Matrix45().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4267
- elGeo.applyMatrix4(new Matrix45().makeTranslation(el.from[0], el.from[1], el.from[2]));
4404
+ elGeo.applyMatrix4(new Matrix46().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4405
+ elGeo.applyMatrix4(new Matrix46().makeTranslation(el.from[0], el.from[1], el.from[2]));
4268
4406
  if (el.rotation) {
4269
4407
  applyElementRotation(el.rotation, elGeo);
4270
4408
  }
4271
- elGeo.applyMatrix4(new Matrix45().makeTranslation(-8, -8, -8));
4409
+ elGeo.applyMatrix4(new Matrix46().makeTranslation(-8, -8, -8));
4410
+ if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
4272
4411
  if (this.options.mergeMeshes) {
4273
4412
  allGeos.push(elGeo);
4274
4413
  } else {
@@ -4290,6 +4429,7 @@ var ModelObject = class _ModelObject extends SceneObject {
4290
4429
  combinedGeo = mergeBufferGeometries(allGeos);
4291
4430
  } else {
4292
4431
  combinedGeo = new BoxGeometry5(16, 16, 16);
4432
+ if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
4293
4433
  }
4294
4434
  combinedGeo.computeBoundingBox();
4295
4435
  let mesh;
@@ -4341,7 +4481,7 @@ function isModelObject(obj) {
4341
4481
 
4342
4482
  // src/model/block/scene/BlockObject.ts
4343
4483
  var import_ts_deepmerge6 = __toESM(require_dist());
4344
- import { Euler as Euler5, Matrix4 as Matrix46, Vector3 as Vector37 } from "three";
4484
+ import { Euler as Euler6, Matrix4 as Matrix47, Vector3 as Vector38 } from "three";
4345
4485
  var p10 = prefix("BlockObject");
4346
4486
  function matchesCondition(condition, state) {
4347
4487
  return Object.entries(condition).every(([key, value]) => {
@@ -4403,7 +4543,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4403
4543
  if (isModelObject(model)) {
4404
4544
  model.removeFromScene();
4405
4545
  } else if (isInstanceReference(model)) {
4406
- model.setScale(new Vector37(0, 0, 0));
4546
+ model.setScale(new Vector38(0, 0, 0));
4407
4547
  }
4408
4548
  }
4409
4549
  super.removeFromScene();
@@ -4464,7 +4604,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4464
4604
  }
4465
4605
  for (let model of this._models) {
4466
4606
  if (isInstanceReference(model)) {
4467
- model.setScale(new Vector37(0, 0, 0));
4607
+ model.setScale(new Vector38(0, 0, 0));
4468
4608
  } else {
4469
4609
  model.dispose();
4470
4610
  }
@@ -4501,7 +4641,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4501
4641
  await this.createVariant(variant);
4502
4642
  }
4503
4643
  async createVariant(variant) {
4504
- const rotation = new Euler5();
4644
+ const rotation = new Euler6();
4505
4645
  if (typeof variant.x !== "undefined") {
4506
4646
  rotation.x = toRadians(clampRotationDegrees(variant.x));
4507
4647
  }
@@ -4511,6 +4651,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4511
4651
  const model = await Models.getMerged(AssetKey.parse("models", variant.model));
4512
4652
  const options = {
4513
4653
  ...this.options,
4654
+ tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
4514
4655
  uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
4515
4656
  };
4516
4657
  const obj = await this.scene.addModel(model, options);
@@ -4587,7 +4728,7 @@ var BlockObject = class _BlockObject extends SceneObject {
4587
4728
  setPositionRotationScaleAt(index, position, rotation, scale) {
4588
4729
  super.setPositionRotationScaleAt(index, position, rotation, scale);
4589
4730
  }
4590
- getMatrixAt(index, matrix = new Matrix46()) {
4731
+ getMatrixAt(index, matrix = new Matrix47()) {
4591
4732
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
4592
4733
  const child = this._models[0];
4593
4734
  if (child && isModelObject(child)) {
@@ -5582,7 +5723,8 @@ var MineRenderScene = class _MineRenderScene extends Scene2 {
5582
5723
  console.log("instanceMeshes + key");
5583
5724
  let key = asset.key.serialize();
5584
5725
  if (isModelObject(obj)) {
5585
- const { uvLockRotation, tints } = obj.options;
5726
+ const { displayPosition, uvLockRotation, tints } = obj.options;
5727
+ if (displayPosition) key += `|display:${displayPosition}`;
5586
5728
  if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
5587
5729
  const palette = Object.entries(tints ?? {}).sort(([a], [b]) => Number(a) - Number(b));
5588
5730
  if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
@@ -5629,7 +5771,7 @@ function isMineRenderScene(obj) {
5629
5771
  }
5630
5772
 
5631
5773
  // src/renderer/Renderer.ts
5632
- import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector39, WebGLRenderer } from "three";
5774
+ import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector310, WebGLRenderer } from "three";
5633
5775
  var import_ts_deepmerge9 = __toESM(require_dist());
5634
5776
  import Stats from "stats.js";
5635
5777
  import { EffectComposer, RenderPass } from "postprocessing";
@@ -5638,11 +5780,11 @@ import { EffectComposer, RenderPass } from "postprocessing";
5638
5780
  import {
5639
5781
  EventDispatcher,
5640
5782
  MOUSE,
5641
- Quaternion as Quaternion3,
5783
+ Quaternion as Quaternion4,
5642
5784
  Spherical,
5643
5785
  TOUCH,
5644
5786
  Vector2 as Vector23,
5645
- Vector3 as Vector38
5787
+ Vector3 as Vector39
5646
5788
  } from "three";
5647
5789
  var _changeEvent = { type: "change" };
5648
5790
  var _startEvent = { type: "start" };
@@ -5656,7 +5798,7 @@ var OrbitControls = class extends EventDispatcher {
5656
5798
  this.domElement = domElement;
5657
5799
  this.domElement.style.touchAction = "none";
5658
5800
  this.enabled = true;
5659
- this.target = new Vector38();
5801
+ this.target = new Vector39();
5660
5802
  this.minDistance = 0;
5661
5803
  this.maxDistance = Infinity;
5662
5804
  this.minZoom = 0;
@@ -5708,11 +5850,11 @@ var OrbitControls = class extends EventDispatcher {
5708
5850
  state = STATE.NONE;
5709
5851
  };
5710
5852
  this.update = function() {
5711
- const offset = new Vector38();
5712
- const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
5853
+ const offset = new Vector39();
5854
+ const quat = new Quaternion4().setFromUnitVectors(object.up, new Vector39(0, 1, 0));
5713
5855
  const quatInverse = quat.clone().invert();
5714
- const lastPosition = new Vector38();
5715
- const lastQuaternion = new Quaternion3();
5856
+ const lastPosition = new Vector39();
5857
+ const lastQuaternion = new Quaternion4();
5716
5858
  const twoPI = 2 * Math.PI;
5717
5859
  return function update() {
5718
5860
  const position = scope.object.position;
@@ -5801,7 +5943,7 @@ var OrbitControls = class extends EventDispatcher {
5801
5943
  const spherical = new Spherical();
5802
5944
  const sphericalDelta = new Spherical();
5803
5945
  let scale = 1;
5804
- const panOffset = new Vector38();
5946
+ const panOffset = new Vector39();
5805
5947
  let zoomChanged = false;
5806
5948
  const rotateStart = new Vector23();
5807
5949
  const rotateEnd = new Vector23();
@@ -5827,7 +5969,7 @@ var OrbitControls = class extends EventDispatcher {
5827
5969
  sphericalDelta.phi -= angle;
5828
5970
  }
5829
5971
  const panLeft = function() {
5830
- const v = new Vector38();
5972
+ const v = new Vector39();
5831
5973
  return function panLeft2(distance, objectMatrix) {
5832
5974
  v.setFromMatrixColumn(objectMatrix, 0);
5833
5975
  v.multiplyScalar(-distance);
@@ -5835,7 +5977,7 @@ var OrbitControls = class extends EventDispatcher {
5835
5977
  };
5836
5978
  }();
5837
5979
  const panUp = function() {
5838
- const v = new Vector38();
5980
+ const v = new Vector39();
5839
5981
  return function panUp2(distance, objectMatrix) {
5840
5982
  if (scope.screenSpacePanning === true) {
5841
5983
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -5848,7 +5990,7 @@ var OrbitControls = class extends EventDispatcher {
5848
5990
  };
5849
5991
  }();
5850
5992
  const pan = function() {
5851
- const offset = new Vector38();
5993
+ const offset = new Vector39();
5852
5994
  return function pan2(deltaX, deltaY) {
5853
5995
  const element = scope.domElement;
5854
5996
  if (scope.object.isPerspectiveCamera) {
@@ -6325,8 +6467,8 @@ var Renderer = class _Renderer {
6325
6467
  top: void 0,
6326
6468
  bottom: void 0
6327
6469
  },
6328
- position: new Vector39(50, 50, 50),
6329
- lookingAt: new Vector39(0, 0, 0)
6470
+ position: new Vector310(50, 50, 50),
6471
+ lookingAt: new Vector310(0, 0, 0)
6330
6472
  },
6331
6473
  render: {
6332
6474
  fpsLimit: 60,
@@ -6791,10 +6933,10 @@ var Skins = class {
6791
6933
  };
6792
6934
 
6793
6935
  // src/world/Chunk.ts
6794
- import { Box3 as Box32, Object3D as Object3D6, Vector3 as Vector311 } from "three";
6936
+ import { Box3 as Box32, Object3D as Object3D6, Vector3 as Vector312 } from "three";
6795
6937
 
6796
6938
  // src/world/MineRenderWorld.ts
6797
- import { Vector3 as Vector310 } from "three";
6939
+ import { Vector3 as Vector311 } from "three";
6798
6940
  var MineRenderWorld = class {
6799
6941
  constructor(scene) {
6800
6942
  this._size = 4;
@@ -6805,10 +6947,10 @@ var MineRenderWorld = class {
6805
6947
  }
6806
6948
  getBlockAt(posOrX, y, z) {
6807
6949
  if (typeof posOrX == "number") {
6808
- return this.getBlockAt(new Vector310(posOrX, y, z));
6950
+ return this.getBlockAt(new Vector311(posOrX, y, z));
6809
6951
  }
6810
6952
  if (isTripleArray(posOrX)) {
6811
- return this.getBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]));
6953
+ return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
6812
6954
  }
6813
6955
  const chunk = this.getChunkAt(posOrX);
6814
6956
  if (typeof chunk === "undefined") {
@@ -6819,10 +6961,10 @@ var MineRenderWorld = class {
6819
6961
  }
6820
6962
  async setBlockAt(posOrX, yOrBlock, z, block) {
6821
6963
  if (typeof posOrX == "number") {
6822
- return this.setBlockAt(new Vector310(posOrX, yOrBlock, z), block);
6964
+ return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
6823
6965
  }
6824
6966
  if (isTripleArray(posOrX)) {
6825
- return this.setBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
6967
+ return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
6826
6968
  }
6827
6969
  this.validatePosBounds(posOrX);
6828
6970
  const chunk = this.getOrCreateChunkAt(posOrX);
@@ -6868,14 +7010,14 @@ var MineRenderWorld = class {
6868
7010
  return this._chunks[index];
6869
7011
  }
6870
7012
  static worldToScenePosition(pos) {
6871
- return new Vector310(
7013
+ return new Vector311(
6872
7014
  pos.x * 16,
6873
7015
  pos.y * 16,
6874
7016
  pos.z * 16
6875
7017
  );
6876
7018
  }
6877
7019
  static sceneToWorldPosition(pos) {
6878
- return new Vector310(
7020
+ return new Vector311(
6879
7021
  pos.x / 16,
6880
7022
  pos.y / 16,
6881
7023
  pos.z / 16
@@ -6917,7 +7059,7 @@ var Chunk = class _Chunk {
6917
7059
  scene.add(anchor);
6918
7060
  anchor.position.set(this.x * 256 + 128 - 8, this.y * 256 + 128 - 8, this.z * 256 + 128 - 8);
6919
7061
  addBox3WireframeToObject(
6920
- new Box32(new Vector311(0, 0, 0), new Vector311(256, 256, 256)),
7062
+ new Box32(new Vector312(0, 0, 0), new Vector312(256, 256, 256)),
6921
7063
  anchor,
6922
7064
  16776960,
6923
7065
  4
@@ -6925,10 +7067,10 @@ var Chunk = class _Chunk {
6925
7067
  }
6926
7068
  getBlockAt(posOrX, y, z) {
6927
7069
  if (typeof posOrX == "number") {
6928
- return this.getBlockAt(new Vector311(posOrX, y, z));
7070
+ return this.getBlockAt(new Vector312(posOrX, y, z));
6929
7071
  }
6930
7072
  if (isTripleArray(posOrX)) {
6931
- return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
7073
+ return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
6932
7074
  }
6933
7075
  const pos = this.worldPosToChunkPos(posOrX);
6934
7076
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -6936,10 +7078,10 @@ var Chunk = class _Chunk {
6936
7078
  }
6937
7079
  async setBlockAt(posOrX, yOrBlock, z, block) {
6938
7080
  if (typeof posOrX == "number") {
6939
- return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
7081
+ return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
6940
7082
  }
6941
7083
  if (isTripleArray(posOrX)) {
6942
- return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
7084
+ return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
6943
7085
  }
6944
7086
  const worldPos = posOrX;
6945
7087
  const pos = this.worldPosToChunkPos(worldPos);
@@ -6985,7 +7127,7 @@ var Chunk = class _Chunk {
6985
7127
  }
6986
7128
  async clear() {
6987
7129
  let promises = [];
6988
- let pos = new Vector311();
7130
+ let pos = new Vector312();
6989
7131
  for (let x = 0; x < 16; x++) {
6990
7132
  for (let z = 0; z < 16; z++) {
6991
7133
  for (let y = 0; y < 16; y++) {
@@ -7004,14 +7146,14 @@ var Chunk = class _Chunk {
7004
7146
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
7005
7147
  }
7006
7148
  worldPosToChunkPos(pos) {
7007
- return new Vector311(
7149
+ return new Vector312(
7008
7150
  pos.x - this.x * 16,
7009
7151
  pos.y - this.y * 16,
7010
7152
  pos.z - this.z * 16
7011
7153
  );
7012
7154
  }
7013
7155
  chunkPosToWorldPos(pos) {
7014
- return new Vector311(
7156
+ return new Vector312(
7015
7157
  this.x * 16 + pos.x,
7016
7158
  this.y * 16 + pos.y,
7017
7159
  this.z * 16 + pos.z
@@ -7035,6 +7177,7 @@ export {
7035
7177
  BlockEntityModels,
7036
7178
  BlockObject,
7037
7179
  BlockStates,
7180
+ BlockTints,
7038
7181
  BrowserArchiveProxy,
7039
7182
  CUBE_FACES,
7040
7183
  Caching,
@@ -7049,6 +7192,7 @@ export {
7049
7192
  DISPLAY_POSITIONS,
7050
7193
  DefaultBlockStates,
7051
7194
  DisplayPosition,
7195
+ DisplayTransforms,
7052
7196
  Entities,
7053
7197
  EntityModels,
7054
7198
  EntityObject,