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.
@@ -412,6 +412,7 @@ var _Caching = class _Caching {
412
412
  this.blockStateCache,
413
413
  this.listAssetCache,
414
414
  this.defaultBlockStatesCache,
415
+ this.blockTintCache,
415
416
  this.entityModelsCache
416
417
  ];
417
418
  }
@@ -454,6 +455,7 @@ _Caching.modelTextureAtlasCache = Caches.builder().expireAfterWrite(Time.minutes
454
455
  _Caching.blockStateCache = Caches.builder().expireAfterWrite(Time.minutes(10)).expireAfterAccess(Time.minutes(5)).expirationInterval(Time.seconds(30)).buildAsync();
455
456
  _Caching.listAssetCache = _Caching.createAssetCache();
456
457
  _Caching.defaultBlockStatesCache = _Caching.createAssetCache();
458
+ _Caching.blockTintCache = _Caching.createAssetCache();
457
459
  _Caching.entityModelsCache = _Caching.createAssetCache();
458
460
  var Caching = _Caching;
459
461
 
@@ -1091,7 +1093,7 @@ var Meshes = class _Meshes {
1091
1093
  };
1092
1094
 
1093
1095
  // src/UVMapper.ts
1094
- import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector33 } from "three";
1096
+ import { Float32BufferAttribute as Float32BufferAttribute2, Vector2, Vector3 as Vector34 } from "three";
1095
1097
 
1096
1098
  // src/model/ModelMerger.ts
1097
1099
  var import_ts_deepmerge = __toESM(require_dist());
@@ -1182,15 +1184,77 @@ function isAssetKey(obj) {
1182
1184
  return isBasicAssetKey(obj) && obj.isAssetKey === true;
1183
1185
  }
1184
1186
 
