minerender 2.1.0-alpha.60 → 2.1.0-alpha.62

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.
@@ -1451,7 +1451,7 @@ var init_Models = __esm({
1451
1451
  }
1452
1452
  static async getItemModel(key) {
1453
1453
  const itemKey = new AssetKey(key.namespace, key.path, "items", void 0, key.rootType, ".json", key.root);
1454
- const model = await this.PERSISTENT_CACHE.getOrLoad(AssetLoader.persistentKey(itemKey.serialize()), async () => {
1454
+ const model = await this.PERSISTENT_CACHE.getOrLoad(`item-v2:${AssetLoader.persistentKey(itemKey.serialize())}`, async () => {
1455
1455
  const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1456
1456
  if (!result) return void 0;
1457
1457
  if (result.key.assetType !== "items") return { ...result.asset, key };
@@ -1460,7 +1460,7 @@ var init_Models = __esm({
1460
1460
  modelKey.root = key.root;
1461
1461
  const model2 = await this.getRaw(modelKey);
1462
1462
  if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
1463
- return selected.special ? { ...model2, special: selected.special } : model2;
1463
+ return { ...model2, ...selected.special && { special: selected.special }, ...selected.tints && { tints: selected.tints } };
1464
1464
  });
1465
1465
  return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1466
1466
  }
@@ -1471,7 +1471,7 @@ var init_Models = __esm({
1471
1471
  }
1472
1472
  switch (node.type.replace(/^minecraft:/, "")) {
1473
1473
  case "model":
1474
- if (typeof node.model === "string" && node.model) return { model: node.model };
1474
+ if (typeof node.model === "string" && node.model) return { model: node.model, tints: node.tints };
1475
1475
  break;
1476
1476
  case "special": {
1477
1477
  if (!node.base || !node.model || typeof node.model !== "object") break;
@@ -3236,11 +3236,11 @@ var init_Entities = __esm({
3236
3236
  return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
3237
3237
  }
3238
3238
  /**
3239
- * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
3239
+ * Native and sampled vanilla clips by name, or undefined when the model or selected version has none.
3240
3240
  */
3241
3241
  static async getAnimations(modelKey) {
3242
3242
  const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
3243
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
3243
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
3244
3244
  const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
3245
3245
  return file?.animations;
3246
3246
  }
@@ -3290,7 +3290,7 @@ function sampleEntityKeyframes(keyframes, time) {
3290
3290
  let low = 0, high = keyframes.length;
3291
3291
  while (low < high) {
3292
3292
  const middle = low + high >>> 1;
3293
- if (time <= keyframes[middle].time) high = middle;
3293
+ if (time < keyframes[middle].time) high = middle;
3294
3294
  else low = middle + 1;
3295
3295
  }
3296
3296
  const a = Math.max(0, low - 1);
@@ -3329,6 +3329,7 @@ var init_EntityAnimation = __esm({
3329
3329
  });
3330
3330
 
3331
3331
  // src/entity/scene/EntityAnimationPlayer.ts
3332
+ import { Euler as Euler3, Vector3 as Vector35 } from "three";
3332
3333
  var ZERO, EntityAnimationPlayer;
3333
3334
  var init_EntityAnimationPlayer = __esm({
3334
3335
  "src/entity/scene/EntityAnimationPlayer.ts"() {
@@ -3348,25 +3349,45 @@ var init_EntityAnimationPlayer = __esm({
3348
3349
  return this._time;
3349
3350
  }
3350
3351
  /**
3351
- * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
3352
- * bones without a matching part are skipped.
3352
+ * Starts an animation on matching named parts. Supplied baked poses are the baseline for offsets;
3353
+ * without them, the current pose is used. Stopping restores the pose from before playback.
3353
3354
  */
3354
- play(layers, animation, options = {}) {
3355
+ play(layers, animation, options = {}, poses) {
3355
3356
  this.stop();
3356
3357
  this._animation = animation;
3357
3358
  this._time = options.time ?? 0;
3358
3359
  this.loop = options.loop ?? animation.loop;
3359
3360
  this.speed = options.speed ?? 1;
3360
3361
  for (const layer of layers) {
3361
- for (const bone of Object.keys(animation.bones)) {
3362
- const object = layer.getObjectByName(`group:${bone}`);
3363
- if (!object) continue;
3364
- this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
3362
+ const objects = [];
3363
+ if (poses) {
3364
+ layer.traverse((object) => {
3365
+ if (poses.has(object)) objects.push(object);
3366
+ });
3367
+ } else {
3368
+ for (const bone of Object.keys(animation.bones)) {
3369
+ const object = layer.getObjectByName(`group:${bone}`);
3370
+ if (object) objects.push(object);
3371
+ }
3372
+ }
3373
+ for (const object of objects) {
3374
+ const bone = object.name.slice("group:".length);
3375
+ const pose = poses?.get(object);
3376
+ this.parts.push({
3377
+ bone,
3378
+ object,
3379
+ position: object.position.clone(),
3380
+ rotation: object.rotation.clone(),
3381
+ scale: object.scale.clone(),
3382
+ basePosition: pose ? new Vector35(...pose.offset) : object.position.clone(),
3383
+ baseRotation: pose ? new Euler3(...pose.rotation, "ZYX") : object.rotation.clone(),
3384
+ baseScale: pose ? new Vector35(...pose.scale ?? [1, 1, 1]) : object.scale.clone()
3385
+ });
3365
3386
  }
3366
3387
  }
3367
3388
  this.apply();
3368
3389
  }
3369
- /** Restores the default poses. Returns whether an animation was active. */
3390
+ /** Restores the poses from before playback. Returns whether an animation was active. */
3370
3391
  stop() {
3371
3392
  if (!this._animation) return false;
3372
3393
  for (const part of this.parts) {
@@ -3395,10 +3416,10 @@ var init_EntityAnimationPlayer = __esm({
3395
3416
  apply() {
3396
3417
  const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
3397
3418
  for (const part of this.parts) {
3398
- const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
3399
- part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
3400
- part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
3401
- part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
3419
+ const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone] ?? {};
3420
+ part.object.position.set(part.basePosition.x + position[0], part.basePosition.y + position[1], part.basePosition.z + position[2]);
3421
+ part.object.rotation.set(part.baseRotation.x + rotation[0], part.baseRotation.y + rotation[1], part.baseRotation.z + rotation[2], part.baseRotation.order);
3422
+ part.object.scale.set(part.baseScale.x + scale[0], part.baseScale.y + scale[1], part.baseScale.z + scale[2]);
3402
3423
  }
3403
3424
  }
3404
3425
  };
@@ -3465,7 +3486,7 @@ var init_InstanceReference = __esm({
3465
3486
  });
3466
3487
 
3467
3488
  // src/renderer/SceneObject.ts
3468
- import { Color as Color2, Euler as Euler3, InstancedBufferAttribute, InstancedMesh, MathUtils, Matrix4 as Matrix44, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector35 } from "three";
3489
+ import { Color as Color2, Euler as Euler4, InstancedBufferAttribute, InstancedMesh, MathUtils, Matrix4 as Matrix44, Mesh as Mesh3, Object3D as Object3D2, Quaternion as Quaternion3, Vector3 as Vector36 } from "three";
3469
3490
  function isSceneObject(obj) {
3470
3491
  return obj.isSceneObject;
3471
3492
  }
@@ -3732,9 +3753,9 @@ var init_SceneObject = __esm({
3732
3753
  }
3733
3754
  setPositionRotationScaleAt(index, position, rotation, scale) {
3734
3755
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3735
- const oldPosition = new Vector35();
3756
+ const oldPosition = new Vector36();
3736
3757
  const oldRotation = new Quaternion3();
3737
- const oldScale = new Vector35();
3758
+ const oldScale = new Vector36();
3738
3759
  const matrix = new Matrix44();
3739
3760
  if (!scale || !rotation || !position) {
3740
3761
  this.getMatrixAt(index, matrix).decompose(oldPosition, oldRotation, oldScale);
@@ -3750,7 +3771,7 @@ var init_SceneObject = __esm({
3750
3771
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3751
3772
  this.setPositionRotationScaleAt(index, position);
3752
3773
  }
3753
- getPositionAt(index, vector = new Vector35()) {
3774
+ getPositionAt(index, vector = new Vector36()) {
3754
3775
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3755
3776
  const matrix = this.getMatrixAt(index);
3756
3777
  vector.setFromMatrixPosition(matrix);
@@ -3760,17 +3781,17 @@ var init_SceneObject = __esm({
3760
3781
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3761
3782
  this.setPositionRotationScaleAt(index, void 0, rotation, void 0);
3762
3783
  }
3763
- getRotationAt(index, euler = new Euler3()) {
3784
+ getRotationAt(index, euler = new Euler4()) {
3764
3785
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3765
3786
  const rotation = new Quaternion3();
3766
- this.getMatrixAt(index).decompose(new Vector35(), rotation, new Vector35());
3787
+ this.getMatrixAt(index).decompose(new Vector36(), rotation, new Vector36());
3767
3788
  return euler.setFromQuaternion(rotation);
3768
3789
  }
3769
3790
  setScaleAt(index, scale) {
3770
3791
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3771
3792
  this.setPositionRotationScaleAt(index, void 0, void 0, scale);
3772
3793
  }
3773
- getScaleAt(index, vector = new Vector35()) {
3794
+ getScaleAt(index, vector = new Vector36()) {
3774
3795
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
3775
3796
  const matrix = this.getMatrixAt(index);
3776
3797
  vector.setFromMatrixScale(matrix);
@@ -3902,7 +3923,7 @@ var init_SceneObject = __esm({
3902
3923
  });
3903
3924
 
3904
3925
  // src/entity/scene/EntityObject.ts
3905
- import { Color as Color3, Euler as Euler4, Matrix4 as Matrix45, Object3D as Object3D3 } from "three";
3926
+ import { Color as Color3, Euler as Euler5, Matrix4 as Matrix45, Object3D as Object3D3 } from "three";
3906
3927
  function isEntityObject(obj) {
3907
3928
  return obj.isEntityObject;
3908
3929
  }
@@ -3932,7 +3953,8 @@ var init_EntityObject = __esm({
3932
3953
  this.scrollMaterials = [];
3933
3954
  /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
3934
3955
  this.age = 0;
3935
- this.animationPlayer = new EntityAnimationPlayer();
3956
+ this.animationPlayers = [];
3957
+ this.partPoses = /* @__PURE__ */ new Map();
3936
3958
  this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
3937
3959
  this.addEventListener("added", () => this.updateScrollSubscription());
3938
3960
  this.addEventListener("removed", () => this.updateScrollSubscription());
@@ -3949,7 +3971,8 @@ var init_EntityObject = __esm({
3949
3971
  for (const geometry of this.geometries) geometry.dispose();
3950
3972
  this.geometries.clear();
3951
3973
  for (const dispose of this.disposeWireframes.splice(0)) dispose();
3952
- this.animationPlayer.clear();
3974
+ for (const player of this.animationPlayers.splice(0)) player.clear();
3975
+ this.partPoses.clear();
3953
3976
  super.disposeAndRemoveAllChildren();
3954
3977
  }
3955
3978
  clearScrollMaterials() {
@@ -3981,36 +4004,61 @@ var init_EntityObject = __esm({
3981
4004
  this.notifyDirty();
3982
4005
  }
3983
4006
  //<editor-fold desc="ANIMATION">
3984
- /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
4007
+ /** The first active clip, until playback is stopped or the object is disposed. */
3985
4008
  get animation() {
3986
- return this.animationPlayer.animation;
4009
+ return this.animationPlayers[0]?.animation;
4010
+ }
4011
+ /** Clips playing together, each targeting a separate geometry layer. */
4012
+ get activeAnimations() {
4013
+ return this.animationPlayers.map((player) => player.animation);
3987
4014
  }
3988
4015
  /** Seconds since the animation started, before looping. */
3989
4016
  get animationTime() {
3990
- return this.animationPlayer.time;
4017
+ return this.animationPlayers[0]?.time ?? 0;
3991
4018
  }
3992
4019
  /**
3993
- * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
3994
- * Parts of every layer are matched by name and their current pose is the default the offsets add to.
4020
+ * Plays a clip from {@link Entities.getAnimations}, replacing all active clips.
4021
+ * Offsets apply to the baked pose in the clip's layer (`main` by default), including repeated draws of that layer.
3995
4022
  * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
3996
4023
  */
3997
4024
  playAnimation(animation, options) {
4025
+ this.playAnimations([animation], options);
4026
+ }
4027
+ /** Plays one clip per selected geometry layer, with a shared clock and no blending between clips. */
4028
+ playAnimations(animations, options) {
4029
+ const targets = /* @__PURE__ */ new Set();
4030
+ const selections = animations.map((animation) => {
4031
+ const layer = animation.layer ?? "main";
4032
+ if (targets.has(layer)) throw new Error(`Multiple animations target layer "${layer}"`);
4033
+ targets.add(layer);
4034
+ const names = Object.keys(this.entityLayers).filter((name) => name.split("#")[0] === layer);
4035
+ if (!names.length) throw new Error(`Entity ${this.entity.id} has no selected animation layer "${layer}"`);
4036
+ return { animation, names };
4037
+ });
3998
4038
  this.createMeshes();
3999
- const layers = Object.keys(this.entityLayers).map((name) => this.getLayerGroup(name)).filter((layer) => !!layer);
4000
- this.animationPlayer.play(layers, animation, options);
4039
+ this.stopAnimation();
4040
+ for (const { animation, names } of selections) {
4041
+ const player = new EntityAnimationPlayer();
4042
+ player.play(names.map((name) => this.getLayerGroup(name)), animation, options, this.partPoses);
4043
+ this.animationPlayers.push(player);
4044
+ }
4001
4045
  this.notifyDirty();
4002
4046
  }
4003
- /** Stops the animation and restores the default pose. */
4047
+ /** Stops all clips and restores the poses from before playback. */
4004
4048
  stopAnimation() {
4005
- if (this.animationPlayer.stop()) this.notifyDirty();
4049
+ const players = this.animationPlayers.splice(0);
4050
+ for (const player of players) player.stop();
4051
+ if (players.length) this.notifyDirty();
4006
4052
  }
4007
4053
  /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
4008
4054
  setAnimationTime(seconds) {
4009
- if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
4055
+ for (const player of this.animationPlayers) player.setTime(seconds);
4056
+ if (this.animationPlayers.length) this.notifyDirty();
4010
4057
  }
4011
4058
  /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
4012
4059
  advanceAnimation(deltaSeconds) {
4013
- if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
4060
+ for (const player of this.animationPlayers) player.advance(deltaSeconds);
4061
+ if (this.animationPlayers.length) this.notifyDirty();
4014
4062
  }
4015
4063
  //</editor-fold>
4016
4064
  getLayerGroup(name) {
@@ -4049,7 +4097,7 @@ var init_EntityObject = __esm({
4049
4097
  const matrix = new Matrix45();
4050
4098
  if ("scale" in op) matrix.makeScale(...op.scale);
4051
4099
  else if ("translate" in op) matrix.makeTranslation(...op.translate);
4052
- else matrix.makeRotationFromEuler(new Euler4(...op.rotate, "ZYX"));
4100
+ else matrix.makeRotationFromEuler(new Euler5(...op.rotate, "ZYX"));
4053
4101
  modelRoot.matrix.multiply(matrix);
4054
4102
  }
4055
4103
  modelRoot.matrixAutoUpdate = false;
@@ -4070,6 +4118,7 @@ var init_EntityObject = __esm({
4070
4118
  anchor.position.fromArray(part.pose.offset);
4071
4119
  anchor.rotation.set(...part.pose.rotation, "ZYX");
4072
4120
  anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
4121
+ this.partPoses.set(anchor, part.pose);
4073
4122
  parent.add(anchor);
4074
4123
  const size = part.texture ?? textureSize;
4075
4124
  for (const cube of part.cubes) {
@@ -4146,7 +4195,7 @@ import {
4146
4195
  TriangleFanDrawMode,
4147
4196
  TriangleStripDrawMode,
4148
4197
  TrianglesDrawMode,
4149
- Vector3 as Vector39
4198
+ Vector3 as Vector310
4150
4199
  } from "three";
4151
4200
  function computeTangents(geometry) {
4152
4201
  geometry.computeTangents();
@@ -4465,15 +4514,15 @@ function computeMorphedAttributes(object) {
4465
4514
  console.error("THREE.BufferGeometryUtils: Geometry is not of type BufferGeometry.");
4466
4515
  return null;
4467
4516
  }
4468
- const _vA = new Vector39();
4469
- const _vB = new Vector39();
4470
- const _vC = new Vector39();
4471
- const _tempA = new Vector39();
4472
- const _tempB = new Vector39();
4473
- const _tempC = new Vector39();
4474
- const _morphA = new Vector39();
4475
- const _morphB = new Vector39();
4476
- const _morphC = new Vector39();
4517
+ const _vA = new Vector310();
4518
+ const _vB = new Vector310();
4519
+ const _vC = new Vector310();
4520
+ const _tempA = new Vector310();
4521
+ const _tempB = new Vector310();
4522
+ const _tempC = new Vector310();
4523
+ const _morphA = new Vector310();
4524
+ const _morphB = new Vector310();
4525
+ const _morphC = new Vector310();
4477
4526
  function _calculateMorphedAttributeData(object2, material2, attribute, morphAttribute, morphTargetsRelative2, a2, b2, c2, modifiedAttributeArray) {
4478
4527
  _vA.fromBufferAttribute(attribute, a2);
4479
4528
  _vB.fromBufferAttribute(attribute, b2);
@@ -4683,7 +4732,7 @@ var init_BufferGeometryUtils = __esm({
4683
4732
  });
4684
4733
 
4685
4734
  // src/model/ModelCulling.ts
4686
- import { Vector3 as Vector310 } from "three";
4735
+ import { Vector3 as Vector311 } from "three";
4687
4736
  var ModelCulling;
4688
4737
  var init_ModelCulling = __esm({
4689
4738
  "src/model/ModelCulling.ts"() {
@@ -4692,7 +4741,7 @@ var init_ModelCulling = __esm({
4692
4741
  static toLocalMask(worldMask, rotation) {
4693
4742
  let localMask = 0;
4694
4743
  for (const [localFace, offset] of CUBE_FACE_OFFSETS.entries()) {
4695
- const normal = new Vector310(...offset).applyEuler(rotation);
4744
+ const normal = new Vector311(...offset).applyEuler(rotation);
4696
4745
  const worldFace = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
4697
4746
  if (worldFace < 0) return 0;
4698
4747
  if (worldMask & 1 << worldFace) localMask |= 1 << localFace;
@@ -4837,8 +4886,89 @@ var init_GuiLight = __esm({
4837
4886
  }
4838
4887
  });
4839
4888
 
4889
+ // src/texture/Colormaps.ts
4890
+ var Colormaps;
4891
+ var init_Colormaps = __esm({
4892
+ "src/texture/Colormaps.ts"() {
4893
+ init_AssetKey();
4894
+ init_ModelTextures();
4895
+ init_Caching();
4896
+ init_MineRenderError();
4897
+ Colormaps = class {
4898
+ /** Samples the selected resource pack's grass colormap using Minecraft's climate coordinates. */
4899
+ static async grassColor(origin, temperature = 0.5, downfall = 1) {
4900
+ const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
4901
+ const temp = Math.fround(temperature);
4902
+ const rain = Math.fround(downfall) * temp;
4903
+ const x = Math.floor((1 - temp) * 255), y = Math.floor((1 - rain) * 255);
4904
+ return await Caching.blockTintCache.get(`${key.serialize()}|${x},${y}`, async () => {
4905
+ const image = await ModelTextures.get(key);
4906
+ if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
4907
+ if (image.width !== 256 || image.height !== 256) {
4908
+ throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
4909
+ }
4910
+ const [red, green, blue] = image.data.getImageData(x, y, 1, 1).data;
4911
+ return red << 16 | green << 8 | blue;
4912
+ });
4913
+ }
4914
+ };
4915
+ }
4916
+ });
4917
+
4918
+ // src/model/ItemTints.ts
4919
+ var ItemTints;
4920
+ var init_ItemTints = __esm({
4921
+ "src/model/ItemTints.ts"() {
4922
+ init_MineRenderError();
4923
+ init_Colormaps();
4924
+ ItemTints = class {
4925
+ /** Resolves preview colors from item definitions; explicit per-index colors take precedence. */
4926
+ static async get(model, tints) {
4927
+ const sources = model.tints;
4928
+ if (!sources?.length) return tints;
4929
+ const colors = { ...tints };
4930
+ await Promise.all(sources.map(async (source, index) => {
4931
+ if (colors[index] !== void 0) return;
4932
+ switch (source.type) {
4933
+ case "constant":
4934
+ case "minecraft:constant":
4935
+ colors[index] = this.rgb(source.value);
4936
+ break;
4937
+ case "grass":
4938
+ case "minecraft:grass":
4939
+ colors[index] = await Colormaps.grassColor(model.key, source.temperature, source.downfall);
4940
+ break;
4941
+ case "dye":
4942
+ case "minecraft:dye":
4943
+ case "potion":
4944
+ case "minecraft:potion":
4945
+ case "map_color":
4946
+ case "minecraft:map_color":
4947
+ case "firework":
4948
+ case "minecraft:firework":
4949
+ case "team":
4950
+ case "minecraft:team":
4951
+ case "custom_model_data":
4952
+ case "minecraft:custom_model_data":
4953
+ colors[index] = this.rgb(source.default);
4954
+ break;
4955
+ default:
4956
+ throw new MineRenderError(`Unsupported item tint source ${source.type}`);
4957
+ }
4958
+ }));
4959
+ return colors;
4960
+ }
4961
+ static rgb(color) {
4962
+ if (!Array.isArray(color)) return color & 16777215;
4963
+ const [red, green, blue] = color.map((channel) => Math.floor(Math.fround(Math.fround(channel) * 255)));
4964
+ return red << 16 | green << 8 | blue;
4965
+ }
4966
+ };
4967
+ }
4968
+ });
4969
+
4840
4970
  // src/model/scene/ModelObject.ts
4841
- import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler6, Matrix4 as Matrix49 } from "three";
4971
+ import { BoxGeometry as BoxGeometry5, BufferAttribute as BufferAttribute5, Color as Color8, Euler as Euler7, Matrix4 as Matrix49 } from "three";
4842
4972
  function isModelObject(obj) {
4843
4973
  return obj.isModelObject;
4844
4974
  }
@@ -4859,6 +4989,7 @@ var init_ModelObject = __esm({
4859
4989
  init_SpecialItems();
4860
4990
  init_EntityObject();
4861
4991
  init_GuiLight();
4992
+ init_ItemTints();
4862
4993
  p7 = prefix("ModelObject");
4863
4994
  _ModelObject = class _ModelObject extends SceneObject {
4864
4995
  constructor(originalModel, options) {
@@ -4874,6 +5005,7 @@ var init_ModelObject = __esm({
4874
5005
  this.addEventListener("removed", () => this.updateAnimationSubscription());
4875
5006
  }
4876
5007
  async init() {
5008
+ this.options.tints = await ItemTints.get(this.originalModel, this.options.tints);
4877
5009
  const special = this.originalModel.special;
4878
5010
  if (special) {
4879
5011
  const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
@@ -4940,7 +5072,7 @@ var init_ModelObject = __esm({
4940
5072
  elGeo.clearGroups();
4941
5073
  }
4942
5074
  if (this.options.uvLockRotation) {
4943
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler6(...this.options.uvLockRotation));
5075
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new Euler7(...this.options.uvLockRotation));
4944
5076
  }
4945
5077
  if (this.options.tints) {
4946
5078
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -5601,7 +5733,7 @@ import {
5601
5733
  Color as Color4,
5602
5734
  Matrix3,
5603
5735
  Vector2 as Vector22,
5604
- Vector3 as Vector36
5736
+ Vector3 as Vector37
5605
5737
  } from "three";
5606
5738
  var OBJExporter = class {
5607
5739
  parse(object) {
@@ -5609,9 +5741,9 @@ var OBJExporter = class {
5609
5741
  let indexVertex = 0;
5610
5742
  let indexVertexUvs = 0;
5611
5743
  let indexNormals = 0;
5612
- const vertex = new Vector36();
5744
+ const vertex = new Vector37();
5613
5745
  const color = new Color4();
5614
- const normal = new Vector36();
5746
+ const normal = new Vector37();
5615
5747
  const uv = new Vector22();
5616
5748
  const face = [];
5617
5749
  function parseMesh(mesh) {
@@ -5740,7 +5872,7 @@ var OBJExporter = class {
5740
5872
  // ../../node_modules/three/examples/jsm/exporters/PLYExporter.js
5741
5873
  import {
5742
5874
  Matrix3 as Matrix32,
5743
- Vector3 as Vector37,
5875
+ Vector3 as Vector38,
5744
5876
  Color as Color5
5745
5877
  } from "three";
5746
5878
  var PLYExporter = class {
@@ -5833,7 +5965,7 @@ property list uchar int vertex_index
5833
5965
  `;
5834
5966
  }
5835
5967
  header += "end_header\n";
5836
- const vertex = new Vector37();
5968
+ const vertex = new Vector38();
5837
5969
  const normalMatrixWorld = new Matrix32();
5838
5970
  let result = null;
5839
5971
  if (options.binary === true) {
@@ -6032,7 +6164,7 @@ import {
6032
6164
  Source,
6033
6165
  SRGBColorSpace as SRGBColorSpace4,
6034
6166
  CompressedTexture,
6035
- Vector3 as Vector38,
6167
+ Vector3 as Vector39,
6036
6168
  Quaternion as Quaternion4
6037
6169
  } from "three";
6038
6170
 
@@ -6493,7 +6625,7 @@ var GLTFWriter = class {
6493
6625
  isNormalizedNormalAttribute(normal) {
6494
6626
  const cache = this.cache;
6495
6627
  if (cache.attributesNormalized.has(normal)) return false;
6496
- const v = new Vector38();
6628
+ const v = new Vector39();
6497
6629
  for (let i = 0, il = normal.count; i < il; i++) {
6498
6630
  if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4) return false;
6499
6631
  }
@@ -6510,7 +6642,7 @@ var GLTFWriter = class {
6510
6642
  const cache = this.cache;
6511
6643
  if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
6512
6644
  const attribute = normal.clone();
6513
- const v = new Vector38();
6645
+ const v = new Vector39();
6514
6646
  for (let i = 0, il = attribute.count; i < il; i++) {
6515
6647
  v.fromBufferAttribute(attribute, i);
6516
6648
  if (v.x === 0 && v.y === 0 && v.z === 0) {
@@ -7777,9 +7909,9 @@ var GLTFMeshGpuInstancing = class {
7777
7909
  const rotationAttr = new Float32Array(mesh.count * 4);
7778
7910
  const scaleAttr = new Float32Array(mesh.count * 3);
7779
7911
  const matrix = new Matrix46();
7780
- const position = new Vector38();
7912
+ const position = new Vector39();
7781
7913
  const quaternion = new Quaternion4();
7782
- const scale = new Vector38();
7914
+ const scale = new Vector39();
7783
7915
  for (let i = 0; i < mesh.count; i++) {
7784
7916
  mesh.getMatrixAt(i, matrix);
7785
7917
  matrix.decompose(position, quaternion, scale);
@@ -8761,6 +8893,7 @@ function isInstanceable(obj) {
8761
8893
  init_DisplayPosition();
8762
8894
  init_DisplayTransforms();
8763
8895
  init_GuiLight();
8896
+ init_ItemTints();
8764
8897
  init_Model();
8765
8898
  init_ModelCulling();
8766
8899
  init_ModelGenerator();
@@ -8771,7 +8904,7 @@ init_SpecialItems();
8771
8904
  init_BlockStates();
8772
8905
  init_MineRenderError();
8773
8906
  init_util();
8774
- import { Euler as Euler7 } from "three";
8907
+ import { Euler as Euler8 } from "three";
8775
8908
  function matchesCondition(condition, state) {
8776
8909
  return Object.entries(condition).every(([key, value]) => {
8777
8910
  if (Array.isArray(value)) {
@@ -8846,7 +8979,7 @@ var BlockStateResolver = class {
8846
8979
  return variants[variants.length - 1];
8847
8980
  }
8848
8981
  static rotation(variant) {
8849
- const rotation = new Euler7();
8982
+ const rotation = new Euler8();
8850
8983
  if (typeof variant.x !== "undefined") {
8851
8984
  rotation.x = toRadians(clampRotationDegrees(variant.x));
8852
8985
  }
@@ -8858,10 +8991,7 @@ var BlockStateResolver = class {
8858
8991
  };
8859
8992
 
8860
8993
  // src/model/block/BlockTints.ts
8861
- init_AssetKey();
8862
- init_ModelTextures();
8863
- init_Caching();
8864
- init_MineRenderError();
8994
+ init_Colormaps();
8865
8995
 
8866
8996
  // src/model/block/blockTints.json
8867
8997
  var blockTints_default = {
@@ -8916,7 +9046,7 @@ var BlockTints = class {
8916
9046
  color = rule.color;
8917
9047
  break;
8918
9048
  case "grass":
8919
- color = await this.grassColor(key);
9049
+ color = await Colormaps.grassColor(key);
8920
9050
  break;
8921
9051
  case "redstone": {
8922
9052
  const power = Number(state.power ?? 0) / 15;
@@ -8934,18 +9064,6 @@ var BlockTints = class {
8934
9064
  }
8935
9065
  return { ...Object.fromEntries([...indices].map((index) => [index, color])), ...tints };
8936
9066
  }
8937
- static async grassColor(origin) {
8938
- const key = AssetKey.parse("textures", "minecraft:colormap/grass", origin);
8939
- return await Caching.blockTintCache.get(key.serialize(), async () => {
8940
- const image = await ModelTextures.get(key);
8941
- if (!image) throw new MineRenderError(`Missing grass colormap: ${key.toNamespacedString()}`);
8942
- if (image.width !== 256 || image.height !== 256) {
8943
- throw new MineRenderError("Grass colormaps must be 256 \xD7 256 pixels");
8944
- }
8945
- const [red, green, blue] = image.data.getImageData(127, 127, 1, 1).data;
8946
- return red << 16 | green << 8 | blue;
8947
- });
8948
- }
8949
9067
  };
8950
9068
 
8951
9069
  // src/model/block/scene/BlockObject.ts
@@ -8956,7 +9074,7 @@ var import_ts_deepmerge6 = __toESM(require_dist());
8956
9074
  init_MineRenderError();
8957
9075
  init_InstanceReference();
8958
9076
  init_AssetKey();
8959
- import { Euler as Euler8, Matrix4 as Matrix411, Quaternion as Quaternion5, Vector3 as Vector311 } from "three";
9077
+ import { Euler as Euler9, Matrix4 as Matrix411, Quaternion as Quaternion5, Vector3 as Vector312 } from "three";
8960
9078
  init_ModelCulling();
8961
9079
  init_FluidGeometry();
8962
9080
  init_Entities();
@@ -9074,12 +9192,12 @@ var _BlockObject = class _BlockObject extends SceneObject {
9074
9192
  getModelCullMask(model, worldMask) {
9075
9193
  const object = isInstanceReference(model) ? model.instanceable : model;
9076
9194
  if (object.options.displayPosition) return 0;
9077
- const position = new Vector311();
9195
+ const position = new Vector312();
9078
9196
  const rotation = new Quaternion5();
9079
- const scale = new Vector311();
9197
+ const scale = new Vector312();
9080
9198
  this.getModelMatrix(model).decompose(position, rotation, scale);
9081
- if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector311(1, 1, 1)) > 1e-10) return 0;
9082
- return ModelCulling.toLocalMask(worldMask, new Euler8().setFromQuaternion(rotation));
9199
+ if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new Vector312(1, 1, 1)) > 1e-10) return 0;
9200
+ return ModelCulling.toLocalMask(worldMask, new Euler9().setFromQuaternion(rotation));
9083
9201
  }
9084
9202
  async setCullMask(worldMask) {
9085
9203
  worldMask &= 63;
@@ -12200,6 +12318,7 @@ var SkinObject = class extends SceneObject {
12200
12318
 
12201
12319
  // src/renderer/MineRenderScene.ts
12202
12320
  init_EntityObject();
12321
+ init_ItemTints();
12203
12322
  var _MineRenderScene = class _MineRenderScene extends Scene5 {
12204
12323
  constructor(options) {
12205
12324
  super();
@@ -12292,6 +12411,7 @@ var _MineRenderScene = class _MineRenderScene extends Scene5 {
12292
12411
  }
12293
12412
  }
12294
12413
  async addModel(model, options, parent = this) {
12414
+ options = { ...options, tints: await ItemTints.get(model, options?.tints) };
12295
12415
  return this.addSceneObject(model, () => new ModelObject(model, options), options, parent);
12296
12416
  }
12297
12417
  async addBlock(blockState, options, parent = this) {
@@ -12327,7 +12447,7 @@ function isMineRenderScene(obj) {
12327
12447
  }
12328
12448
 
12329
12449
  // src/renderer/Renderer.ts
12330
- import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera as PerspectiveCamera2, SRGBColorSpace as SRGBColorSpace6, Vector3 as Vector313, WebGLRenderer as WebGLRenderer2 } from "three";
12450
+ import { AxesHelper as AxesHelper2, GridHelper, OrthographicCamera, PCFSoftShadowMap, PerspectiveCamera as PerspectiveCamera2, SRGBColorSpace as SRGBColorSpace6, Vector3 as Vector314, WebGLRenderer as WebGLRenderer2 } from "three";
12331
12451
  var import_ts_deepmerge9 = __toESM(require_dist());
12332
12452
  init_util();
12333
12453
  init_Model();
@@ -12343,7 +12463,7 @@ import {
12343
12463
  Spherical,
12344
12464
  TOUCH,
12345
12465
  Vector2 as Vector25,
12346
- Vector3 as Vector312
12466
+ Vector3 as Vector313
12347
12467
  } from "three";
12348
12468
  var _changeEvent = { type: "change" };
12349
12469
  var _startEvent = { type: "start" };
@@ -12357,7 +12477,7 @@ var OrbitControls = class extends EventDispatcher {
12357
12477
  this.domElement = domElement;
12358
12478
  this.domElement.style.touchAction = "none";
12359
12479
  this.enabled = true;
12360
- this.target = new Vector312();
12480
+ this.target = new Vector313();
12361
12481
  this.minDistance = 0;
12362
12482
  this.maxDistance = Infinity;
12363
12483
  this.minZoom = 0;
@@ -12409,10 +12529,10 @@ var OrbitControls = class extends EventDispatcher {
12409
12529
  state = STATE.NONE;
12410
12530
  };
12411
12531
  this.update = function() {
12412
- const offset = new Vector312();
12413
- const quat = new Quaternion6().setFromUnitVectors(object.up, new Vector312(0, 1, 0));
12532
+ const offset = new Vector313();
12533
+ const quat = new Quaternion6().setFromUnitVectors(object.up, new Vector313(0, 1, 0));
12414
12534
  const quatInverse = quat.clone().invert();
12415
- const lastPosition = new Vector312();
12535
+ const lastPosition = new Vector313();
12416
12536
  const lastQuaternion = new Quaternion6();
12417
12537
  const twoPI = 2 * Math.PI;
12418
12538
  return function update() {
@@ -12502,7 +12622,7 @@ var OrbitControls = class extends EventDispatcher {
12502
12622
  const spherical = new Spherical();
12503
12623
  const sphericalDelta = new Spherical();
12504
12624
  let scale = 1;
12505
- const panOffset = new Vector312();
12625
+ const panOffset = new Vector313();
12506
12626
  let zoomChanged = false;
12507
12627
  const rotateStart = new Vector25();
12508
12628
  const rotateEnd = new Vector25();
@@ -12528,7 +12648,7 @@ var OrbitControls = class extends EventDispatcher {
12528
12648
  sphericalDelta.phi -= angle;
12529
12649
  }
12530
12650
  const panLeft = function() {
12531
- const v = new Vector312();
12651
+ const v = new Vector313();
12532
12652
  return function panLeft2(distance, objectMatrix) {
12533
12653
  v.setFromMatrixColumn(objectMatrix, 0);
12534
12654
  v.multiplyScalar(-distance);
@@ -12536,7 +12656,7 @@ var OrbitControls = class extends EventDispatcher {
12536
12656
  };
12537
12657
  }();
12538
12658
  const panUp = function() {
12539
- const v = new Vector312();
12659
+ const v = new Vector313();
12540
12660
  return function panUp2(distance, objectMatrix) {
12541
12661
  if (scope.screenSpacePanning === true) {
12542
12662
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -12549,7 +12669,7 @@ var OrbitControls = class extends EventDispatcher {
12549
12669
  };
12550
12670
  }();
12551
12671
  const pan = function() {
12552
- const offset = new Vector312();
12672
+ const offset = new Vector313();
12553
12673
  return function pan2(deltaX, deltaY) {
12554
12674
  const element = scope.domElement;
12555
12675
  if (scope.object.isPerspectiveCamera) {
@@ -13366,8 +13486,8 @@ _Renderer.DEFAULT_OPTIONS = (0, import_ts_deepmerge9.default)({}, {
13366
13486
  top: void 0,
13367
13487
  bottom: void 0
13368
13488
  },
13369
- position: new Vector313(50, 50, 50),
13370
- lookingAt: new Vector313(0, 0, 0)
13489
+ position: new Vector314(50, 50, 50),
13490
+ lookingAt: new Vector314(0, 0, 0)
13371
13491
  },
13372
13492
  render: {
13373
13493
  fpsLimit: 60,
@@ -13563,6 +13683,7 @@ var Skins = class {
13563
13683
  };
13564
13684
 
13565
13685
  // src/texture/index.ts
13686
+ init_Colormaps();
13566
13687
  init_TextureAtlas();
13567
13688
  init_TextureLoader();
13568
13689
  init_Textures();
@@ -13831,13 +13952,13 @@ var AnvilParser = class {
13831
13952
  };
13832
13953
 
13833
13954
  // src/world/Chunk.ts
13834
- import { Vector3 as Vector316 } from "three";
13955
+ import { Vector3 as Vector317 } from "three";
13835
13956
  init_BlockStates();
13836
13957
  init_AssetKey();
13837
13958
 
13838
13959
  // src/world/MineRenderWorld.ts
13839
13960
  init_Model();
13840
- import { Vector3 as Vector315 } from "three";
13961
+ import { Vector3 as Vector316 } from "three";
13841
13962
  init_BatchedExecutor();
13842
13963
  init_AssetKey();
13843
13964
  init_BlockStates();
@@ -13847,7 +13968,7 @@ init_CubeFace();
13847
13968
  init_AssetKey();
13848
13969
  init_Models();
13849
13970
  init_CubeFace();
13850
- import { Matrix4 as Matrix412, Vector3 as Vector314 } from "three";
13971
+ import { Matrix4 as Matrix412, Vector3 as Vector315 } from "three";
13851
13972
  init_ModelCulling();
13852
13973
  init_ModelObject();
13853
13974
  init_UVMapper();
@@ -13915,7 +14036,7 @@ var SectionModels = class {
13915
14036
  const cullFaces = CUBE_FACES.map((face) => {
13916
14037
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
13917
14038
  if (local < 0) return 0;
13918
- const normal = new Vector314(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
14039
+ const normal = new Vector315(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
13919
14040
  const world = CUBE_FACE_OFFSETS.findIndex(([x, y, z]) => Math.abs(normal.x - x) < 1e-6 && Math.abs(normal.y - y) < 1e-6 && Math.abs(normal.z - z) < 1e-6);
13920
14041
  return 1 << world;
13921
14042
  });
@@ -13945,20 +14066,20 @@ var MineRenderWorld = class {
13945
14066
  }
13946
14067
  getBlockAt(posOrX, y, z) {
13947
14068
  if (typeof posOrX == "number") {
13948
- return this.getBlockAt(new Vector315(posOrX, y, z));
14069
+ return this.getBlockAt(new Vector316(posOrX, y, z));
13949
14070
  }
13950
14071
  if (isTripleArray(posOrX)) {
13951
- return this.getBlockAt(new Vector315(posOrX[0], posOrX[1], posOrX[2]));
14072
+ return this.getBlockAt(new Vector316(posOrX[0], posOrX[1], posOrX[2]));
13952
14073
  }
13953
14074
  this.validatePosBounds(posOrX);
13954
14075
  return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
13955
14076
  }
13956
14077
  async setBlockAt(posOrX, yOrBlock, z, block) {
13957
14078
  if (typeof posOrX == "number") {
13958
- return this.setBlockAt(new Vector315(posOrX, yOrBlock, z), block);
14079
+ return this.setBlockAt(new Vector316(posOrX, yOrBlock, z), block);
13959
14080
  }
13960
14081
  if (isTripleArray(posOrX)) {
13961
- return this.setBlockAt(new Vector315(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14082
+ return this.setBlockAt(new Vector316(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
13962
14083
  }
13963
14084
  return this.placeBlock(posOrX, yOrBlock);
13964
14085
  }
@@ -13979,7 +14100,7 @@ var MineRenderWorld = class {
13979
14100
  const collect = async (positions2) => {
13980
14101
  for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
13981
14102
  };
13982
- const place = (block) => this.placeBlock(new Vector315(...block.position), block, collect);
14103
+ const place = (block) => this.placeBlock(new Vector316(...block.position), block, collect);
13983
14104
  const keys = /* @__PURE__ */ new Map();
13984
14105
  for (const block of multiblock.blocks) {
13985
14106
  if (Chunk.isAir(block)) continue;
@@ -14057,13 +14178,13 @@ var MineRenderWorld = class {
14057
14178
  for (const pos of positions) {
14058
14179
  this.pendingCulling.set(pos.toArray().join(","), pos.clone());
14059
14180
  for (const offset of CUBE_FACE_OFFSETS) {
14060
- const neighbor = pos.clone().add(new Vector315(...offset));
14181
+ const neighbor = pos.clone().add(new Vector316(...offset));
14061
14182
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14062
14183
  }
14063
14184
  for (let y = -1; y <= 1; y++) {
14064
14185
  for (let z = -1; z <= 1; z++) {
14065
14186
  for (let x = -1; x <= 1; x++) {
14066
- const neighbor = pos.clone().add(new Vector315(x, y, z));
14187
+ const neighbor = pos.clone().add(new Vector316(x, y, z));
14067
14188
  if (this.getBlockAt(neighbor)?.object?.fluidKind) {
14068
14189
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14069
14190
  }
@@ -14085,7 +14206,7 @@ var MineRenderWorld = class {
14085
14206
  if (!block) continue;
14086
14207
  if (block.object?.fluidKind) {
14087
14208
  await block.object.updateFluid((x, y, z) => {
14088
- const neighbor = pos.clone().add(new Vector315(x, y, z));
14209
+ const neighbor = pos.clone().add(new Vector316(x, y, z));
14089
14210
  const section = this.getChunkAt(neighbor);
14090
14211
  const object = section?.getBlockAt(neighbor)?.object;
14091
14212
  return {
@@ -14097,7 +14218,7 @@ var MineRenderWorld = class {
14097
14218
  }
14098
14219
  let mask = 0;
14099
14220
  for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
14100
- const neighbor = pos.clone().add(new Vector315(...offset));
14221
+ const neighbor = pos.clone().add(new Vector316(...offset));
14101
14222
  if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
14102
14223
  mask |= 1 << face;
14103
14224
  }
@@ -14131,14 +14252,14 @@ var MineRenderWorld = class {
14131
14252
  return this._chunks.get(this.worldPosToChunkKey(pos));
14132
14253
  }
14133
14254
  static worldToScenePosition(pos) {
14134
- return new Vector315(
14255
+ return new Vector316(
14135
14256
  pos.x * 16,
14136
14257
  pos.y * 16,
14137
14258
  pos.z * 16
14138
14259
  );
14139
14260
  }
14140
14261
  static sceneToWorldPosition(pos) {
14141
- return new Vector315(
14262
+ return new Vector316(
14142
14263
  pos.x / 16,
14143
14264
  pos.y / 16,
14144
14265
  pos.z / 16
@@ -14282,10 +14403,10 @@ var Chunk = class _Chunk {
14282
14403
  }
14283
14404
  getBlockAt(posOrX, y, z) {
14284
14405
  if (typeof posOrX == "number") {
14285
- return this.getBlockAt(new Vector316(posOrX, y, z));
14406
+ return this.getBlockAt(new Vector317(posOrX, y, z));
14286
14407
  }
14287
14408
  if (isTripleArray(posOrX)) {
14288
- return this.getBlockAt(new Vector316(posOrX[0], posOrX[1], posOrX[2]));
14409
+ return this.getBlockAt(new Vector317(posOrX[0], posOrX[1], posOrX[2]));
14289
14410
  }
14290
14411
  const pos = this.worldPosToChunkPos(posOrX);
14291
14412
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -14293,10 +14414,10 @@ var Chunk = class _Chunk {
14293
14414
  }
14294
14415
  async setBlockAt(posOrX, yOrBlock, z, block) {
14295
14416
  if (typeof posOrX == "number") {
14296
- return this.setBlockAt(new Vector316(posOrX, yOrBlock, z), block);
14417
+ return this.setBlockAt(new Vector317(posOrX, yOrBlock, z), block);
14297
14418
  }
14298
14419
  if (isTripleArray(posOrX)) {
14299
- return this.setBlockAt(new Vector316(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14420
+ return this.setBlockAt(new Vector317(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14300
14421
  }
14301
14422
  const worldPos = posOrX;
14302
14423
  const pos = this.worldPosToChunkPos(worldPos);
@@ -14382,7 +14503,7 @@ var Chunk = class _Chunk {
14382
14503
  }
14383
14504
  async clear(onBlocksChanged = this.onBlocksChanged) {
14384
14505
  const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
14385
- new Vector316(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
14506
+ new Vector317(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
14386
14507
  ));
14387
14508
  for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
14388
14509
  this.sectionBlocks.clear();
@@ -14406,14 +14527,14 @@ var Chunk = class _Chunk {
14406
14527
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
14407
14528
  }
14408
14529
  worldPosToChunkPos(pos) {
14409
- return new Vector316(
14530
+ return new Vector317(
14410
14531
  pos.x - this.x * 16,
14411
14532
  pos.y - this.y * 16,
14412
14533
  pos.z - this.z * 16
14413
14534
  );
14414
14535
  }
14415
14536
  chunkPosToWorldPos(pos) {
14416
- return new Vector316(
14537
+ return new Vector317(
14417
14538
  this.x * 16 + pos.x,
14418
14539
  this.y * 16 + pos.y,
14419
14540
  this.z * 16 + pos.z
@@ -14449,6 +14570,7 @@ export {
14449
14570
  CanvasImage,
14450
14571
  Chunk,
14451
14572
  ChunkData,
14573
+ Colormaps,
14452
14574
  CubeFace,
14453
14575
  CubeFaceIndex,
14454
14576
  DEFAULT_ELEMENTS,
@@ -14474,6 +14596,7 @@ export {
14474
14596
  ImageLoader,
14475
14597
  InstanceManager,
14476
14598
  InstanceReference,
14599
+ ItemTints,
14477
14600
  MapControls,
14478
14601
  Materials,
14479
14602
  Meshes,