1187
+ // src/model/DisplayTransforms.ts
1188
+ import { Euler, Matrix4, Quaternion, Vector3 as Vector32 } from "three";
1189
+
1190
+ // src/model/DisplayPosition.ts
1191
+ var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
1192
+ DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
1193
+ DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
1194
+ DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
1195
+ DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
1196
+ DisplayPosition2["GUI"] = "gui";
1197
+ DisplayPosition2["HEAD"] = "head";
1198
+ DisplayPosition2["GROUND"] = "ground";
1199
+ DisplayPosition2["FIXED"] = "fixed";
1200
+ DisplayPosition2["ON_SHELF"] = "on_shelf";
1201
+ return DisplayPosition2;
1202
+ })(DisplayPosition || {});
1203
+ var DISPLAY_POSITIONS = Object.values(DisplayPosition);
1204
+
1205
+ // src/model/DisplayTransforms.ts
1206
+ var DisplayTransforms = class {
1207
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
1208
+ static withHandFallbacks(display) {
1209
+ if (!display) return void 0;
1210
+ const resolved = { ...display };
1211
+ for (const [left, right] of [
1212
+ ["thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */, "thirdperson_righthand" /* THIRDPERSON_RIGHTHAND */],
1213
+ ["firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */, "firstperson_righthand" /* FIRSTPERSON_RIGHTHAND */]
1214
+ ]) {
1215
+ if (resolved[left] === void 0 && resolved[right] !== void 0) resolved[left] = resolved[right];
1216
+ }
1217
+ return resolved;
1218
+ }
1219
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
1220
+ static getMatrix(display, position) {
1221
+ const transform = this.withHandFallbacks(display)?.[position] ?? {};
1222
+ const left = position === "firstperson_lefthand" /* FIRSTPERSON_LEFTHAND */ || position === "thirdperson_lefthand" /* THIRDPERSON_LEFTHAND */;
1223
+ const sign = left ? -1 : 1;
1224
+ const [x, y, z] = transform.rotation ?? [0, 0, 0];
1225
+ const rotation = new Quaternion().setFromEuler(new Euler(toRadians(x), sign * toRadians(y), sign * toRadians(z), "XYZ"));
1226
+ const translation = new Vector32(...transform.translation ?? [0, 0, 0]).clampScalar(-80, 80);
1227
+ translation.x *= sign;
1228
+ const scale = new Vector32(...transform.scale ?? [1, 1, 1]).clampScalar(-4, 4);
1229
+ return new Matrix4().compose(translation, rotation, scale);
1230
+ }
1231
+ static apply(geometry, matrix) {
1232
+ geometry.applyMatrix4(matrix);
1233
+ if (matrix.determinant() < 0) {
1234
+ if (!geometry.index) geometry.setIndex(Array.from({ length: geometry.getAttribute("position").count }, (_, i) => i));
1235
+ const index = geometry.index;
1236
+ for (let i = 0; i < index.count; i += 3) {
1237
+ const second = index.getX(i + 1);
1238
+ index.setX(i + 1, index.getX(i + 2));
1239
+ index.setX(i + 2, second);
1240
+ }
1241
+ index.needsUpdate = true;
1242
+ }
1243
+ }
1244
+ };
1245
+
1185
1246
  // src/model/ModelMerger.ts
1186
1247
  var ModelMerger = class {
1187
1248
  static async mergeWithParents(model) {
1188
1249
  const models = await this.collectAllParents(model);
1189
1250
  let merged = {};
1190
- for (let parentModel of models) {
1191
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, parentModel);
1251
+ for (const source of [...models, model]) {
1252
+ const inheritedDisplay = merged.display;
1253
+ merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, source);
1254
+ if (source.display) {
1255
+ merged.display = { ...inheritedDisplay, ...DisplayTransforms.withHandFallbacks(source.display) };
1256
+ }
1192
1257
  }
1193
- merged = import_ts_deepmerge.default.withOptions({ mergeArrays: false }, merged, model);
1194
1258
  merged.hierarchy = models.map((m) => m.parent).filter((p12) => `${p12}`);
1195
1259
  merged.hierarchy.push(`${merged.parent}`);
1196
1260
  return merged;
@@ -1445,9 +1509,9 @@ var BatchedExecutor = class {
1445
1509
  };
1446
1510
 
1447
1511
  // src/util/model.ts
1448
- import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector32 } from "three";
1512
+ import { AxesHelper, BoxGeometry as BoxGeometry2, EdgesGeometry, LineBasicMaterial, LineSegments, Vector3 as Vector33 } from "three";
1449
1513
  function applyElementRotation(rotation, geometry) {
1450
- const origin = new Vector32(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1514
+ const origin = new Vector33(rotation.origin[0], rotation.origin[1], rotation.origin[2]);
1451
1515
  geometry.translate(-origin.x, -origin.y, -origin.z);
1452
1516
  switch (rotation.axis) {
1453
1517
  case "x" /* X */:
@@ -1472,7 +1536,7 @@ function applyElementRotation(rotation, geometry) {
1472
1536
  geometry.translate(origin.x, origin.y, origin.z);
1473
1537
  }
1474
1538
  function applyModelPartRotation(modelPart, geometry) {
1475
- const origin = new Vector32(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1539
+ const origin = new Vector33(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1476
1540
  geometry.translate(-origin.x, -origin.y, -origin.z);
1477
1541
  geometry.rotateX(toRadians(modelPart.pitch));
1478
1542
  geometry.rotateY(toRadians(modelPart.yaw));
@@ -1482,18 +1546,18 @@ function applyModelPartRotation(modelPart, geometry) {
1482
1546
  function applyGenericRotation(axis, rotation, obj) {
1483
1547
  switch (axis) {
1484
1548
  case "x" /* X */:
1485
- obj.rotateOnAxis(new Vector32(1, 0, 0), toRadians(rotation));
1549
+ obj.rotateOnAxis(new Vector33(1, 0, 0), toRadians(rotation));
1486
1550
  break;
1487
1551
  case "y" /* Y */:
1488
- obj.rotateOnAxis(new Vector32(0, 1, 0), toRadians(rotation));
1552
+ obj.rotateOnAxis(new Vector33(0, 1, 0), toRadians(rotation));
1489
1553
  break;
1490
1554
  case "z" /* Z */:
1491
- obj.rotateOnAxis(new Vector32(0, 0, 1), toRadians(rotation));
1555
+ obj.rotateOnAxis(new Vector33(0, 0, 1), toRadians(rotation));
1492
1556
  break;
1493
1557
  }
1494
1558
  }
1495
1559
  function addBox3WireframeToObject(box, obj, color = 16777215, w = 2) {
1496
- let size = new Vector32();
1560
+ let size = new Vector33();
1497
1561
  box.getSize(size);
1498
1562
  let boxGeo = new BoxGeometry2(size.x, size.y, size.z, 1, 1, 1);
1499
1563
  let wireGeo = new EdgesGeometry(boxGeo);
@@ -2061,12 +2125,12 @@ var X = 0;
2061
2125
  var Y = 1;
2062
2126
  var Z = 2;
2063
2127
  var FACE_UV_AXES = {
2064
- east: [new Vector33(0, 0, -1), new Vector33(0, -1, 0)],
2065
- west: [new Vector33(0, 0, 1), new Vector33(0, -1, 0)],
2066
- up: [new Vector33(1, 0, 0), new Vector33(0, 0, 1)],
2067
- down: [new Vector33(1, 0, 0), new Vector33(0, 0, -1)],
2068
- south: [new Vector33(1, 0, 0), new Vector33(0, -1, 0)],
2069
- north: [new Vector33(-1, 0, 0), new Vector33(0, -1, 0)]
2128
+ east: [new Vector34(0, 0, -1), new Vector34(0, -1, 0)],
2129
+ west: [new Vector34(0, 0, 1), new Vector34(0, -1, 0)],
2130
+ up: [new Vector34(1, 0, 0), new Vector34(0, 0, 1)],
2131
+ down: [new Vector34(1, 0, 0), new Vector34(0, 0, -1)],
2132
+ south: [new Vector34(1, 0, 0), new Vector34(0, -1, 0)],
2133
+ north: [new Vector34(-1, 0, 0), new Vector34(0, -1, 0)]
2070
2134
  };
2071
2135
  var UVMapper = class {
2072
2136
  static makeUv(uvCoord, originalTextureSize, actualTextureSize) {
@@ -2647,7 +2711,7 @@ var BlockEntityModels = class {
2647
2711
  };
2648
2712
 
2649
2713
  // src/renderer/SceneObject.ts
2650
- import { Euler as Euler2, InstancedMesh, MathUtils, Matrix4 as Matrix42, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion2, Vector3 as Vector34 } from "three";
2714
+ import { Euler as Euler3, InstancedMesh, MathUtils, Matrix4 as Matrix43, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector35 } from "three";
2651
2715
 
2652
2716
  // src/instance/InstanceReference.ts
2653
2717
  var InstanceReference = class {
@@ -2884,7 +2948,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2884
2948
  nextInstance() {
2885
2949
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2886
2950
  const i = this._instanceCounter++;
2887
- this.setMatrixAt(i, new Matrix42());
2951
+ this.setMatrixAt(i, new Matrix43());
2888
2952
  const mesh = this.children[0];
2889
2953
  if (mesh && isInstancedMesh(mesh)) {
2890
2954
  mesh.count = Math.min(this._instanceCounter, mesh.instanceMatrix.count);
@@ -2901,7 +2965,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2901
2965
  }
2902
2966
  //</editor-fold>
2903
2967
  //<editor-fold desc="TRANSFORMATION">
2904
- getMatrixAt(index, matrix = new Matrix42()) {
2968
+ getMatrixAt(index, matrix = new Matrix43()) {
2905
2969
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2906
2970
  const child = this.children[0];
2907
2971
  if (child && isInstancedMesh(child)) {
@@ -2920,16 +2984,16 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2920
2984
  }
2921
2985
  setPositionRotationScaleAt(index, position, rotation, scale) {
2922
2986
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2923
- const oldPosition = new Vector34();
2924
- const oldRotation = new Quaternion2();
2925
- const oldScale = new Vector34();
2926
- const matrix = new Matrix42();
2987
+ const oldPosition = new Vector35();
2988
+ const oldRotation = new Quaternion3();
2989
+ const oldScale = new Vector35();
2990
+ const matrix = new Matrix43();
2927
2991
  if (!scale || !rotation || !position) {
2928
2992
  this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
2929
2993
  }
2930
2994
  matrix.compose(
2931
2995
  position ? position : oldPosition,
2932
- rotation ? new Quaternion2().setFromEuler(rotation) : oldRotation,
2996
+ rotation ? new Quaternion3().setFromEuler(rotation) : oldRotation,
2933
2997
  scale ? scale : oldScale
2934
2998
  );
2935
2999
  this.setMatrixAt(index, matrix);
@@ -2938,7 +3002,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2938
3002
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2939
3003
  this.setPositionRotationScaleAt(index, position);
2940
3004
  }
2941
- getPositionAt(index, vector = new Vector34()) {
3005
+ getPositionAt(index, vector = new Vector35()) {
2942
3006
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2943
3007
  const matrix = this.getMatrixAt(index);
2944
3008
  vector.setFromMatrixPosition(matrix);
@@ -2948,7 +3012,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2948
3012
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2949
3013
  this.setPositionRotationScaleAt(index, void 0, rotation, void 0);
2950
3014
  }
2951
- getRotationAt(index, euler = new Euler2()) {
3015
+ getRotationAt(index, euler = new Euler3()) {
2952
3016
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2953
3017
  const matrix = this.getMatrixAt(index);
2954
3018
  euler.setFromRotationMatrix(matrix);
@@ -2958,7 +3022,7 @@ var _SceneObject = class _SceneObject extends Object3D2 {
2958
3022
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2959
3023
  this.setPositionRotationScaleAt(index, void 0, void 0, scale);
2960
3024
  }
2961
- getScaleAt(index, vector = new Vector34()) {
3025
+ getScaleAt(index, vector = new Vector35()) {
2962
3026
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
2963
3027
  const matrix = this.getMatrixAt(index);
2964
3028
  vector.setFromMatrixScale(matrix);
@@ -3584,20 +3648,6 @@ function isInstanceable(obj) {
3584
3648
  return "nextInstance" in obj;
3585
3649
  }
3586
3650
 
3587
- // src/model/DisplayPosition.ts
3588
- var DisplayPosition = /* @__PURE__ */ ((DisplayPosition2) => {
3589
- DisplayPosition2["THIRDPERSON_RIGHTHAND"] = "thirdperson_righthand";
3590
- DisplayPosition2["THIRDPERSON_LEFTHAND"] = "thirdperson_lefthand";
3591
- DisplayPosition2["FIRSTPERSON_RIGHTHAND"] = "firstperson_righthand";
3592
- DisplayPosition2["FIRSTPERSON_LEFTHAND"] = "firstperson_lefthand";
3593
- DisplayPosition2["GUI"] = "gui";
3594
- DisplayPosition2["HEAD"] = "head";
3595
- DisplayPosition2["GROUND"] = "ground";
3596
- DisplayPosition2["FIXED"] = "fixed";
3597
- return DisplayPosition2;
3598
- })(DisplayPosition || {});
3599
- var DISPLAY_POSITIONS = Object.values(DisplayPosition);
3600
-
3601
3651
  // src/model/GuiLight.ts
3602
3652
  var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
3603
3653
  GuiLight2["FRONT"] = "front";
@@ -3620,8 +3670,93 @@ function isQuadArray(obj) {
3620
3670
  return Array.isArray(obj) && obj.length === 4;
3621
3671
  }
3622
3672
 
3673
+ // src/model/block/blockTints.json
3674
+ var blockTints_default = {
3675
+ "minecraft:large_fern": { source: "grass" },
3676
+ "minecraft:tall_grass": { source: "grass" },
3677
+ "minecraft:grass_block": { source: "grass" },
3678
+ "minecraft:fern": { source: "grass" },
3679
+ "minecraft:grass": { source: "grass" },
3680
+ "minecraft:short_grass": { source: "grass" },
3681
+ "minecraft:potted_fern": { source: "grass" },
3682
+ "minecraft:bush": { source: "grass" },
3683
+ "minecraft:pink_petals": { source: "grass", untinted: [0] },
3684
+ "minecraft:wildflowers": { source: "grass", untinted: [0] },
3685
+ "minecraft:spruce_leaves": { source: "constant", color: 6396257 },
3686
+ "minecraft:birch_leaves": { source: "constant", color: 8431445 },
3687
+ "minecraft:oak_leaves": { source: "constant", color: 4764952 },
3688
+ "minecraft:jungle_leaves": { source: "constant", color: 4764952 },
3689
+ "minecraft:acacia_leaves": { source: "constant", color: 4764952 },
3690
+ "minecraft:dark_oak_leaves": { source: "constant", color: 4764952 },
3691
+ "minecraft:vine": { source: "constant", color: 4764952 },
3692
+ "minecraft:mangrove_leaves": { source: "constant", color: 4764952 },
3693
+ "minecraft:leaf_litter": { source: "constant", color: 6044722 },
3694
+ "minecraft:water_cauldron": { source: "constant", color: 4159204 },
3695
+ "minecraft:redstone_wire": { source: "redstone" },
3696
+ "minecraft:attached_melon_stem": { source: "constant", color: 14731036 },
3697
+ "minecraft:attached_pumpkin_stem": { source: "constant", color: 14731036 },
3698
+ "minecraft:melon_stem": { source: "stem" },
3699
+ "minecraft:pumpkin_stem": { source: "stem" },
3700
+ "minecraft:lily_pad": { source: "constant", color: 7455580 }
3701
+ };
3702
+
3703
+ // src/model/block/BlockTints.ts
3704
+ var rules = blockTints_default;
3705
+ var BlockTints = class {
3706
+ /** Resolves block preview colors without biome context; explicit tints take precedence. */
3707
+ static async get(key, state, model, tints) {
3708
+ const rule = key && rules[key.toNamespacedString()];
3709
+ if (!key || !rule) return tints;
3710
+ const indices = /* @__PURE__ */ new Set();
3711
+ for (const element of model.elements ?? []) {
3712
+ for (const face of Object.values(element.faces)) {
3713
+ const index = face?.tintindex;
3714
+ if (index !== void 0 && index >= 0 && tints?.[index] === void 0 && !rule.untinted?.includes(index)) {
3715
+ indices.add(index);
3716
+ }
3717
+ }
3718
+ }
3719
+ if (!indices.size) return tints;
3720
+ let color;
3721
+ switch (rule.source) {
3722
+ case "constant":
3723
+ color = rule.color;
3724
+ break;
3725
+ case "grass":
3726
+ color = await this.grassColor(key);
3727
+ break;
3728
+ case "redstone": {
3729
+ const power = Number(state.power ?? 0) / 15;
3730
+ const red = power * 0.6 + (power > 0 ? 0.4 : 0.3);
3731
+ const green = Math.max(0, power * power * 0.7 - 0.5);
3732
+ const blue = Math.max(0, power * power * 0.6 - 0.7);
3733
+ color = Math.floor(red * 255) << 16 | Math.floor(green * 255) << 8 | Math.floor(blue * 255);
3734
+ break;
3735
+ }
3736
+ case "stem": {
3737
+ const age = Number(state.age ?? 0);
3738
+ color = age * 32 << 16 | 255 - age * 8 << 8 | age * 4;
3739
+ break;
3740
+ }
3741
+ }
3742
+ return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
3743
+ }
3744
+ static async grassColor(origin) {
3745
+ const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
3746
+ return await Caching.blockTintCache.get(key.serialize(), async () => {
3747
+ const image = await ModelTextures.get(key);
3748
+ if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
3749
+ if (image.width !== 256 || image.height !== 256) {
3750
+ throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
3751
+ }
3752
+ const [red, green, blue] = image.data.getImageData(127, 127, 1, 1).data;
3753
+ return red << 16 | green << 8 | blue;
3754
+ });
3755
+ }
3756
+ };
3757
+
3623
3758
  // src/model/scene/ModelObject.ts
3624
- import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler4, Matrix4 as Matrix45 } from "three";
3759
+ import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute4, Color as Color3, Euler as Euler5, Matrix4 as Matrix46 } from "three";
3625
3760
 
3626
3761
  // src/three/BufferGeometryUtils.js
3627
3762
  import {
@@ -3633,7 +3768,7 @@ import {
3633
3768
  TriangleFanDrawMode,
3634
3769
  TriangleStripDrawMode,
3635
3770
  TrianglesDrawMode,
3636
- Vector3 as Vector36
3771
+ Vector3 as Vector37
3637
3772
  } from "three";
3638
3773
  function computeTangents(geometry) {
3639
3774
  geometry.computeTangents();
@@ -3952,15 +4087,15 @@ function computeMorphedAttributes(object) {
3952
4087
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
3953
4088
  return null;
3954
4089
  }
3955
- const _vA = new Vector36();
3956
- const _vB = new Vector36();
3957
- const _vC = new Vector36();
3958
- const _tempA = new Vector36();
3959
- const _tempB = new Vector36();
3960
- const _tempC = new Vector36();
3961
- const _morphA = new Vector36();
3962
- const _morphB = new Vector36();
3963
- const _morphC = new Vector36();
4090
+ const _vA = new Vector37();
4091
+ const _vB = new Vector37();
4092
+ const _vC = new Vector37();
4093
+ const _tempA = new Vector37();
4094
+ const _tempB = new Vector37();
4095
+ const _tempC = new Vector37();
4096
+ const _morphA = new Vector37();
4097
+ const _morphB = new Vector37();
4098
+ const _morphC = new Vector37();
3964
4099
  function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
3965
4100
  _vA.fromBufferAttribute(attribute, a2);
3966
4101
  _vB.fromBufferAttribute(attribute, b2);
@@ -4197,13 +4332,14 @@ var _ModelObject = class _ModelObject extends SceneObject {
4197
4332
  createMeshes(force = false) {
4198
4333
  if (this.meshesCreated && !force) return;
4199
4334
  const mat = Materials.MISSING_TEXTURE;
4335
+ const displayTransform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : void 0;
4200
4336
  let allGeos = [];
4201
4337
  if (this.atlas) {
4202
4338
  if (this.atlas.model.elements) {
4203
4339
  this.atlas.model.elements?.forEach((el) => {
4204
4340
  const elGeo = this._getBoxGeometryFromElement(el).clone();
4205
4341
  if (this.options.uvLockRotation) {
4206
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler4(...this.options.uvLockRotation));
4342
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler5(...this.options.uvLockRotation));
4207
4343
  }
4208
4344
  if (this.options.tints) {
4209
4345
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -4219,12 +4355,13 @@ var _ModelObject = class _ModelObject extends SceneObject {
4219
4355
  }
4220
4356
  elGeo.setAttribute("color", new BufferAttribute4(colors, 3));
4221
4357
  }
4222
- 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));
4223
- elGeo.applyMatrix4(new Matrix45().makeTranslation(el.from[0], el.from[1], el.from[2]));
4358
+ 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));
4359
+ elGeo.applyMatrix4(new Matrix46().makeTranslation(el.from[0], el.from[1], el.from[2]));
4224
4360
  if (el.rotation) {
4225
4361
  applyElementRotation(el.rotation, elGeo);
4226
4362
  }
4227
- elGeo.applyMatrix4(new Matrix45().makeTranslation(-8, -8, -8));
4363
+ elGeo.applyMatrix4(new Matrix46().makeTranslation(-8, -8, -8));
4364
+ if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
4228
4365
  if (this.options.mergeMeshes) {
4229
4366
  allGeos.push(elGeo);
4230
4367
  } else {
@@ -4246,6 +4383,7 @@ var _ModelObject = class _ModelObject extends SceneObject {
4246
4383
  combinedGeo = mergeBufferGeometries(allGeos);
4247
4384
  } else {
4248
4385
  combinedGeo = new BoxGeometry5(16, 16, 16);
4386
+ if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
4249
4387
  }
4250
4388
  combinedGeo.computeBoundingBox();
4251
4389
  let mesh;
@@ -4299,7 +4437,7 @@ function isModelObject(obj) {
4299
4437
 
4300
4438
  // src/model/block/scene/BlockObject.ts
4301
4439
  var import_ts_deepmerge6 = __toESM(require_dist());
4302
- import { Euler as Euler5, Matrix4 as Matrix46, Vector3 as Vector37 } from "three";
4440
+ import { Euler as Euler6, Matrix4 as Matrix47, Vector3 as Vector38 } from "three";
4303
4441
  var p10 = prefix("BlockObject");
4304
4442
  function matchesCondition(condition, state) {
4305
4443
  return Object.entries(condition).every(([key, value]) => {
@@ -4356,7 +4494,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4356
4494
  if (isModelObject(model)) {
4357
4495
  model.removeFromScene();
4358
4496
  } else if (isInstanceReference(model)) {
4359
- model.setScale(new Vector37(0, 0, 0));
4497
+ model.setScale(new Vector38(0, 0, 0));
4360
4498
  }
4361
4499
  }
4362
4500
  super.removeFromScene();
@@ -4417,7 +4555,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4417
4555
  }
4418
4556
  for (let model of this._models) {
4419
4557
  if (isInstanceReference(model)) {
4420
- model.setScale(new Vector37(0, 0, 0));
4558
+ model.setScale(new Vector38(0, 0, 0));
4421
4559
  } else {
4422
4560
  model.dispose();
4423
4561
  }
@@ -4454,7 +4592,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4454
4592
  await this.createVariant(variant);
4455
4593
  }
4456
4594
  async createVariant(variant) {
4457
- const rotation = new Euler5();
4595
+ const rotation = new Euler6();
4458
4596
  if (typeof variant.x !== "undefined") {
4459
4597
  rotation.x = toRadians(clampRotationDegrees(variant.x));
4460
4598
  }
@@ -4464,6 +4602,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4464
4602
  const model = await Models.getMerged(AssetKey.parse("models", variant.model));
4465
4603
  const options = {
4466
4604
  ...this.options,
4605
+ tints: model ? await BlockTints.get(this.blockState.key, this.state, model, this.options.tints) : this.options.tints,
4467
4606
  uvLockRotation: variant.uvlock && (rotation.x !== 0 || rotation.y !== 0) ? [rotation.x, rotation.y, rotation.z] : void 0
4468
4607
  };
4469
4608
  const obj = await this.scene.addModel(model, options);
@@ -4540,7 +4679,7 @@ var _BlockObject = class _BlockObject extends SceneObject {
4540
4679
  setPositionRotationScaleAt(index, position, rotation, scale) {
4541
4680
  super.setPositionRotationScaleAt(index, position, rotation, scale);
4542
4681
  }
4543
- getMatrixAt(index, matrix = new Matrix46()) {
4682
+ getMatrixAt(index, matrix = new Matrix47()) {
4544
4683
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
4545
4684
  const child = this._models[0];
4546
4685
  if (child && isModelObject(child)) {
@@ -5536,7 +5675,8 @@ var _MineRenderScene = class _MineRenderScene extends Scene2 {
5536
5675
  console.log("instanceMeshes + key");
5537
5676
  let key = asset.key.serialize();
5538
5677
  if (isModelObject(obj)) {
5539
- const { uvLockRotation, tints } = obj.options;
5678
+ const { displayPosition, uvLockRotation, tints } = obj.options;
5679
+ if (displayPosition) key += `|display:${displayPosition}`;
5540
5680
  if (uvLockRotation) key += `|uvlock:${uvLockRotation.join(",")}`;
5541
5681
  const palette = Object.entries(tints ?? {}).sort(([a], [b]) => Number(a) - Number(b));
5542
5682
  if (palette.length) key += `|tints:${JSON.stringify(palette)}`;
@@ -5585,7 +5725,7 @@ function isMineRenderScene(obj) {
5585
5725
  }
5586
5726
 
5587
5727
  // src/renderer/Renderer.ts
5588
- import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector39, WebGLRenderer } from "three";
5728
+ import { AxesHelper as AxesHelper3, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera, SRGBColorSpace as SRGBColorSpace3, Vector3 as Vector310, WebGLRenderer } from "three";
5589
5729
  var import_ts_deepmerge9 = __toESM(require_dist());
5590
5730
  import Stats from "stats.js";
5591
5731
  import { EffectComposer, RenderPass } from "postprocessing";
@@ -5594,11 +5734,11 @@ import { EffectComposer, RenderPass } from "postprocessing";
5594
5734
  import {
5595
5735
  EventDispatcher,
5596
5736
  MOUSE,
5597
- Quaternion as Quaternion3,
5737
+ Quaternion as Quaternion4,
5598
5738
  Spherical,
5599
5739
  TOUCH,
5600
5740
  Vector2 as Vector23,
5601
- Vector3 as Vector38
5741
+ Vector3 as Vector39
5602
5742
  } from "three";
5603
5743
  var _changeEvent = { type: "change" };
5604
5744
  var _startEvent = { type: "start" };
@@ -5612,7 +5752,7 @@ var OrbitControls = class extends EventDispatcher {
5612
5752
  this.domElement = domElement;
5613
5753
  this.domElement.style.touchAction = "none";
5614
5754
  this.enabled = true;
5615
- this.target = new Vector38();
5755
+ this.target = new Vector39();
5616
5756
  this.minDistance = 0;
5617
5757
  this.maxDistance = Infinity;
5618
5758
  this.minZoom = 0;
@@ -5664,11 +5804,11 @@ var OrbitControls = class extends EventDispatcher {
5664
5804
  state = STATE.NONE;
5665
5805
  };
5666
5806
  this.update = function() {
5667
- const offset = new Vector38();
5668
- const quat = new Quaternion3().setFromUnitVectors(object.up, new Vector38(0, 1, 0));
5807
+ const offset = new Vector39();
5808
+ const quat = new Quaternion4().setFromUnitVectors(object.up, new Vector39(0, 1, 0));
5669
5809
  const quatInverse = quat.clone().invert();
5670
- const lastPosition = new Vector38();
5671
- const lastQuaternion = new Quaternion3();
5810
+ const lastPosition = new Vector39();
5811
+ const lastQuaternion = new Quaternion4();
5672
5812
  const twoPI = 2 * Math.PI;
5673
5813
  return function update() {
5674
5814
  const position = scope.object.position;
@@ -5757,7 +5897,7 @@ var OrbitControls = class extends EventDispatcher {
5757
5897
  const spherical = new Spherical();
5758
5898
  const sphericalDelta = new Spherical();
5759
5899
  let scale = 1;
5760
- const panOffset = new Vector38();
5900
+ const panOffset = new Vector39();
5761
5901
  let zoomChanged = false;
5762
5902
  const rotateStart = new Vector23();
5763
5903
  const rotateEnd = new Vector23();
@@ -5783,7 +5923,7 @@ var OrbitControls = class extends EventDispatcher {
5783
5923
  sphericalDelta.phi -= angle;
5784
5924
  }
5785
5925
  const panLeft = function() {
5786
- const v = new Vector38();
5926
+ const v = new Vector39();
5787
5927
  return function panLeft2(distance, objectMatrix) {
5788
5928
  v.setFromMatrixColumn(objectMatrix, 0);
5789
5929
  v.multiplyScalar(-distance);
@@ -5791,7 +5931,7 @@ var OrbitControls = class extends EventDispatcher {
5791
5931
  };
5792
5932
  }();
5793
5933
  const panUp = function() {
5794
- const v = new Vector38();
5934
+ const v = new Vector39();
5795
5935
  return function panUp2(distance, objectMatrix) {
5796
5936
  if (scope.screenSpacePanning === true) {
5797
5937
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -5804,7 +5944,7 @@ var OrbitControls = class extends EventDispatcher {
5804
5944
  };
5805
5945
  }();
5806
5946
  const pan = function() {
5807
- const offset = new Vector38();
5947
+ const offset = new Vector39();
5808
5948
  return function pan2(deltaX, deltaY) {
5809
5949
  const element = scope.domElement;
5810
5950
  if (scope.object.isPerspectiveCamera) {
@@ -6551,8 +6691,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
6551
6691
  top: void 0,
6552
6692
  bottom: void 0
6553
6693
  },
6554
- position: new Vector39(50, 50, 50),
6555
- lookingAt: new Vector39(0, 0, 0)
6694
+ position: new Vector310(50, 50, 50),
6695
+ lookingAt: new Vector310(0, 0, 0)
6556
6696
  },
6557
6697
  render: {
6558
6698
  fpsLimit: 60,
@@ -6746,10 +6886,10 @@ var Skins = class {
6746
6886
  };
6747
6887
 
6748
6888
  // src/world/Chunk.ts
6749
- import { Box3 as Box32, Object3D as Object3D6, Vector3 as Vector311 } from "three";
6889
+ import { Box3 as Box32, Object3D as Object3D6, Vector3 as Vector312 } from "three";
6750
6890
 
6751
6891
  // src/world/MineRenderWorld.ts
6752
- import { Vector3 as Vector310 } from "three";
6892
+ import { Vector3 as Vector311 } from "three";
6753
6893
  var MineRenderWorld = class {
6754
6894
  constructor(scene) {
6755
6895
  this._size = 4;
@@ -6760,10 +6900,10 @@ var MineRenderWorld = class {
6760
6900
  }
6761
6901
  getBlockAt(posOrX, y, z) {
6762
6902
  if (typeof posOrX == "number") {
6763
- return this.getBlockAt(new Vector310(posOrX, y, z));
6903
+ return this.getBlockAt(new Vector311(posOrX, y, z));
6764
6904
  }
6765
6905
  if (isTripleArray(posOrX)) {
6766
- return this.getBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]));
6906
+ return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
6767
6907
  }
6768
6908
  const chunk = this.getChunkAt(posOrX);
6769
6909
  if (typeof chunk === "undefined") {
@@ -6774,10 +6914,10 @@ var MineRenderWorld = class {
6774
6914
  }
6775
6915
  async setBlockAt(posOrX, yOrBlock, z, block) {
6776
6916
  if (typeof posOrX == "number") {
6777
- return this.setBlockAt(new Vector310(posOrX, yOrBlock, z), block);
6917
+ return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
6778
6918
  }
6779
6919
  if (isTripleArray(posOrX)) {
6780
- return this.setBlockAt(new Vector310(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
6920
+ return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
6781
6921
  }
6782
6922
  this.validatePosBounds(posOrX);
6783
6923
  const chunk = this.getOrCreateChunkAt(posOrX);
@@ -6823,14 +6963,14 @@ var MineRenderWorld = class {
6823
6963
  return this._chunks[index];
6824
6964
  }
6825
6965
  static worldToScenePosition(pos) {
6826
- return new Vector310(
6966
+ return new Vector311(
6827
6967
  pos.x * 16,
6828
6968
  pos.y * 16,
6829
6969
  pos.z * 16
6830
6970
  );
6831
6971
  }
6832
6972
  static sceneToWorldPosition(pos) {
6833
- return new Vector310(
6973
+ return new Vector311(
6834
6974
  pos.x / 16,
6835
6975
  pos.y / 16,
6836
6976
  pos.z / 16
@@ -6872,7 +7012,7 @@ var Chunk = class _Chunk {
6872
7012
  scene.add(anchor);
6873
7013
  anchor.position.set(this.x * 256 + 128 - 8, this.y * 256 + 128 - 8, this.z * 256 + 128 - 8);
6874
7014
  addBox3WireframeToObject(
6875
- new Box32(new Vector311(0, 0, 0), new Vector311(256, 256, 256)),
7015
+ new Box32(new Vector312(0, 0, 0), new Vector312(256, 256, 256)),
6876
7016
  anchor,
6877
7017
  16776960,
6878
7018
  4
@@ -6880,10 +7020,10 @@ var Chunk = class _Chunk {
6880
7020
  }
6881
7021
  getBlockAt(posOrX, y, z) {
6882
7022
  if (typeof posOrX == "number") {
6883
- return this.getBlockAt(new Vector311(posOrX, y, z));
7023
+ return this.getBlockAt(new Vector312(posOrX, y, z));
6884
7024
  }
6885
7025
  if (isTripleArray(posOrX)) {
6886
- return this.getBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]));
7026
+ return this.getBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]));
6887
7027
  }
6888
7028
  const pos = this.worldPosToChunkPos(posOrX);
6889
7029
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -6891,10 +7031,10 @@ var Chunk = class _Chunk {
6891
7031
  }
6892
7032
  async setBlockAt(posOrX, yOrBlock, z, block) {
6893
7033
  if (typeof posOrX == "number") {
6894
- return this.setBlockAt(new Vector311(posOrX, yOrBlock, z), block);
7034
+ return this.setBlockAt(new Vector312(posOrX, yOrBlock, z), block);
6895
7035
  }
6896
7036
  if (isTripleArray(posOrX)) {
6897
- return this.setBlockAt(new Vector311(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
7037
+ return this.setBlockAt(new Vector312(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
6898
7038
  }
6899
7039
  const worldPos = posOrX;
6900
7040
  const pos = this.worldPosToChunkPos(worldPos);
@@ -6940,7 +7080,7 @@ var Chunk = class _Chunk {
6940
7080
  }
6941
7081
  async clear() {
6942
7082
  let promises = [];
6943
- let pos = new Vector311();
7083
+ let pos = new Vector312();
6944
7084
  for (let x = 0; x < 16; x++) {
6945
7085
  for (let z = 0; z < 16; z++) {
6946
7086
  for (let y = 0; y < 16; y++) {
@@ -6959,14 +7099,14 @@ var Chunk = class _Chunk {
6959
7099
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
6960
7100
  }
6961
7101
  worldPosToChunkPos(pos) {
6962
- return new Vector311(
7102
+ return new Vector312(
6963
7103
  pos.x - this.x * 16,
6964
7104
  pos.y - this.y * 16,
6965
7105
  pos.z - this.z * 16
6966
7106
  );
6967
7107
  }
6968
7108
  chunkPosToWorldPos(pos) {
6969
- return new Vector311(
7109
+ return new Vector312(
6970
7110
  this.x * 16 + pos.x,
6971
7111
  this.y * 16 + pos.y,
6972
7112
  this.z * 16 + pos.z
@@ -6990,6 +7130,7 @@ export {
6990
7130
  BlockEntityModels,
6991
7131
  BlockObject,
6992
7132
  BlockStates,
7133
+ BlockTints,
6993
7134
  BrowserArchiveProxy,
6994
7135
  BrowserCache,
6995
7136
  BrowserEnv,
@@ -7006,6 +7147,7 @@ export {
7006
7147
  DISPLAY_POSITIONS,
7007
7148
  DefaultBlockStates,
7008
7149
  DisplayPosition,
7150
+ DisplayTransforms,
7009
7151
  Entities,
7010
7152
  EntityModels,
7011
7153
  EntityObject,