minerender 2.1.0-alpha.59 → 2.1.0-alpha.60

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.
@@ -1134,6 +1134,26 @@ var init_Materials = __esm({
1134
1134
  }
1135
1135
  });
1136
1136
 
1137
+ // src/model/Model.ts
1138
+ function isDoubleArray(obj) {
1139
+ return Array.isArray(obj) && obj.length === 2;
1140
+ }
1141
+ function isTripleArray(obj) {
1142
+ return Array.isArray(obj) && obj.length === 3;
1143
+ }
1144
+ function isQuadArray(obj) {
1145
+ return Array.isArray(obj) && obj.length === 4;
1146
+ }
1147
+ var ITEM_GENERATED, BUILTIN_GENERATED, BUILTIN_ENTITY, DEFAULT_ELEMENTS;
1148
+ var init_Model = __esm({
1149
+ "src/model/Model.ts"() {
1150
+ ITEM_GENERATED = "item/generated";
1151
+ BUILTIN_GENERATED = "builtin/generated";
1152
+ BUILTIN_ENTITY = "builtin/entity";
1153
+ DEFAULT_ELEMENTS = [];
1154
+ }
1155
+ });
1156
+
1137
1157
  // ../../node_modules/ts-deepmerge/dist/index.js
1138
1158
  var require_dist = __commonJS({
1139
1159
  "../../node_modules/ts-deepmerge/dist/index.js"(exports2) {
@@ -1392,6 +1412,7 @@ var init_DisplayTransforms = __esm({
1392
1412
  var import_ts_deepmerge, ModelMerger;
1393
1413
  var init_ModelMerger = __esm({
1394
1414
  "src/model/ModelMerger.ts"() {
1415
+ init_Model();
1395
1416
  init_Models();
1396
1417
  import_ts_deepmerge = __toESM(require_dist());
1397
1418
  init_AssetKey();
@@ -1417,6 +1438,7 @@ var init_ModelMerger = __esm({
1417
1438
  }
1418
1439
  const models = [];
1419
1440
  const parentKey = AssetKey.parse("models", model.parent);
1441
+ if (parentKey.namespace === "minecraft" && parentKey.getFullPath() === BUILTIN_ENTITY) return models;
1420
1442
  parentKey.root = model.key?.root;
1421
1443
  const parentModel = await Models.getRaw(parentKey);
1422
1444
  if (parentModel) {
@@ -1483,12 +1505,12 @@ var init_Models = __esm({
1483
1505
  const result = await AssetLoader.getFirst([itemKey, key], "json" /* JSON */);
1484
1506
  if (!result) return void 0;
1485
1507
  if (result.key.assetType !== "items") return { ...result.asset, key };
1486
- const reference = this.defaultItemModel(result.asset.model, key);
1487
- const modelKey = AssetKey.parse("models", reference);
1508
+ const selected = this.defaultItemModel(result.asset.model, key);
1509
+ const modelKey = AssetKey.parse("models", selected.model);
1488
1510
  modelKey.root = key.root;
1489
1511
  const model2 = await this.getRaw(modelKey);
1490
- if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${reference}`);
1491
- return model2;
1512
+ if (!model2) throw new Error(`Item ${key.toNamespacedString()} references missing model ${selected.model}`);
1513
+ return selected.special ? { ...model2, special: selected.special } : model2;
1492
1514
  });
1493
1515
  return model ? { ...model, key: Object.assign(new AssetKey("", ""), model.key) } : void 0;
1494
1516
  }
@@ -1499,8 +1521,25 @@ var init_Models = __esm({
1499
1521
  }
1500
1522
  switch (node.type.replace(/^minecraft:/, "")) {
1501
1523
  case "model":
1502
- if (typeof node.model === "string" && node.model) return node.model;
1524
+ if (typeof node.model === "string" && node.model) return { model: node.model };
1503
1525
  break;
1526
+ case "special": {
1527
+ if (!node.base || !node.model || typeof node.model !== "object") break;
1528
+ const special = node.model;
1529
+ switch (special.type) {
1530
+ case "chest":
1531
+ case "minecraft:chest":
1532
+ case "bed":
1533
+ case "minecraft:bed":
1534
+ if (typeof special.texture === "string" && special.texture) return { model: node.base, special };
1535
+ break;
1536
+ case "head":
1537
+ case "minecraft:head":
1538
+ if (typeof special.kind === "string" && special.kind) return { model: node.base, special };
1539
+ break;
1540
+ }
1541
+ throw new Error(`Unsupported special item renderer ${special.type} for ${key.toNamespacedString()}`);
1542
+ }
1504
1543
  case "condition":
1505
1544
  return this.defaultItemModel(node.on_false, key);
1506
1545
  case "select": {
@@ -3100,6 +3139,102 @@ var init_UVMapper = __esm({
3100
3139
  }
3101
3140
  });
3102
3141
 
3142
+ // src/MinecraftCubeTexture.ts
3143
+ var MinecraftCubeTexture;
3144
+ var init_MinecraftCubeTexture = __esm({
3145
+ "src/MinecraftCubeTexture.ts"() {
3146
+ init_UVMapper();
3147
+ init_CubeFace();
3148
+ MinecraftCubeTexture = class {
3149
+ constructor(u, v, width, height) {
3150
+ this.u = u;
3151
+ this.v = v;
3152
+ this.width = width;
3153
+ this.height = height;
3154
+ }
3155
+ mapW(x) {
3156
+ return x / this.width;
3157
+ }
3158
+ mapH(x) {
3159
+ return 1 - x / this.height;
3160
+ }
3161
+ getUvEast(w, h, l) {
3162
+ return [
3163
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
3164
+ [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
3165
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
3166
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)]
3167
+ ];
3168
+ }
3169
+ getUvWest(w, h, l) {
3170
+ return [
3171
+ [this.mapW(this.u + l), this.mapH(this.v + l + h)],
3172
+ [this.mapW(this.u), this.mapH(this.v + l + h)],
3173
+ [this.mapW(this.u + l), this.mapH(this.v + l)],
3174
+ [this.mapW(this.u), this.mapH(this.v + l)]
3175
+ ];
3176
+ }
3177
+ getUvUp(w, h, l) {
3178
+ return [
3179
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)],
3180
+ [this.mapW(this.u + l + w + w), this.mapH(this.v + l)],
3181
+ [this.mapW(this.u + l + w), this.mapH(this.v)],
3182
+ [this.mapW(this.u + l + w + w), this.mapH(this.v)]
3183
+ ];
3184
+ }
3185
+ getUvDown(w, h, l) {
3186
+ return [
3187
+ [this.mapW(this.u + l), this.mapH(this.v)],
3188
+ [this.mapW(this.u + l + w), this.mapH(this.v)],
3189
+ [this.mapW(this.u + l), this.mapH(this.v + l)],
3190
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)]
3191
+ ];
3192
+ }
3193
+ getUvSouth(w, h, l) {
3194
+ return [
3195
+ [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l + h)],
3196
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
3197
+ [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
3198
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
3199
+ ];
3200
+ }
3201
+ getUvNorth(w, h, l) {
3202
+ return [
3203
+ [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
3204
+ [this.mapW(this.u + l), this.mapH(this.v + l + h)],
3205
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)],
3206
+ [this.mapW(this.u + l), this.mapH(this.v + l)]
3207
+ ];
3208
+ }
3209
+ getFaceUv(face, w, h, l) {
3210
+ switch (face) {
3211
+ case "east" /* EAST */:
3212
+ return this.getUvEast(w, h, l);
3213
+ case "west" /* WEST */:
3214
+ return this.getUvWest(w, h, l);
3215
+ case "up" /* UP */:
3216
+ return this.getUvUp(w, h, l);
3217
+ case "down" /* DOWN */:
3218
+ return this.getUvDown(w, h, l);
3219
+ case "south" /* SOUTH */:
3220
+ return this.getUvSouth(w, h, l);
3221
+ case "north" /* NORTH */:
3222
+ return this.getUvNorth(w, h, l);
3223
+ }
3224
+ }
3225
+ toUvArray(w, h, l, mirror = false) {
3226
+ const uv = [];
3227
+ for (let i = 0; i < CUBE_FACES.length; i++) {
3228
+ const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
3229
+ const corners = this.getFaceUv(face, w, h, l);
3230
+ UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
3231
+ }
3232
+ return uv;
3233
+ }
3234
+ };
3235
+ }
3236
+ });
3237
+
3103
3238
  // src/error/MineRenderError.ts
3104
3239
  var MineRenderError;
3105
3240
  var init_MineRenderError = __esm({
@@ -3116,6 +3251,248 @@ var init_MineRenderError = __esm({
3116
3251
  }
3117
3252
  });
3118
3253
 
3254
+ // src/assets/Entities.ts
3255
+ var Entities;
3256
+ var init_Entities = __esm({
3257
+ "src/assets/Entities.ts"() {
3258
+ init_AssetKey();
3259
+ init_AssetLoader();
3260
+ init_source();
3261
+ init_Caching();
3262
+ init_Assets();
3263
+ init_MineRenderError();
3264
+ init_ModelTextures();
3265
+ Entities = class {
3266
+ static async getEntityList() {
3267
+ const collect = async (path) => {
3268
+ const prefix2 = path ? `${path}/` : "";
3269
+ const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
3270
+ const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
3271
+ if (!list) return [];
3272
+ const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
3273
+ const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
3274
+ return [...files, ...children.flat()];
3275
+ };
3276
+ return collect("");
3277
+ }
3278
+ static async getModelFile(modelKey) {
3279
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
3280
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", isAssetKey(modelKey) ? modelKey.root : void 0);
3281
+ return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
3282
+ }
3283
+ static async getLayerList(modelKey) {
3284
+ return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
3285
+ }
3286
+ /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
3287
+ static async getPassList(modelKey) {
3288
+ return (await this.getModelFile(modelKey))?.passes ?? [];
3289
+ }
3290
+ static async getEntity(modelKey, textureKey, options) {
3291
+ const model = await this.getModelFile(modelKey);
3292
+ if (!model) return void 0;
3293
+ const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
3294
+ const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
3295
+ if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
3296
+ draws.push(...passes);
3297
+ const names = [];
3298
+ const selected = draws.map((pass) => {
3299
+ const layer = model.layers[pass.layer];
3300
+ if (!layer) {
3301
+ throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
3302
+ }
3303
+ let name = pass.layer;
3304
+ for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
3305
+ names.push(name);
3306
+ return { name, layer, pass };
3307
+ });
3308
+ const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
3309
+ const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
3310
+ const textureLocation = pass.textureLocation ?? layer.textureLocation;
3311
+ let texture;
3312
+ if (override) {
3313
+ const path = isAssetKey(override) ? override.getFullPath() : override.path;
3314
+ texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
3315
+ } else if (textureLocation !== void 0) {
3316
+ texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
3317
+ if (isAssetKey(modelKey)) texture.root = modelKey.root;
3318
+ } else {
3319
+ texture = await this.resolveTexture(modelKey);
3320
+ }
3321
+ const render = pass.render ?? layer.render;
3322
+ return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
3323
+ })));
3324
+ return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
3325
+ }
3326
+ /**
3327
+ * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
3328
+ */
3329
+ static async getAnimations(modelKey) {
3330
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
3331
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
3332
+ const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
3333
+ return file?.animations;
3334
+ }
3335
+ static async resolveTexture(modelKey) {
3336
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
3337
+ const root = isAssetKey(modelKey) ? modelKey.root : void 0;
3338
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json", root);
3339
+ return Caching.entityTextureCache.get(key.serialize(), async () => {
3340
+ const name = path.split("/").pop();
3341
+ for (const candidate of [path, `${path}/${name}`]) {
3342
+ const texture2 = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png", root);
3343
+ if (await ModelTextures.get(texture2)) return texture2;
3344
+ }
3345
+ const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json", root);
3346
+ const list = await AssetLoader.get(listKey, "list" /* LIST */);
3347
+ const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
3348
+ const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
3349
+ if (!file) return void 0;
3350
+ const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json", root);
3351
+ const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
3352
+ const assets = variant?.assets;
3353
+ const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
3354
+ if (typeof textureId !== "string") return void 0;
3355
+ const texture = AssetKey.parse("textures", textureId);
3356
+ texture.root = root;
3357
+ return texture;
3358
+ });
3359
+ }
3360
+ /** @deprecated Use getEntityList(); block entities share the entity dataset. */
3361
+ static getBlockList() {
3362
+ return this.getEntityList();
3363
+ }
3364
+ /** @deprecated Use getEntity(); block entities share the entity dataset. */
3365
+ static getBlock(modelKey, textureKey, options) {
3366
+ return this.getEntity(modelKey, textureKey, options);
3367
+ }
3368
+ };
3369
+ }
3370
+ });
3371
+
3372
+ // src/entity/EntityAnimation.ts
3373
+ function catmullRom(delta, p0, p1, p22, p32) {
3374
+ return 0.5 * (2 * p1 + (p22 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p22 - p32) * delta * delta + (3 * p1 - p0 - 3 * p22 + p32) * delta * delta * delta);
3375
+ }
3376
+ function sampleEntityKeyframes(keyframes, time) {
3377
+ if (keyframes.length === 0) return [0, 0, 0];
3378
+ let low = 0, high = keyframes.length;
3379
+ while (low < high) {
3380
+ const middle = low + high >>> 1;
3381
+ if (time <= keyframes[middle].time) high = middle;
3382
+ else low = middle + 1;
3383
+ }
3384
+ const a = Math.max(0, low - 1);
3385
+ const b = Math.min(keyframes.length - 1, a + 1);
3386
+ const from = keyframes[a];
3387
+ const to = keyframes[b];
3388
+ const delta = a === b ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
3389
+ if (to.interpolation === "catmullrom") {
3390
+ const before = keyframes[Math.max(0, a - 1)].value;
3391
+ const after = keyframes[Math.min(keyframes.length - 1, b + 1)].value;
3392
+ return [0, 1, 2].map((i) => catmullRom(delta, before[i], from.value[i], to.value[i], after[i]));
3393
+ }
3394
+ const target = to.pre ?? to.value;
3395
+ return [0, 1, 2].map((i) => from.value[i] + (target[i] - from.value[i]) * delta);
3396
+ }
3397
+ function entityAnimationTime(animation, time, loop = animation.loop) {
3398
+ return loop && animation.length > 0 ? time % animation.length : time;
3399
+ }
3400
+ function sampleEntityAnimation(animation, time, loop = animation.loop) {
3401
+ const elapsed = entityAnimationTime(animation, time, loop);
3402
+ const pose = {};
3403
+ for (const [name, bone] of Object.entries(animation.bones)) {
3404
+ const sampled = pose[name] = {};
3405
+ for (const channel of ENTITY_ANIMATION_CHANNELS) {
3406
+ const keyframes = bone[channel];
3407
+ if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
3408
+ }
3409
+ }
3410
+ return pose;
3411
+ }
3412
+ var ENTITY_ANIMATION_CHANNELS;
3413
+ var init_EntityAnimation = __esm({
3414
+ "src/entity/EntityAnimation.ts"() {
3415
+ ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
3416
+ }
3417
+ });
3418
+
3419
+ // src/entity/scene/EntityAnimationPlayer.ts
3420
+ var ZERO, EntityAnimationPlayer;
3421
+ var init_EntityAnimationPlayer = __esm({
3422
+ "src/entity/scene/EntityAnimationPlayer.ts"() {
3423
+ init_EntityAnimation();
3424
+ ZERO = [0, 0, 0];
3425
+ EntityAnimationPlayer = class {
3426
+ constructor() {
3427
+ this.parts = [];
3428
+ this._time = 0;
3429
+ this.loop = false;
3430
+ this.speed = 1;
3431
+ }
3432
+ get animation() {
3433
+ return this._animation;
3434
+ }
3435
+ get time() {
3436
+ return this._time;
3437
+ }
3438
+ /**
3439
+ * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
3440
+ * bones without a matching part are skipped.
3441
+ */
3442
+ play(layers, animation, options = {}) {
3443
+ this.stop();
3444
+ this._animation = animation;
3445
+ this._time = options.time ?? 0;
3446
+ this.loop = options.loop ?? animation.loop;
3447
+ this.speed = options.speed ?? 1;
3448
+ for (const layer of layers) {
3449
+ for (const bone of Object.keys(animation.bones)) {
3450
+ const object = layer.getObjectByName(`group:${bone}`);
3451
+ if (!object) continue;
3452
+ this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
3453
+ }
3454
+ }
3455
+ this.apply();
3456
+ }
3457
+ /** Restores the default poses. Returns whether an animation was active. */
3458
+ stop() {
3459
+ if (!this._animation) return false;
3460
+ for (const part of this.parts) {
3461
+ part.object.position.copy(part.position);
3462
+ part.object.rotation.copy(part.rotation);
3463
+ part.object.scale.copy(part.scale);
3464
+ }
3465
+ this.clear();
3466
+ return true;
3467
+ }
3468
+ /** Forgets the animation without touching the parts, for parts that no longer exist. */
3469
+ clear() {
3470
+ this.parts = [];
3471
+ this._animation = void 0;
3472
+ this._time = 0;
3473
+ }
3474
+ setTime(seconds) {
3475
+ if (!this._animation) return false;
3476
+ this._time = seconds;
3477
+ this.apply();
3478
+ return true;
3479
+ }
3480
+ advance(deltaSeconds) {
3481
+ return this.setTime(this._time + deltaSeconds * this.speed);
3482
+ }
3483
+ apply() {
3484
+ const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
3485
+ for (const part of this.parts) {
3486
+ const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
3487
+ part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
3488
+ part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
3489
+ part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
3490
+ }
3491
+ }
3492
+ };
3493
+ }
3494
+ });
3495
+
3119
3496
  // src/instance/InstanceReference.ts
3120
3497
  function isInstanceReference(obj) {
3121
3498
  return obj.isInstanceReference;
@@ -3613,6 +3990,242 @@ var init_SceneObject = __esm({
3613
3990
  }
3614
3991
  });
3615
3992
 
3993
+ // src/entity/scene/EntityObject.ts
3994
+ function isEntityObject(obj) {
3995
+ return obj.isEntityObject;
3996
+ }
3997
+ var import_ts_deepmerge4, import_three13, EntityObject;
3998
+ var init_EntityObject = __esm({
3999
+ "src/entity/scene/EntityObject.ts"() {
4000
+ init_SceneObject();
4001
+ init_Caching();
4002
+ import_ts_deepmerge4 = __toESM(require_dist());
4003
+ import_three13 = require("three");
4004
+ init_Ticker();
4005
+ init_model();
4006
+ init_ModelTextures();
4007
+ init_AssetKey();
4008
+ init_Materials();
4009
+ init_MinecraftCubeTexture();
4010
+ init_three();
4011
+ init_EntityAnimationPlayer();
4012
+ EntityObject = class _EntityObject extends SceneObject {
4013
+ constructor(entity, options) {
4014
+ super();
4015
+ this.entity = entity;
4016
+ this.isEntityObject = true;
4017
+ this.meshesCreated = false;
4018
+ this.geometries = /* @__PURE__ */ new Set();
4019
+ this.disposeWireframes = [];
4020
+ /** Scrolling materials are owned: their texture offset follows this entity's age. */
4021
+ this.scrollMaterials = [];
4022
+ /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
4023
+ this.age = 0;
4024
+ this.animationPlayer = new EntityAnimationPlayer();
4025
+ this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
4026
+ this.addEventListener("added", () => this.updateScrollSubscription());
4027
+ this.addEventListener("removed", () => this.updateScrollSubscription());
4028
+ }
4029
+ static {
4030
+ this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
4031
+ }
4032
+ async init() {
4033
+ this.createMeshes();
4034
+ await this.applyTextures();
4035
+ }
4036
+ dispose() {
4037
+ super.dispose();
4038
+ }
4039
+ disposeAndRemoveAllChildren() {
4040
+ this.clearScrollMaterials();
4041
+ for (const geometry of this.geometries) geometry.dispose();
4042
+ this.geometries.clear();
4043
+ for (const dispose of this.disposeWireframes.splice(0)) dispose();
4044
+ this.animationPlayer.clear();
4045
+ super.disposeAndRemoveAllChildren();
4046
+ }
4047
+ clearScrollMaterials() {
4048
+ Ticker.remove(this.scrollTicker);
4049
+ this.scrollTicker = void 0;
4050
+ for (const { material } of this.scrollMaterials.splice(0)) {
4051
+ material.map?.dispose();
4052
+ material.dispose();
4053
+ }
4054
+ }
4055
+ updateScrollSubscription() {
4056
+ if (this.parent && this.scrollMaterials.length) {
4057
+ if (this.scrollTicker === void 0) {
4058
+ this.scrollTicker = Ticker.add(() => {
4059
+ this.age++;
4060
+ this.updateScroll();
4061
+ });
4062
+ }
4063
+ } else {
4064
+ Ticker.remove(this.scrollTicker);
4065
+ this.scrollTicker = void 0;
4066
+ }
4067
+ }
4068
+ /** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
4069
+ updateScroll() {
4070
+ for (const { offset, speed } of this.scrollMaterials) {
4071
+ offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
4072
+ }
4073
+ this.notifyDirty();
4074
+ }
4075
+ //<editor-fold desc="ANIMATION">
4076
+ /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
4077
+ get animation() {
4078
+ return this.animationPlayer.animation;
4079
+ }
4080
+ /** Seconds since the animation started, before looping. */
4081
+ get animationTime() {
4082
+ return this.animationPlayer.time;
4083
+ }
4084
+ /**
4085
+ * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
4086
+ * Parts of every layer are matched by name and their current pose is the default the offsets add to.
4087
+ * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
4088
+ */
4089
+ playAnimation(animation, options) {
4090
+ this.createMeshes();
4091
+ const layers = Object.keys(this.entityLayers).map((name) => this.getLayerGroup(name)).filter((layer) => !!layer);
4092
+ this.animationPlayer.play(layers, animation, options);
4093
+ this.notifyDirty();
4094
+ }
4095
+ /** Stops the animation and restores the default pose. */
4096
+ stopAnimation() {
4097
+ if (this.animationPlayer.stop()) this.notifyDirty();
4098
+ }
4099
+ /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
4100
+ setAnimationTime(seconds) {
4101
+ if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
4102
+ }
4103
+ /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
4104
+ advanceAnimation(deltaSeconds) {
4105
+ if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
4106
+ }
4107
+ //</editor-fold>
4108
+ getLayerGroup(name) {
4109
+ return super.getGroupByName(`layer:${name}`);
4110
+ }
4111
+ getGroupByName(name, layerName) {
4112
+ return layerName === void 0 ? super.getGroupByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name}`);
4113
+ }
4114
+ getMeshByName(name, layerName) {
4115
+ return layerName === void 0 ? super.getMeshByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name}`);
4116
+ }
4117
+ get entityLayers() {
4118
+ return this.entity.layers ?? { main: this.entity };
4119
+ }
4120
+ getTextureKey(layer) {
4121
+ if (layer.texture) return layer.texture;
4122
+ const key = layer.key;
4123
+ return new AssetKey(
4124
+ key.namespace,
4125
+ isAssetKey(key) ? key.getFullPath() : key.path,
4126
+ "textures",
4127
+ "entity",
4128
+ "assets",
4129
+ ".png"
4130
+ );
4131
+ }
4132
+ async loadTextures(layer = this.entity) {
4133
+ return ModelTextures.get(this.getTextureKey(layer));
4134
+ }
4135
+ createMeshes(force = false) {
4136
+ if (this.meshesCreated && !force) return;
4137
+ const modelRoot = new import_three13.Object3D();
4138
+ const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
4139
+ if (transform) {
4140
+ for (const op of transform) {
4141
+ const matrix = new import_three13.Matrix4();
4142
+ if ("scale" in op) matrix.makeScale(...op.scale);
4143
+ else if ("translate" in op) matrix.makeTranslation(...op.translate);
4144
+ else matrix.makeRotationFromEuler(new import_three13.Euler(...op.rotate, "ZYX"));
4145
+ modelRoot.matrix.multiply(matrix);
4146
+ }
4147
+ modelRoot.matrixAutoUpdate = false;
4148
+ } else if (this.options.flip ?? true) {
4149
+ modelRoot.scale.set(-1, -1, 1);
4150
+ }
4151
+ this.add(modelRoot);
4152
+ Object.entries(this.entityLayers).forEach(([name, layer], index) => {
4153
+ const group = this.createGroup(`layer:${name}`);
4154
+ modelRoot.add(group);
4155
+ const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
4156
+ this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
4157
+ });
4158
+ this.meshesCreated = true;
4159
+ }
4160
+ createPart(name, part, parent, textureSize, material, renderOrder, inward = true) {
4161
+ const anchor = this.createGroup(name);
4162
+ anchor.position.fromArray(part.pose.offset);
4163
+ anchor.rotation.set(...part.pose.rotation, "ZYX");
4164
+ anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
4165
+ parent.add(anchor);
4166
+ const size = part.texture ?? textureSize;
4167
+ for (const cube of part.cubes) {
4168
+ const [width, height, depth] = cube.size;
4169
+ const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
4170
+ const texture = new MinecraftCubeTexture(...cube.uv, ...size);
4171
+ const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
4172
+ const geometry = this._getBoxGeometryForDimensionsAndUv(
4173
+ width + growX * 2,
4174
+ height + growY * 2,
4175
+ depth + growZ * 2,
4176
+ uv
4177
+ ).clone();
4178
+ this.geometries.add(geometry);
4179
+ geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
4180
+ if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
4181
+ const index = Array.from(geometry.getIndex().array);
4182
+ geometry.setIndex(index.concat(index.slice().reverse()));
4183
+ }
4184
+ const mesh = this.createMesh(name, geometry, material);
4185
+ mesh.renderOrder = renderOrder;
4186
+ anchor.add(mesh);
4187
+ if (this.options.wireframe) this.disposeWireframes.push(addWireframeToMesh(geometry, mesh));
4188
+ }
4189
+ for (const [childName, child] of Object.entries(part.children)) {
4190
+ this.createPart(childName, child, anchor, size, material, renderOrder, inward);
4191
+ }
4192
+ }
4193
+ async applyTextures() {
4194
+ this.clearScrollMaterials();
4195
+ await Promise.all(Object.entries(this.entityLayers).map(async ([name, layer]) => {
4196
+ const mode = layer.render ?? layer.layer.render ?? "cutout";
4197
+ const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
4198
+ const scroll = Materials.entityModeScroll(mode);
4199
+ const assetKeyStr = this.getTextureKey(layer).serialize();
4200
+ const keyStr = `entity:${mode}:${tint === void 0 ? "" : new import_three13.Color(tint).getHexString()}:${assetKeyStr}`;
4201
+ let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
4202
+ if (!mat) {
4203
+ const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
4204
+ const imageData = await this.loadTextures(layer);
4205
+ if (!imageData) return;
4206
+ const canvas = imageData.data.canvas;
4207
+ const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode, tint);
4208
+ mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
4209
+ if (scroll) {
4210
+ this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
4211
+ }
4212
+ }
4213
+ this.getLayerGroup(name)?.traverse((object) => {
4214
+ if (isMesh(object)) object.material = mat;
4215
+ });
4216
+ }));
4217
+ if (!this.children.length) {
4218
+ this.clearScrollMaterials();
4219
+ } else if (this.scrollMaterials.length) {
4220
+ this.updateScroll();
4221
+ }
4222
+ this.updateScrollSubscription();
4223
+ this.notifyDirty();
4224
+ }
4225
+ };
4226
+ }
4227
+ });
4228
+
3616
4229
  // src/three/BufferGeometryUtils.js
3617
4230
  function computeTangents(geometry) {
3618
4231
  geometry.computeTangents();
@@ -4192,32 +4805,151 @@ var init_ModelCulling = __esm({
4192
4805
  }
4193
4806
  });
4194
4807
 
4808
+ // src/model/SpecialItems.ts
4809
+ var import_three22, SpecialItems;
4810
+ var init_SpecialItems = __esm({
4811
+ "src/model/SpecialItems.ts"() {
4812
+ import_three22 = require("three");
4813
+ init_AssetKey();
4814
+ init_Entities();
4815
+ SpecialItems = class {
4816
+ /** Resolves the static entity parts drawn by a special item renderer, in model units. */
4817
+ static async getParts(special, root) {
4818
+ const texture = (id, directory) => {
4819
+ const key = AssetKey.parse("textures", id);
4820
+ return new AssetKey(
4821
+ key.namespace,
4822
+ [directory, key.getFullPath()].filter(Boolean).join("/"),
4823
+ "textures",
4824
+ "entity",
4825
+ "assets",
4826
+ ".png",
4827
+ root
4828
+ );
4829
+ };
4830
+ const load = async (id, textureKey, transform, rotations = {}) => {
4831
+ const key = new AssetKey("minecraft", id, void 0, void 0, "entity-models", ".json", root);
4832
+ const model = await Entities.getEntity(key, textureKey, { layer: "main" });
4833
+ if (!model) throw new Error(`Missing entity model minecraft:${id} for special item ${special.type}`);
4834
+ return { model, transform, rotations };
4835
+ };
4836
+ switch (special.type) {
4837
+ case "minecraft:chest":
4838
+ case "chest": {
4839
+ const angle = -(special.openness ?? 0) * Math.PI / 2;
4840
+ const chest = await load("chest", texture(special.texture, "chest"), new import_three22.Matrix4(), {
4841
+ lid: [angle, 0, 0],
4842
+ lock: [angle, 0, 0]
4843
+ });
4844
+ chest.model = { ...chest.model, render: "solid", layers: void 0 };
4845
+ return [chest];
4846
+ }
4847
+ case "minecraft:bed":
4848
+ case "bed": {
4849
+ const transform = new import_three22.Matrix4().makeTranslation(0, 9, 0).multiply(new import_three22.Matrix4().makeRotationX(Math.PI / 2)).multiply(new import_three22.Matrix4().makeTranslation(8, 8, 8)).multiply(new import_three22.Matrix4().makeRotationZ(Math.PI)).multiply(new import_three22.Matrix4().makeTranslation(-8, -8, -8));
4850
+ const key = texture(special.texture, "bed");
4851
+ return Promise.all([
4852
+ load("bed_head", key, transform),
4853
+ load("bed_foot", key, new import_three22.Matrix4().makeTranslation(0, 0, -16).multiply(transform))
4854
+ ]);
4855
+ }
4856
+ case "minecraft:head":
4857
+ case "head": {
4858
+ const models = {
4859
+ skeleton: "skeleton_skull",
4860
+ wither_skeleton: "wither_skeleton_skull",
4861
+ zombie: "zombie_head",
4862
+ creeper: "creeper_head",
4863
+ dragon: "dragon_skull",
4864
+ piglin: "piglin_head"
4865
+ };
4866
+ const id = Object.prototype.hasOwnProperty.call(models, special.kind) ? models[special.kind] : void 0;
4867
+ if (!id) throw new Error(`Unsupported special item head kind ${special.kind}`);
4868
+ const animation = (special.animation ?? 0) * Math.PI * 0.2;
4869
+ const rotations = { head: [0, Math.PI, 0] };
4870
+ if (special.kind === "dragon") rotations.jaw = [(Math.sin(animation) + 1) * 0.2, 0, 0];
4871
+ if (special.kind === "piglin") {
4872
+ rotations.left_ear = [0, 0, -(Math.cos(animation * 1.2) + 2.5) * 0.2];
4873
+ rotations.right_ear = [0, 0, (Math.cos(animation) + 2.5) * 0.2];
4874
+ }
4875
+ return [await load(
4876
+ id,
4877
+ special.texture ? texture(special.texture, "") : void 0,
4878
+ new import_three22.Matrix4().makeTranslation(8, 0, 8).multiply(new import_three22.Matrix4().makeScale(-1, -1, 1)),
4879
+ rotations
4880
+ )];
4881
+ }
4882
+ }
4883
+ }
4884
+ /** An owned material with model-preview shading; its entity texture remains shared. */
4885
+ static createMaterial(source, shade) {
4886
+ const material = source.clone();
4887
+ if (shade) {
4888
+ material.onBeforeCompile = (shader) => {
4889
+ shader.vertexShader = `varying float itemLight;
4890
+ ${shader.vertexShader}`.replace("#include <begin_vertex>", `
4891
+ #include <begin_vertex>
4892
+ vec3 N = inverseTransformDirection(normalMatrix * normal, viewMatrix);
4893
+ itemLight = (1.0 + N.y) * 0.25 - N.x * N.x * 0.15 + N.z * N.z * 0.05 + 0.5;
4894
+ `);
4895
+ shader.fragmentShader = `varying float itemLight;
4896
+ ${shader.fragmentShader}`.replace(
4897
+ "#include <color_fragment>",
4898
+ "#include <color_fragment>\ndiffuseColor.rgb *= itemLight;"
4899
+ );
4900
+ };
4901
+ material.customProgramCacheKey = () => "special-item-side";
4902
+ }
4903
+ return material;
4904
+ }
4905
+ };
4906
+ }
4907
+ });
4908
+
4909
+ // src/model/GuiLight.ts
4910
+ var GuiLight;
4911
+ var init_GuiLight = __esm({
4912
+ "src/model/GuiLight.ts"() {
4913
+ GuiLight = /* @__PURE__ */ ((GuiLight2) => {
4914
+ GuiLight2["FRONT"] = "front";
4915
+ GuiLight2["SIDE"] = "side";
4916
+ return GuiLight2;
4917
+ })(GuiLight || {});
4918
+ }
4919
+ });
4920
+
4195
4921
  // src/model/scene/ModelObject.ts
4196
4922
  function isModelObject(obj) {
4197
4923
  return obj.isModelObject;
4198
4924
  }
4199
- var import_three22, import_ts_deepmerge5, p7, ModelObject;
4925
+ var import_three23, import_ts_deepmerge5, p7, ModelObject;
4200
4926
  var init_ModelObject = __esm({
4201
4927
  "src/model/scene/ModelObject.ts"() {
4202
4928
  init_SceneObject();
4203
4929
  init_Materials();
4204
4930
  init_UVMapper();
4205
- import_three22 = require("three");
4931
+ import_three23 = require("three");
4206
4932
  init_BufferGeometryUtils();
4207
4933
  init_model();
4208
4934
  import_ts_deepmerge5 = __toESM(require_dist());
4209
4935
  init_log();
4210
4936
  init_CubeFace();
4937
+ init_DisplayPosition();
4211
4938
  init_DisplayTransforms();
4212
4939
  init_ModelCulling();
4940
+ init_SpecialItems();
4941
+ init_EntityObject();
4942
+ init_GuiLight();
4213
4943
  p7 = prefix("ModelObject");
4214
4944
  ModelObject = class _ModelObject extends SceneObject {
4215
4945
  constructor(originalModel, options) {
4216
4946
  super(options);
4217
4947
  this.originalModel = originalModel;
4218
4948
  this.isModelObject = true;
4949
+ this.specialMaterials = /* @__PURE__ */ new Map();
4219
4950
  this.meshesCreated = false;
4220
4951
  this.options = (0, import_ts_deepmerge5.default)({}, _ModelObject.DEFAULT_OPTIONS, options ?? {});
4952
+ if (originalModel.special) this.options.instanceMeshes = false;
4221
4953
  if (this.options.tints) this.options.tints = { ...this.options.tints };
4222
4954
  this.addEventListener("added", () => this.updateAnimationSubscription());
4223
4955
  this.addEventListener("removed", () => this.updateAnimationSubscription());
@@ -4226,6 +4958,39 @@ var init_ModelObject = __esm({
4226
4958
  this.DEFAULT_OPTIONS = (0, import_ts_deepmerge5.default)({}, SceneObject.DEFAULT_OPTIONS, {});
4227
4959
  }
4228
4960
  async init() {
4961
+ const special = this.originalModel.special;
4962
+ if (special) {
4963
+ const parts = await SpecialItems.getParts(special, this.originalModel.key?.root);
4964
+ const transform = this.options.displayPosition ? DisplayTransforms.getMatrix(this.originalModel.display, this.options.displayPosition) : new import_three23.Matrix4();
4965
+ transform.multiply(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
4966
+ try {
4967
+ for (const part of parts) {
4968
+ const object = new EntityObject(part.model, { flip: false, wireframe: this.options.wireframe });
4969
+ object.matrix.copy(transform).multiply(part.transform);
4970
+ object.matrixAutoUpdate = false;
4971
+ this.add(object);
4972
+ await object.init();
4973
+ object.iterateAllMeshes((mesh) => {
4974
+ const source = mesh.material;
4975
+ let material = this.specialMaterials.get(source);
4976
+ if (!material) {
4977
+ const front = this.options.displayPosition === "gui" /* GUI */ && this.originalModel.gui_light === "front" /* FRONT */;
4978
+ material = SpecialItems.createMaterial(source, !front);
4979
+ this.specialMaterials.set(source, material);
4980
+ }
4981
+ mesh.material = material;
4982
+ });
4983
+ for (const [name, rotation] of Object.entries(part.rotations)) {
4984
+ object.getGroupByName(name)?.rotation.set(...rotation, "ZYX");
4985
+ }
4986
+ }
4987
+ } catch (error) {
4988
+ this.disposeAndRemoveAllChildren();
4989
+ throw error;
4990
+ }
4991
+ this.notifyDirty();
4992
+ return;
4993
+ }
4229
4994
  await this.loadTextures();
4230
4995
  this.createMeshes();
4231
4996
  this.applyTextures();
@@ -4259,7 +5024,7 @@ var init_ModelObject = __esm({
4259
5024
  elGeo.clearGroups();
4260
5025
  }
4261
5026
  if (this.options.uvLockRotation) {
4262
- UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three22.Euler(...this.options.uvLockRotation));
5027
+ UVMapper.lockUvs(elGeo, el.faces, this.atlas, new import_three23.Euler(...this.options.uvLockRotation));
4263
5028
  }
4264
5029
  if (this.options.tints) {
4265
5030
  const colors = new Float32Array(elGeo.getAttribute("position").count * 3).fill(1);
@@ -4268,19 +5033,19 @@ var init_ModelObject = __esm({
4268
5033
  if (tintIndex === void 0 || tintIndex < 0) continue;
4269
5034
  const tint = this.options.tints[tintIndex];
4270
5035
  if (tint === void 0) continue;
4271
- const color = new import_three22.Color(tint);
5036
+ const color = new import_three23.Color(tint);
4272
5037
  for (let vertex = 0; vertex < 4; vertex++) {
4273
5038
  color.toArray(colors, (faceIndex * 4 + vertex) * 3);
4274
5039
  }
4275
5040
  }
4276
- elGeo.setAttribute("color", new import_three22.BufferAttribute(colors, 3));
5041
+ elGeo.setAttribute("color", new import_three23.BufferAttribute(colors, 3));
4277
5042
  }
4278
- elGeo.applyMatrix4(new import_three22.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
4279
- elGeo.applyMatrix4(new import_three22.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
5043
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation((el.to[0] - el.from[0]) / 2, (el.to[1] - el.from[1]) / 2, (el.to[2] - el.from[2]) / 2));
5044
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation(el.from[0], el.from[1], el.from[2]));
4280
5045
  if (el.rotation) {
4281
5046
  applyElementRotation(el.rotation, elGeo);
4282
5047
  }
4283
- elGeo.applyMatrix4(new import_three22.Matrix4().makeTranslation(-8, -8, -8));
5048
+ elGeo.applyMatrix4(new import_three23.Matrix4().makeTranslation(-8, -8, -8));
4284
5049
  if (displayTransform) DisplayTransforms.apply(elGeo, displayTransform);
4285
5050
  if (this.options.mergeMeshes) {
4286
5051
  allGeos.push(elGeo);
@@ -4302,7 +5067,7 @@ var init_ModelObject = __esm({
4302
5067
  if (allGeos.length > 0) {
4303
5068
  combinedGeo = mergeBufferGeometries(allGeos);
4304
5069
  } else {
4305
- combinedGeo = new import_three22.BoxGeometry(16, 16, 16);
5070
+ combinedGeo = new import_three23.BoxGeometry(16, 16, 16);
4306
5071
  if (displayTransform) DisplayTransforms.apply(combinedGeo, displayTransform);
4307
5072
  }
4308
5073
  combinedGeo.computeBoundingBox();
@@ -4370,6 +5135,8 @@ var init_ModelObject = __esm({
4370
5135
  this.atlasMaterial?.dispose();
4371
5136
  this.atlasTexture = void 0;
4372
5137
  this.atlasMaterial = void 0;
5138
+ for (const material of this.specialMaterials.values()) material.dispose();
5139
+ this.specialMaterials.clear();
4373
5140
  super.disposeAndRemoveAllChildren();
4374
5141
  }
4375
5142
  };
@@ -4410,7 +5177,7 @@ function ownHeight(sample) {
4410
5177
  return (level === 0 || level >= 8 ? 8 : 8 - level) / 9;
4411
5178
  }
4412
5179
  function createFluidGeometry(kind, sample) {
4413
- const geometry = new import_three27.BufferGeometry();
5180
+ const geometry = new import_three28.BufferGeometry();
4414
5181
  const positions = [], normals = [], uvs = [], indices = [];
4415
5182
  const self = sample(0, 0, 0);
4416
5183
  const height = (x, z) => {
@@ -4509,16 +5276,16 @@ function createFluidGeometry(kind, sample) {
4509
5276
  1
4510
5277
  );
4511
5278
  }
4512
- geometry.setAttribute("position", new import_three27.Float32BufferAttribute(positions, 3));
4513
- geometry.setAttribute("normal", new import_three27.Float32BufferAttribute(normals, 3));
4514
- geometry.setAttribute("uv", new import_three27.Float32BufferAttribute(uvs, 2));
5279
+ geometry.setAttribute("position", new import_three28.Float32BufferAttribute(positions, 3));
5280
+ geometry.setAttribute("normal", new import_three28.Float32BufferAttribute(normals, 3));
5281
+ geometry.setAttribute("uv", new import_three28.Float32BufferAttribute(uvs, 2));
4515
5282
  geometry.setIndex(indices);
4516
5283
  return geometry;
4517
5284
  }
4518
- var import_three27, fluidRules, HORIZONTAL, EPSILON;
5285
+ var import_three28, fluidRules, HORIZONTAL, EPSILON;
4519
5286
  var init_FluidGeometry = __esm({
4520
5287
  "src/model/fluid/FluidGeometry.ts"() {
4521
- import_three27 = require("three");
5288
+ import_three28 = require("three");
4522
5289
  init_fluidBlocks();
4523
5290
  fluidRules = fluidBlocks_default;
4524
5291
  HORIZONTAL = [[0, -1], [0, 1], [-1, 0], [1, 0]];
@@ -4547,10 +5314,10 @@ function sampleFluid(kind, sample) {
4547
5314
  }
4548
5315
  return { key: key.join(""), sample: (x, y, z) => cells[(y + 1) * 9 + (z + 1) * 3 + x + 1] };
4549
5316
  }
4550
- var import_three28, FluidModelObject;
5317
+ var import_three29, FluidModelObject;
4551
5318
  var init_FluidModelObject = __esm({
4552
5319
  "src/model/fluid/FluidModelObject.ts"() {
4553
- import_three28 = require("three");
5320
+ import_three29 = require("three");
4554
5321
  init_AssetKey();
4555
5322
  init_Materials();
4556
5323
  init_ModelObject();
@@ -4583,10 +5350,10 @@ var init_FluidModelObject = __esm({
4583
5350
  }
4584
5351
  }
4585
5352
  geometry.clearGroups();
4586
- const color = new import_three28.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
5353
+ const color = new import_three29.Color(this.options.tints?.[0] ?? (this.kind === "water" ? 4159204 : 16777215));
4587
5354
  const colors = new Float32Array(geometry.getAttribute("position").count * 3);
4588
5355
  for (let i = 0; i < colors.length; i += 3) color.toArray(colors, i);
4589
- geometry.setAttribute("color", new import_three28.BufferAttribute(colors, 3));
5356
+ geometry.setAttribute("color", new import_three29.BufferAttribute(colors, 3));
4590
5357
  geometry.computeBoundingBox();
4591
5358
  geometry.computeBoundingSphere();
4592
5359
  if (this.options.instanceMeshes) {
@@ -4600,7 +5367,7 @@ var init_FluidModelObject = __esm({
4600
5367
  super.applyTextures();
4601
5368
  this.iterateAllMeshes((mesh) => {
4602
5369
  const material = mesh.material;
4603
- material.side = import_three28.DoubleSide;
5370
+ material.side = import_three29.DoubleSide;
4604
5371
  material.forceSinglePass = true;
4605
5372
  material.depthWrite = !material.transparent;
4606
5373
  });
@@ -4704,6 +5471,7 @@ __export(index_node_exports, {
4704
5471
  SkinPart: () => SkinPart,
4705
5472
  SkinTextures: () => SkinTextures,
4706
5473
  Skins: () => Skins,
5474
+ SpecialItems: () => SpecialItems,
4707
5475
  StructureParser: () => StructureParser,
4708
5476
  TextureAtlas: () => TextureAtlas,
4709
5477
  TextureLoader: () => TextureLoader,
@@ -4894,96 +5662,8 @@ var Meshes = class _Meshes {
4894
5662
  }
4895
5663
  };
4896
5664
 
4897
- // src/MinecraftCubeTexture.ts
4898
- init_UVMapper();
4899
- init_CubeFace();
4900
- var MinecraftCubeTexture = class {
4901
- constructor(u, v, width, height) {
4902
- this.u = u;
4903
- this.v = v;
4904
- this.width = width;
4905
- this.height = height;
4906
- }
4907
- mapW(x) {
4908
- return x / this.width;
4909
- }
4910
- mapH(x) {
4911
- return 1 - x / this.height;
4912
- }
4913
- getUvEast(w, h, l) {
4914
- return [
4915
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
4916
- [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
4917
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
4918
- [this.mapW(this.u + l + w), this.mapH(this.v + l)]
4919
- ];
4920
- }
4921
- getUvWest(w, h, l) {
4922
- return [
4923
- [this.mapW(this.u + l), this.mapH(this.v + l + h)],
4924
- [this.mapW(this.u), this.mapH(this.v + l + h)],
4925
- [this.mapW(this.u + l), this.mapH(this.v + l)],
4926
- [this.mapW(this.u), this.mapH(this.v + l)]
4927
- ];
4928
- }
4929
- getUvUp(w, h, l) {
4930
- return [
4931
- [this.mapW(this.u + l + w), this.mapH(this.v + l)],
4932
- [this.mapW(this.u + l + w + w), this.mapH(this.v + l)],
4933
- [this.mapW(this.u + l + w), this.mapH(this.v)],
4934
- [this.mapW(this.u + l + w + w), this.mapH(this.v)]
4935
- ];
4936
- }
4937
- getUvDown(w, h, l) {
4938
- return [
4939
- [this.mapW(this.u + l), this.mapH(this.v)],
4940
- [this.mapW(this.u + l + w), this.mapH(this.v)],
4941
- [this.mapW(this.u + l), this.mapH(this.v + l)],
4942
- [this.mapW(this.u + l + w), this.mapH(this.v + l)]
4943
- ];
4944
- }
4945
- getUvSouth(w, h, l) {
4946
- return [
4947
- [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l + h)],
4948
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
4949
- [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
4950
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
4951
- ];
4952
- }
4953
- getUvNorth(w, h, l) {
4954
- return [
4955
- [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
4956
- [this.mapW(this.u + l), this.mapH(this.v + l + h)],
4957
- [this.mapW(this.u + l + w), this.mapH(this.v + l)],
4958
- [this.mapW(this.u + l), this.mapH(this.v + l)]
4959
- ];
4960
- }
4961
- getFaceUv(face, w, h, l) {
4962
- switch (face) {
4963
- case "east" /* EAST */:
4964
- return this.getUvEast(w, h, l);
4965
- case "west" /* WEST */:
4966
- return this.getUvWest(w, h, l);
4967
- case "up" /* UP */:
4968
- return this.getUvUp(w, h, l);
4969
- case "down" /* DOWN */:
4970
- return this.getUvDown(w, h, l);
4971
- case "south" /* SOUTH */:
4972
- return this.getUvSouth(w, h, l);
4973
- case "north" /* NORTH */:
4974
- return this.getUvNorth(w, h, l);
4975
- }
4976
- }
4977
- toUvArray(w, h, l, mirror = false) {
4978
- const uv = [];
4979
- for (let i = 0; i < CUBE_FACES.length; i++) {
4980
- const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
4981
- const corners = this.getFaceUv(face, w, h, l);
4982
- UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
4983
- }
4984
- return uv;
4985
- }
4986
- };
5665
+ // src/index.ts
5666
+ init_MinecraftCubeTexture();
4987
5667
 
4988
5668
  // src/SceneStats.ts
4989
5669
  var SceneStats = class {
@@ -5077,116 +5757,7 @@ var BlockEntities = class {
5077
5757
 
5078
5758
  // src/assets/index.ts
5079
5759
  init_BlockStates();
5080
-
5081
- // src/assets/Entities.ts
5082
- init_AssetKey();
5083
- init_AssetLoader();
5084
- init_source();
5085
- init_Caching();
5086
- init_Assets();
5087
- init_MineRenderError();
5088
- init_ModelTextures();
5089
- var Entities = class {
5090
- static async getEntityList() {
5091
- const collect = async (path) => {
5092
- const prefix2 = path ? `${path}/` : "";
5093
- const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
5094
- const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
5095
- if (!list) return [];
5096
- const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
5097
- const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
5098
- return [...files, ...children.flat()];
5099
- };
5100
- return collect("");
5101
- }
5102
- static async getModelFile(modelKey) {
5103
- const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
5104
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
5105
- return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
5106
- }
5107
- static async getLayerList(modelKey) {
5108
- return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
5109
- }
5110
- /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
5111
- static async getPassList(modelKey) {
5112
- return (await this.getModelFile(modelKey))?.passes ?? [];
5113
- }
5114
- static async getEntity(modelKey, textureKey, options) {
5115
- const model = await this.getModelFile(modelKey);
5116
- if (!model) return void 0;
5117
- const passes = options?.layers || options?.layer !== void 0 ? [] : (model.passes ?? []).filter((pass) => pass.when === void 0 || options?.when?.includes(pass.when));
5118
- const draws = [...new Set(options?.layers ?? [options?.layer ?? "main"])].map((layer) => ({ layer }));
5119
- if (draws.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
5120
- draws.push(...passes);
5121
- const names = [];
5122
- const selected = draws.map((pass) => {
5123
- const layer = model.layers[pass.layer];
5124
- if (!layer) {
5125
- throw new MineRenderError(`Entity ${model.id} has no layer "${pass.layer}". Available layers: ${Object.keys(model.layers).join(", ")}`);
5126
- }
5127
- let name = pass.layer;
5128
- for (let n = 2; names.includes(name); n++) name = `${pass.layer}#${n}`;
5129
- names.push(name);
5130
- return { name, layer, pass };
5131
- });
5132
- const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer, pass }, index) => {
5133
- const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
5134
- const textureLocation = pass.textureLocation ?? layer.textureLocation;
5135
- let texture;
5136
- if (override) {
5137
- const path = isAssetKey(override) ? override.getFullPath() : override.path;
5138
- texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
5139
- } else if (textureLocation !== void 0) {
5140
- texture = AssetKey.parse("textures", textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
5141
- } else {
5142
- texture = await this.resolveTexture(modelKey);
5143
- }
5144
- const render = pass.render ?? layer.render;
5145
- return [name, { key: override ?? modelKey, texture, layer, ...render && { render }, ...pass.tint && { tint: pass.tint } }];
5146
- })));
5147
- return { ...layers[names[0]], id: model.id, layers, ...model.transform && { transform: model.transform } };
5148
- }
5149
- /**
5150
- * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
5151
- */
5152
- static async getAnimations(modelKey) {
5153
- const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
5154
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models/animations", ".json");
5155
- const file = await Caching.entityAnimationCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
5156
- return file?.animations;
5157
- }
5158
- static async resolveTexture(modelKey) {
5159
- const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
5160
- const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
5161
- return Caching.entityTextureCache.get(key.serialize(), async () => {
5162
- const name = path.split("/").pop();
5163
- for (const candidate of [path, `${path}/${name}`]) {
5164
- const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
5165
- if (await ModelTextures.get(texture)) return texture;
5166
- }
5167
- const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json");
5168
- const list = await AssetLoader.get(listKey, "list" /* LIST */);
5169
- const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
5170
- const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
5171
- if (!file) return void 0;
5172
- const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json");
5173
- const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
5174
- const assets = variant?.assets;
5175
- const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
5176
- return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
5177
- });
5178
- }
5179
- /** @deprecated Use getEntityList(); block entities share the entity dataset. */
5180
- static getBlockList() {
5181
- return this.getEntityList();
5182
- }
5183
- /** @deprecated Use getEntity(); block entities share the entity dataset. */
5184
- static getBlock(modelKey, textureKey, options) {
5185
- return this.getEntity(modelKey, textureKey, options);
5186
- }
5187
- };
5188
-
5189
- // src/assets/index.ts
5760
+ init_Entities();
5190
5761
  init_ModelTextures();
5191
5762
  init_Models();
5192
5763
  init_source();
@@ -5231,347 +5802,12 @@ function trimCanvas(source) {
5231
5802
  return canvas;
5232
5803
  }
5233
5804
 
5234
- // src/entity/EntityAnimation.ts
5235
- var ENTITY_ANIMATION_CHANNELS = ["position", "rotation", "scale"];
5236
- function catmullRom(delta, p0, p1, p22, p32) {
5237
- return 0.5 * (2 * p1 + (p22 - p0) * delta + (2 * p0 - 5 * p1 + 4 * p22 - p32) * delta * delta + (3 * p1 - p0 - 3 * p22 + p32) * delta * delta * delta);
5238
- }
5239
- function sampleEntityKeyframes(keyframes, time) {
5240
- if (keyframes.length === 0) return [0, 0, 0];
5241
- let low = 0, high = keyframes.length;
5242
- while (low < high) {
5243
- const middle = low + high >>> 1;
5244
- if (time <= keyframes[middle].time) high = middle;
5245
- else low = middle + 1;
5246
- }
5247
- const a = Math.max(0, low - 1);
5248
- const b = Math.min(keyframes.length - 1, a + 1);
5249
- const from = keyframes[a];
5250
- const to = keyframes[b];
5251
- const delta = a === b ? 0 : Math.min(1, Math.max(0, (time - from.time) / (to.time - from.time)));
5252
- if (to.interpolation === "catmullrom") {
5253
- const before = keyframes[Math.max(0, a - 1)].value;
5254
- const after = keyframes[Math.min(keyframes.length - 1, b + 1)].value;
5255
- return [0, 1, 2].map((i) => catmullRom(delta, before[i], from.value[i], to.value[i], after[i]));
5256
- }
5257
- const target = to.pre ?? to.value;
5258
- return [0, 1, 2].map((i) => from.value[i] + (target[i] - from.value[i]) * delta);
5259
- }
5260
- function entityAnimationTime(animation, time, loop = animation.loop) {
5261
- return loop && animation.length > 0 ? time % animation.length : time;
5262
- }
5263
- function sampleEntityAnimation(animation, time, loop = animation.loop) {
5264
- const elapsed = entityAnimationTime(animation, time, loop);
5265
- const pose = {};
5266
- for (const [name, bone] of Object.entries(animation.bones)) {
5267
- const sampled = pose[name] = {};
5268
- for (const channel of ENTITY_ANIMATION_CHANNELS) {
5269
- const keyframes = bone[channel];
5270
- if (keyframes?.length) sampled[channel] = sampleEntityKeyframes(keyframes, elapsed);
5271
- }
5272
- }
5273
- return pose;
5274
- }
5275
-
5276
- // src/entity/scene/EntityAnimationPlayer.ts
5277
- var ZERO = [0, 0, 0];
5278
- var EntityAnimationPlayer = class {
5279
- constructor() {
5280
- this.parts = [];
5281
- this._time = 0;
5282
- this.loop = false;
5283
- this.speed = 1;
5284
- }
5285
- get animation() {
5286
- return this._animation;
5287
- }
5288
- get time() {
5289
- return this._time;
5290
- }
5291
- /**
5292
- * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
5293
- * bones without a matching part are skipped.
5294
- */
5295
- play(layers, animation, options = {}) {
5296
- this.stop();
5297
- this._animation = animation;
5298
- this._time = options.time ?? 0;
5299
- this.loop = options.loop ?? animation.loop;
5300
- this.speed = options.speed ?? 1;
5301
- for (const layer of layers) {
5302
- for (const bone of Object.keys(animation.bones)) {
5303
- const object = layer.getObjectByName(`group:${bone}`);
5304
- if (!object) continue;
5305
- this.parts.push({ bone, object, position: object.position.clone(), rotation: object.rotation.clone(), scale: object.scale.clone() });
5306
- }
5307
- }
5308
- this.apply();
5309
- }
5310
- /** Restores the default poses. Returns whether an animation was active. */
5311
- stop() {
5312
- if (!this._animation) return false;
5313
- for (const part of this.parts) {
5314
- part.object.position.copy(part.position);
5315
- part.object.rotation.copy(part.rotation);
5316
- part.object.scale.copy(part.scale);
5317
- }
5318
- this.clear();
5319
- return true;
5320
- }
5321
- /** Forgets the animation without touching the parts, for parts that no longer exist. */
5322
- clear() {
5323
- this.parts = [];
5324
- this._animation = void 0;
5325
- this._time = 0;
5326
- }
5327
- setTime(seconds) {
5328
- if (!this._animation) return false;
5329
- this._time = seconds;
5330
- this.apply();
5331
- return true;
5332
- }
5333
- advance(deltaSeconds) {
5334
- return this.setTime(this._time + deltaSeconds * this.speed);
5335
- }
5336
- apply() {
5337
- const pose = sampleEntityAnimation(this._animation, this._time, this.loop);
5338
- for (const part of this.parts) {
5339
- const { position = ZERO, rotation = ZERO, scale = ZERO } = pose[part.bone];
5340
- part.object.position.set(part.position.x + position[0], part.position.y + position[1], part.position.z + position[2]);
5341
- part.object.rotation.set(part.rotation.x + rotation[0], part.rotation.y + rotation[1], part.rotation.z + rotation[2], part.rotation.order);
5342
- part.object.scale.set(part.scale.x + scale[0], part.scale.y + scale[1], part.scale.z + scale[2]);
5343
- }
5344
- }
5345
- };
5805
+ // src/entity/index.ts
5806
+ init_EntityAnimation();
5346
5807
 
5347
- // src/entity/scene/EntityObject.ts
5348
- init_SceneObject();
5349
- init_Caching();
5350
- var import_ts_deepmerge4 = __toESM(require_dist());
5351
- var import_three13 = require("three");
5352
- init_Ticker();
5353
- init_model();
5354
- init_ModelTextures();
5355
- init_AssetKey();
5356
- init_Materials();
5357
- init_three();
5358
- var EntityObject = class _EntityObject extends SceneObject {
5359
- constructor(entity, options) {
5360
- super();
5361
- this.entity = entity;
5362
- this.isEntityObject = true;
5363
- this.meshesCreated = false;
5364
- this.geometries = /* @__PURE__ */ new Set();
5365
- this.disposeWireframes = [];
5366
- /** Scrolling materials are owned: their texture offset follows this entity's age. */
5367
- this.scrollMaterials = [];
5368
- /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
5369
- this.age = 0;
5370
- this.animationPlayer = new EntityAnimationPlayer();
5371
- this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
5372
- this.addEventListener("added", () => this.updateScrollSubscription());
5373
- this.addEventListener("removed", () => this.updateScrollSubscription());
5374
- }
5375
- static {
5376
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS);
5377
- }
5378
- async init() {
5379
- this.createMeshes();
5380
- await this.applyTextures();
5381
- }
5382
- dispose() {
5383
- super.dispose();
5384
- }
5385
- disposeAndRemoveAllChildren() {
5386
- this.clearScrollMaterials();
5387
- for (const geometry of this.geometries) geometry.dispose();
5388
- this.geometries.clear();
5389
- for (const dispose of this.disposeWireframes.splice(0)) dispose();
5390
- this.animationPlayer.clear();
5391
- super.disposeAndRemoveAllChildren();
5392
- }
5393
- clearScrollMaterials() {
5394
- Ticker.remove(this.scrollTicker);
5395
- this.scrollTicker = void 0;
5396
- for (const { material } of this.scrollMaterials.splice(0)) {
5397
- material.map?.dispose();
5398
- material.dispose();
5399
- }
5400
- }
5401
- updateScrollSubscription() {
5402
- if (this.parent && this.scrollMaterials.length) {
5403
- if (this.scrollTicker === void 0) {
5404
- this.scrollTicker = Ticker.add(() => {
5405
- this.age++;
5406
- this.updateScroll();
5407
- });
5408
- }
5409
- } else {
5410
- Ticker.remove(this.scrollTicker);
5411
- this.scrollTicker = void 0;
5412
- }
5413
- }
5414
- /** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
5415
- updateScroll() {
5416
- for (const { offset, speed } of this.scrollMaterials) {
5417
- offset.set(this.age * speed[0] % 1, 0 - this.age * speed[1] % 1);
5418
- }
5419
- this.notifyDirty();
5420
- }
5421
- //<editor-fold desc="ANIMATION">
5422
- /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
5423
- get animation() {
5424
- return this.animationPlayer.animation;
5425
- }
5426
- /** Seconds since the animation started, before looping. */
5427
- get animationTime() {
5428
- return this.animationPlayer.time;
5429
- }
5430
- /**
5431
- * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
5432
- * Parts of every layer are matched by name and their current pose is the default the offsets add to.
5433
- * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
5434
- */
5435
- playAnimation(animation, options) {
5436
- this.createMeshes();
5437
- const layers = Object.keys(this.entityLayers).map((name) => this.getLayerGroup(name)).filter((layer) => !!layer);
5438
- this.animationPlayer.play(layers, animation, options);
5439
- this.notifyDirty();
5440
- }
5441
- /** Stops the animation and restores the default pose. */
5442
- stopAnimation() {
5443
- if (this.animationPlayer.stop()) this.notifyDirty();
5444
- }
5445
- /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
5446
- setAnimationTime(seconds) {
5447
- if (this.animationPlayer.setTime(seconds)) this.notifyDirty();
5448
- }
5449
- /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
5450
- advanceAnimation(deltaSeconds) {
5451
- if (this.animationPlayer.advance(deltaSeconds)) this.notifyDirty();
5452
- }
5453
- //</editor-fold>
5454
- getLayerGroup(name) {
5455
- return super.getGroupByName(`layer:${name}`);
5456
- }
5457
- getGroupByName(name, layerName) {
5458
- return layerName === void 0 ? super.getGroupByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name}`);
5459
- }
5460
- getMeshByName(name, layerName) {
5461
- return layerName === void 0 ? super.getMeshByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name}`);
5462
- }
5463
- get entityLayers() {
5464
- return this.entity.layers ?? { main: this.entity };
5465
- }
5466
- getTextureKey(layer) {
5467
- if (layer.texture) return layer.texture;
5468
- const key = layer.key;
5469
- return new AssetKey(
5470
- key.namespace,
5471
- isAssetKey(key) ? key.getFullPath() : key.path,
5472
- "textures",
5473
- "entity",
5474
- "assets",
5475
- ".png"
5476
- );
5477
- }
5478
- async loadTextures(layer = this.entity) {
5479
- return ModelTextures.get(this.getTextureKey(layer));
5480
- }
5481
- createMeshes(force = false) {
5482
- if (this.meshesCreated && !force) return;
5483
- const modelRoot = new import_three13.Object3D();
5484
- const transform = this.options.flip === void 0 ? this.entity.transform : void 0;
5485
- if (transform) {
5486
- for (const op of transform) {
5487
- const matrix = new import_three13.Matrix4();
5488
- if ("scale" in op) matrix.makeScale(...op.scale);
5489
- else if ("translate" in op) matrix.makeTranslation(...op.translate);
5490
- else matrix.makeRotationFromEuler(new import_three13.Euler(...op.rotate, "ZYX"));
5491
- modelRoot.matrix.multiply(matrix);
5492
- }
5493
- modelRoot.matrixAutoUpdate = false;
5494
- } else if (this.options.flip ?? true) {
5495
- modelRoot.scale.set(-1, -1, 1);
5496
- }
5497
- this.add(modelRoot);
5498
- Object.entries(this.entityLayers).forEach(([name, layer], index) => {
5499
- const group = this.createGroup(`layer:${name}`);
5500
- modelRoot.add(group);
5501
- const inward = !Materials.entityModeCulls(layer.render ?? layer.layer.render);
5502
- this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index, inward);
5503
- });
5504
- this.meshesCreated = true;
5505
- }
5506
- createPart(name, part, parent, textureSize, material, renderOrder, inward = true) {
5507
- const anchor = this.createGroup(name);
5508
- anchor.position.fromArray(part.pose.offset);
5509
- anchor.rotation.set(...part.pose.rotation, "ZYX");
5510
- anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
5511
- parent.add(anchor);
5512
- const size = part.texture ?? textureSize;
5513
- for (const cube of part.cubes) {
5514
- const [width, height, depth] = cube.size;
5515
- const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
5516
- const texture = new MinecraftCubeTexture(...cube.uv, ...size);
5517
- const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
5518
- const geometry = this._getBoxGeometryForDimensionsAndUv(
5519
- width + growX * 2,
5520
- height + growY * 2,
5521
- depth + growZ * 2,
5522
- uv
5523
- ).clone();
5524
- this.geometries.add(geometry);
5525
- geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
5526
- if (inward && Math.min(width + growX * 2, height + growY * 2, depth + growZ * 2) > 0) {
5527
- const index = Array.from(geometry.getIndex().array);
5528
- geometry.setIndex(index.concat(index.slice().reverse()));
5529
- }
5530
- const mesh = this.createMesh(name, geometry, material);
5531
- mesh.renderOrder = renderOrder;
5532
- anchor.add(mesh);
5533
- if (this.options.wireframe) this.disposeWireframes.push(addWireframeToMesh(geometry, mesh));
5534
- }
5535
- for (const [childName, child] of Object.entries(part.children)) {
5536
- this.createPart(childName, child, anchor, size, material, renderOrder, inward);
5537
- }
5538
- }
5539
- async applyTextures() {
5540
- this.clearScrollMaterials();
5541
- await Promise.all(Object.entries(this.entityLayers).map(async ([name, layer]) => {
5542
- const mode = layer.render ?? layer.layer.render ?? "cutout";
5543
- const tint = layer.tint === void 0 ? void 0 : this.options.tints?.[layer.tint];
5544
- const scroll = Materials.entityModeScroll(mode);
5545
- const assetKeyStr = this.getTextureKey(layer).serialize();
5546
- const keyStr = `entity:${mode}:${tint === void 0 ? "" : new import_three13.Color(tint).getHexString()}:${assetKeyStr}`;
5547
- let mat = scroll ? void 0 : Caching.materialCache.getIfPresent(keyStr);
5548
- if (!mat) {
5549
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
5550
- const imageData = await this.loadTextures(layer);
5551
- if (!imageData) return;
5552
- const canvas = imageData.data.canvas;
5553
- const createMaterial = () => Materials.createEntityCanvasMaterial(canvas, mode, tint);
5554
- mat = !scroll && cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
5555
- if (scroll) {
5556
- this.scrollMaterials.push({ material: mat, offset: mat.map.offset, speed: scroll });
5557
- }
5558
- }
5559
- this.getLayerGroup(name)?.traverse((object) => {
5560
- if (isMesh(object)) object.material = mat;
5561
- });
5562
- }));
5563
- if (!this.children.length) {
5564
- this.clearScrollMaterials();
5565
- } else if (this.scrollMaterials.length) {
5566
- this.updateScroll();
5567
- }
5568
- this.updateScrollSubscription();
5569
- this.notifyDirty();
5570
- }
5571
- };
5572
- function isEntityObject(obj) {
5573
- return obj.isEntityObject;
5574
- }
5808
+ // src/entity/scene/index.ts
5809
+ init_EntityAnimationPlayer();
5810
+ init_EntityObject();
5575
5811
 
5576
5812
  // src/error/index.ts
5577
5813
  init_MineRenderError();
@@ -8147,7 +8383,7 @@ var GuiHelper = class {
8147
8383
  };
8148
8384
 
8149
8385
  // src/gui/scene/GuiObject.ts
8150
- var import_three23 = require("three");
8386
+ var import_three24 = require("three");
8151
8387
  init_AssetKey();
8152
8388
  init_ModelTextures();
8153
8389
  init_Models();
@@ -8156,22 +8392,14 @@ init_SceneObject();
8156
8392
  init_Materials();
8157
8393
  init_ModelObject();
8158
8394
  init_DisplayPosition();
8159
-
8160
- // src/model/GuiLight.ts
8161
- var GuiLight = /* @__PURE__ */ ((GuiLight2) => {
8162
- GuiLight2["FRONT"] = "front";
8163
- GuiLight2["SIDE"] = "side";
8164
- return GuiLight2;
8165
- })(GuiLight || {});
8166
-
8167
- // src/gui/scene/GuiObject.ts
8395
+ init_GuiLight();
8168
8396
  var GuiObject = class extends SceneObject {
8169
8397
  constructor(textureLayers, options) {
8170
8398
  super({ ...options, instanceMeshes: false, mergeMeshes: false });
8171
8399
  this.textureLayers = textureLayers;
8172
8400
  this.isGuiObject = true;
8173
8401
  /** Local bounds in GUI pixels, with y growing down from the origin. */
8174
- this.bounds = new import_three23.Box2();
8402
+ this.bounds = new import_three24.Box2();
8175
8403
  this.geometries = /* @__PURE__ */ new Set();
8176
8404
  this.ownedMaterials = /* @__PURE__ */ new Set();
8177
8405
  this.initialized = false;
@@ -8187,19 +8415,19 @@ var GuiObject = class extends SceneObject {
8187
8415
  const item = await this.createItem(layer, index);
8188
8416
  item.position.set(x + width2 / 2, -y - height2 / 2, 0);
8189
8417
  item.scale.set(width2 / 16, height2 / 16, width2 / 16);
8190
- item.updateMatrix();
8191
- const bounds = new import_three23.Box3();
8418
+ item.updateWorldMatrix(true, true);
8419
+ const inverse = this.matrixWorld.clone().invert();
8420
+ const bounds = new import_three24.Box3();
8192
8421
  item.iterateAllMeshes((mesh2) => {
8193
8422
  mesh2.geometry.computeBoundingBox();
8194
- bounds.union(mesh2.geometry.boundingBox);
8423
+ bounds.union(mesh2.geometry.boundingBox.clone().applyMatrix4(new import_three24.Matrix4().multiplyMatrices(inverse, mesh2.matrixWorld)));
8195
8424
  });
8196
- bounds.applyMatrix4(item.matrix);
8197
8425
  item.position.z = depth - bounds.min.z;
8198
8426
  depth += bounds.max.z - bounds.min.z + 0.01;
8199
- this.bounds.expandByPoint(new import_three23.Vector2(x, y));
8200
- this.bounds.expandByPoint(new import_three23.Vector2(x + width2, y + height2));
8201
- this.bounds.expandByPoint(new import_three23.Vector2(bounds.min.x, -bounds.max.y));
8202
- this.bounds.expandByPoint(new import_three23.Vector2(bounds.max.x, -bounds.min.y));
8427
+ this.bounds.expandByPoint(new import_three24.Vector2(x, y));
8428
+ this.bounds.expandByPoint(new import_three24.Vector2(x + width2, y + height2));
8429
+ this.bounds.expandByPoint(new import_three24.Vector2(bounds.min.x, -bounds.max.y));
8430
+ this.bounds.expandByPoint(new import_three24.Vector2(bounds.max.x, -bounds.min.y));
8203
8431
  continue;
8204
8432
  }
8205
8433
  const key = typeof layer.texture === "string" ? AssetKey.parse("textures", layer.texture) : layer.texture;
@@ -8207,7 +8435,7 @@ var GuiObject = class extends SceneObject {
8207
8435
  const image = material.map.image;
8208
8436
  const [cropX, cropY, cropWidth, cropHeight] = layer.crop ?? [0, 0, image.width, image.height];
8209
8437
  const [width, height] = layer.size ?? [cropWidth, cropHeight];
8210
- const geometry = new import_three23.PlaneGeometry(width, height);
8438
+ const geometry = new import_three24.PlaneGeometry(width, height);
8211
8439
  this.geometries.add(geometry);
8212
8440
  const uv = geometry.getAttribute("uv");
8213
8441
  for (let i = 0; i < uv.count; i++) {
@@ -8217,13 +8445,13 @@ var GuiObject = class extends SceneObject {
8217
8445
  1 - (cropY + (1 - uv.getY(i)) * cropHeight) / image.height
8218
8446
  );
8219
8447
  }
8220
- const mesh = new import_three23.Mesh(geometry, material);
8448
+ const mesh = new import_three24.Mesh(geometry, material);
8221
8449
  mesh.name = `mesh:${layer.name ?? index}`;
8222
8450
  mesh.position.set(x + width / 2, -y - height / 2, depth);
8223
8451
  mesh.renderOrder = index;
8224
8452
  this.add(mesh);
8225
- this.bounds.expandByPoint(new import_three23.Vector2(x, y));
8226
- this.bounds.expandByPoint(new import_three23.Vector2(x + width, y + height));
8453
+ this.bounds.expandByPoint(new import_three24.Vector2(x, y));
8454
+ this.bounds.expandByPoint(new import_three24.Vector2(x + width, y + height));
8227
8455
  depth += 0.01;
8228
8456
  }
8229
8457
  for (const child of this.children) child.position.z -= depth - 0.01;
@@ -8248,7 +8476,7 @@ var GuiObject = class extends SceneObject {
8248
8476
  this.add(item);
8249
8477
  await item.init();
8250
8478
  item.iterateAllMeshes((mesh) => {
8251
- this.geometries.add(mesh.geometry);
8479
+ if (!model.special) this.geometries.add(mesh.geometry);
8252
8480
  mesh.name = `mesh:${layer.name ?? index}`;
8253
8481
  mesh.renderOrder = index;
8254
8482
  for (const material of Array.isArray(mesh.material) ? mesh.material : [mesh.material]) {
@@ -8298,7 +8526,7 @@ function isGuiObject(obj) {
8298
8526
  init_image();
8299
8527
 
8300
8528
  // src/inspector/SceneInspector.ts
8301
- var import_three24 = require("three");
8529
+ var import_three25 = require("three");
8302
8530
  init_SceneObject();
8303
8531
  init_util();
8304
8532
  init_log();
@@ -8308,11 +8536,11 @@ var help = "<span>Ctrl/Cmd+Click to Select<br/></span><br/>";
8308
8536
  var SceneInspector = class {
8309
8537
  constructor(renderer) {
8310
8538
  this.renderer = renderer;
8311
- this.mouse = new import_three24.Vector2();
8539
+ this.mouse = new import_three25.Vector2();
8312
8540
  this.listeners = new AbortController();
8313
8541
  this.objectInfoContainer = document.createElement("div");
8314
8542
  this.objectControlsContainer = document.createElement("div");
8315
- this.raycaster = new import_three24.Raycaster();
8543
+ this.raycaster = new import_three25.Raycaster();
8316
8544
  this.init();
8317
8545
  }
8318
8546
  init() {
@@ -8706,29 +8934,15 @@ function isInstanceable(obj) {
8706
8934
  // src/model/index.ts
8707
8935
  init_DisplayPosition();
8708
8936
  init_DisplayTransforms();
8709
-
8710
- // src/model/Model.ts
8711
- var ITEM_GENERATED = "item/generated";
8712
- var BUILTIN_GENERATED = "builtin/generated";
8713
- var BUILTIN_ENTITY = "builtin/entity";
8714
- var DEFAULT_ELEMENTS = [];
8715
- function isDoubleArray(obj) {
8716
- return Array.isArray(obj) && obj.length === 2;
8717
- }
8718
- function isTripleArray(obj) {
8719
- return Array.isArray(obj) && obj.length === 3;
8720
- }
8721
- function isQuadArray(obj) {
8722
- return Array.isArray(obj) && obj.length === 4;
8723
- }
8724
-
8725
- // src/model/index.ts
8937
+ init_GuiLight();
8938
+ init_Model();
8726
8939
  init_ModelCulling();
8727
8940
  init_ModelGenerator();
8728
8941
  init_ModelMerger();
8942
+ init_SpecialItems();
8729
8943
 
8730
8944
  // src/model/block/BlockStateResolver.ts
8731
- var import_three26 = require("three");
8945
+ var import_three27 = require("three");
8732
8946
  init_BlockStates();
8733
8947
  init_MineRenderError();
8734
8948
  init_util();
@@ -8806,7 +9020,7 @@ var BlockStateResolver = class {
8806
9020
  return variants[variants.length - 1];
8807
9021
  }
8808
9022
  static rotation(variant) {
8809
- const rotation = new import_three26.Euler();
9023
+ const rotation = new import_three27.Euler();
8810
9024
  if (typeof variant.x !== "undefined") {
8811
9025
  rotation.x = toRadians(clampRotationDegrees(variant.x));
8812
9026
  }
@@ -8913,12 +9127,13 @@ init_SceneObject();
8913
9127
  init_ModelObject();
8914
9128
  init_Models();
8915
9129
  var import_ts_deepmerge6 = __toESM(require_dist());
8916
- var import_three29 = require("three");
9130
+ var import_three30 = require("three");
8917
9131
  init_MineRenderError();
8918
9132
  init_InstanceReference();
8919
9133
  init_AssetKey();
8920
9134
  init_ModelCulling();
8921
9135
  init_FluidGeometry();
9136
+ init_Entities();
8922
9137
  var BlockObject = class _BlockObject extends SceneObject {
8923
9138
  constructor(blockState, options) {
8924
9139
  super(options);
@@ -8934,7 +9149,7 @@ var BlockObject = class _BlockObject extends SceneObject {
8934
9149
  this._models = [];
8935
9150
  this._cullMask = 0;
8936
9151
  this._entities = [];
8937
- this._entityPlacement = new import_three29.Matrix4();
9152
+ this._entityPlacement = new import_three30.Matrix4();
8938
9153
  this._entityGeneration = 0;
8939
9154
  this.options = (0, import_ts_deepmerge6.default)({}, _BlockObject.DEFAULT_OPTIONS, options ?? {});
8940
9155
  }
@@ -9019,7 +9234,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9019
9234
  return true;
9020
9235
  }
9021
9236
  placeEntities() {
9022
- const matrix = new import_three29.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
9237
+ const matrix = new import_three30.Matrix4().makeTranslation(this.position.x - 8, this.position.y - 8, this.position.z - 8).multiply(this._entityPlacement);
9023
9238
  for (const entity of this._entities) {
9024
9239
  matrix.decompose(entity.position, entity.quaternion, entity.scale);
9025
9240
  }
@@ -9038,12 +9253,12 @@ var BlockObject = class _BlockObject extends SceneObject {
9038
9253
  getModelCullMask(model, worldMask) {
9039
9254
  const object = isInstanceReference(model) ? model.instanceable : model;
9040
9255
  if (object.options.displayPosition) return 0;
9041
- const position = new import_three29.Vector3();
9042
- const rotation = new import_three29.Quaternion();
9043
- const scale = new import_three29.Vector3();
9256
+ const position = new import_three30.Vector3();
9257
+ const rotation = new import_three30.Quaternion();
9258
+ const scale = new import_three30.Vector3();
9044
9259
  this.getModelMatrix(model).decompose(position, rotation, scale);
9045
- if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three29.Vector3(1, 1, 1)) > 1e-10) return 0;
9046
- return ModelCulling.toLocalMask(worldMask, new import_three29.Euler().setFromQuaternion(rotation));
9260
+ if (position.distanceToSquared(this.position) > 1e-10 || scale.distanceToSquared(new import_three30.Vector3(1, 1, 1)) > 1e-10) return 0;
9261
+ return ModelCulling.toLocalMask(worldMask, new import_three30.Euler().setFromQuaternion(rotation));
9047
9262
  }
9048
9263
  async setCullMask(worldMask) {
9049
9264
  worldMask &= 63;
@@ -9105,7 +9320,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9105
9320
  () => new FluidModelObject2(kind, surface.sample, this.blockState.key, this.options)
9106
9321
  );
9107
9322
  const previous = this._fluidModel;
9108
- const matrix = previous ? this.getModelMatrix(previous) : new import_three29.Matrix4().makeTranslation(...this.position.toArray());
9323
+ const matrix = previous ? this.getModelMatrix(previous) : new import_three30.Matrix4().makeTranslation(...this.position.toArray());
9109
9324
  if (isInstanceReference(replacement)) replacement.setMatrix(matrix);
9110
9325
  else matrix.decompose(replacement.position, replacement.quaternion, replacement.scale);
9111
9326
  this._models = this._models.filter((model) => model !== previous);
@@ -9243,7 +9458,7 @@ var BlockObject = class _BlockObject extends SceneObject {
9243
9458
  setPositionRotationScaleAt(index, position, rotation, scale) {
9244
9459
  super.setPositionRotationScaleAt(index, position, rotation, scale);
9245
9460
  }
9246
- getMatrixAt(index, matrix = new import_three29.Matrix4()) {
9461
+ getMatrixAt(index, matrix = new import_three30.Matrix4()) {
9247
9462
  if (!this.isInstanced) throw new MineRenderError("Object is not instanced");
9248
9463
  const child = this._models[0];
9249
9464
  if (child && isModelObject(child)) {
@@ -11110,7 +11325,7 @@ init_ModelObject();
11110
11325
  init_nbt();
11111
11326
 
11112
11327
  // src/renderer/MineRenderScene.ts
11113
- var import_three31 = require("three");
11328
+ var import_three32 = require("three");
11114
11329
  init_SceneObject();
11115
11330
  var import_ts_deepmerge8 = __toESM(require_dist());
11116
11331
  init_ModelObject();
@@ -11843,7 +12058,7 @@ var import_ts_deepmerge7 = __toESM(require_dist());
11843
12058
  init_util();
11844
12059
 
11845
12060
  // src/skin/SkinTextures.ts
11846
- var import_three30 = require("three");
12061
+ var import_three31 = require("three");
11847
12062
  init_Caching();
11848
12063
  init_CacheKey();
11849
12064
  init_MineRenderError();
@@ -11927,11 +12142,11 @@ var SkinTextures = class {
11927
12142
  });
11928
12143
  }
11929
12144
  static createMaterial(pixels, width, height, transparent = true) {
11930
- const texture = Textures.initTextureProps(new import_three30.DataTexture(pixels, width, height));
11931
- texture.colorSpace = import_three30.SRGBColorSpace;
12145
+ const texture = Textures.initTextureProps(new import_three31.DataTexture(pixels, width, height));
12146
+ texture.colorSpace = import_three31.SRGBColorSpace;
11932
12147
  texture.flipY = true;
11933
12148
  texture.needsUpdate = true;
11934
- return new import_three30.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three30.DoubleSide : import_three30.FrontSide, alphaTest: transparent ? 0.1 : 0 });
12149
+ return new import_three31.MeshBasicMaterial({ map: texture, transparent, side: transparent ? import_three31.DoubleSide : import_three31.FrontSide, alphaTest: transparent ? 0.1 : 0 });
11935
12150
  }
11936
12151
  static isSlim(image, scale) {
11937
12152
  for (const [x, y] of [[46, 52], [54, 20]]) {
@@ -12159,7 +12374,8 @@ var SkinObject = class extends SceneObject {
12159
12374
  };
12160
12375
 
12161
12376
  // src/renderer/MineRenderScene.ts
12162
- var MineRenderScene = class _MineRenderScene extends import_three31.Scene {
12377
+ init_EntityObject();
12378
+ var MineRenderScene = class _MineRenderScene extends import_three32.Scene {
12163
12379
  constructor(options) {
12164
12380
  super();
12165
12381
  this.isMineRenderScene = true;
@@ -12287,19 +12503,20 @@ function isMineRenderScene(obj) {
12287
12503
  }
12288
12504
 
12289
12505
  // src/renderer/Renderer.ts
12290
- var import_three33 = require("three");
12506
+ var import_three34 = require("three");
12291
12507
  var import_ts_deepmerge9 = __toESM(require_dist());
12292
12508
  var import_stats = __toESM(require("stats.js"));
12293
12509
  var import_postprocessing = require("postprocessing");
12294
12510
  init_util();
12511
+ init_Model();
12295
12512
  init_three();
12296
12513
 
12297
12514
  // src/three/OrbitControls.js
12298
- var import_three32 = require("three");
12515
+ var import_three33 = require("three");
12299
12516
  var _changeEvent = { type: "change" };
12300
12517
  var _startEvent = { type: "start" };
12301
12518
  var _endEvent = { type: "end" };
12302
- var OrbitControls = class extends import_three32.EventDispatcher {
12519
+ var OrbitControls = class extends import_three33.EventDispatcher {
12303
12520
  constructor(object, domElement) {
12304
12521
  super();
12305
12522
  if (domElement === void 0) console.warn('THREE.OrbitControls: The second parameter "domElement" is now mandatory.');
@@ -12308,7 +12525,7 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12308
12525
  this.domElement = domElement;
12309
12526
  this.domElement.style.touchAction = "none";
12310
12527
  this.enabled = true;
12311
- this.target = new import_three32.Vector3();
12528
+ this.target = new import_three33.Vector3();
12312
12529
  this.minDistance = 0;
12313
12530
  this.maxDistance = Infinity;
12314
12531
  this.minZoom = 0;
@@ -12330,8 +12547,8 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12330
12547
  this.autoRotate = false;
12331
12548
  this.autoRotateSpeed = 2;
12332
12549
  this.keys = { LEFT: "ArrowLeft", UP: "ArrowUp", RIGHT: "ArrowRight", BOTTOM: "ArrowDown" };
12333
- this.mouseButtons = { LEFT: import_three32.MOUSE.ROTATE, MIDDLE: import_three32.MOUSE.DOLLY, RIGHT: import_three32.MOUSE.PAN };
12334
- this.touches = { ONE: import_three32.TOUCH.ROTATE, TWO: import_three32.TOUCH.DOLLY_PAN };
12550
+ this.mouseButtons = { LEFT: import_three33.MOUSE.ROTATE, MIDDLE: import_three33.MOUSE.DOLLY, RIGHT: import_three33.MOUSE.PAN };
12551
+ this.touches = { ONE: import_three33.TOUCH.ROTATE, TWO: import_three33.TOUCH.DOLLY_PAN };
12335
12552
  this.target0 = this.target.clone();
12336
12553
  this.position0 = this.object.position.clone();
12337
12554
  this.zoom0 = this.object.zoom;
@@ -12360,11 +12577,11 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12360
12577
  state = STATE.NONE;
12361
12578
  };
12362
12579
  this.update = function() {
12363
- const offset = new import_three32.Vector3();
12364
- const quat = new import_three32.Quaternion().setFromUnitVectors(object.up, new import_three32.Vector3(0, 1, 0));
12580
+ const offset = new import_three33.Vector3();
12581
+ const quat = new import_three33.Quaternion().setFromUnitVectors(object.up, new import_three33.Vector3(0, 1, 0));
12365
12582
  const quatInverse = quat.clone().invert();
12366
- const lastPosition = new import_three32.Vector3();
12367
- const lastQuaternion = new import_three32.Quaternion();
12583
+ const lastPosition = new import_three33.Vector3();
12584
+ const lastQuaternion = new import_three33.Quaternion();
12368
12585
  const twoPI = 2 * Math.PI;
12369
12586
  return function update() {
12370
12587
  const position = scope.object.position;
@@ -12450,20 +12667,20 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12450
12667
  };
12451
12668
  let state = STATE.NONE;
12452
12669
  const EPS = 1e-6;
12453
- const spherical = new import_three32.Spherical();
12454
- const sphericalDelta = new import_three32.Spherical();
12670
+ const spherical = new import_three33.Spherical();
12671
+ const sphericalDelta = new import_three33.Spherical();
12455
12672
  let scale = 1;
12456
- const panOffset = new import_three32.Vector3();
12673
+ const panOffset = new import_three33.Vector3();
12457
12674
  let zoomChanged = false;
12458
- const rotateStart = new import_three32.Vector2();
12459
- const rotateEnd = new import_three32.Vector2();
12460
- const rotateDelta = new import_three32.Vector2();
12461
- const panStart = new import_three32.Vector2();
12462
- const panEnd = new import_three32.Vector2();
12463
- const panDelta = new import_three32.Vector2();
12464
- const dollyStart = new import_three32.Vector2();
12465
- const dollyEnd = new import_three32.Vector2();
12466
- const dollyDelta = new import_three32.Vector2();
12675
+ const rotateStart = new import_three33.Vector2();
12676
+ const rotateEnd = new import_three33.Vector2();
12677
+ const rotateDelta = new import_three33.Vector2();
12678
+ const panStart = new import_three33.Vector2();
12679
+ const panEnd = new import_three33.Vector2();
12680
+ const panDelta = new import_three33.Vector2();
12681
+ const dollyStart = new import_three33.Vector2();
12682
+ const dollyEnd = new import_three33.Vector2();
12683
+ const dollyDelta = new import_three33.Vector2();
12467
12684
  const pointers = [];
12468
12685
  const pointerPositions = {};
12469
12686
  function getAutoRotationAngle() {
@@ -12479,7 +12696,7 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12479
12696
  sphericalDelta.phi -= angle;
12480
12697
  }
12481
12698
  const panLeft = function() {
12482
- const v = new import_three32.Vector3();
12699
+ const v = new import_three33.Vector3();
12483
12700
  return function panLeft2(distance, objectMatrix) {
12484
12701
  v.setFromMatrixColumn(objectMatrix, 0);
12485
12702
  v.multiplyScalar(-distance);
@@ -12487,7 +12704,7 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12487
12704
  };
12488
12705
  }();
12489
12706
  const panUp = function() {
12490
- const v = new import_three32.Vector3();
12707
+ const v = new import_three33.Vector3();
12491
12708
  return function panUp2(distance, objectMatrix) {
12492
12709
  if (scope.screenSpacePanning === true) {
12493
12710
  v.setFromMatrixColumn(objectMatrix, 1);
@@ -12500,7 +12717,7 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12500
12717
  };
12501
12718
  }();
12502
12719
  const pan = function() {
12503
- const offset = new import_three32.Vector3();
12720
+ const offset = new import_three33.Vector3();
12504
12721
  return function pan2(deltaX, deltaY) {
12505
12722
  const element = scope.domElement;
12506
12723
  if (scope.object.isPerspectiveCamera) {
@@ -12749,12 +12966,12 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12749
12966
  mouseAction = -1;
12750
12967
  }
12751
12968
  switch (mouseAction) {
12752
- case import_three32.MOUSE.DOLLY:
12969
+ case import_three33.MOUSE.DOLLY:
12753
12970
  if (scope.enableZoom === false) return;
12754
12971
  handleMouseDownDolly(event);
12755
12972
  state = STATE.DOLLY;
12756
12973
  break;
12757
- case import_three32.MOUSE.ROTATE:
12974
+ case import_three33.MOUSE.ROTATE:
12758
12975
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
12759
12976
  if (scope.enablePan === false) return;
12760
12977
  handleMouseDownPan(event);
@@ -12765,7 +12982,7 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12765
12982
  state = STATE.ROTATE;
12766
12983
  }
12767
12984
  break;
12768
- case import_three32.MOUSE.PAN:
12985
+ case import_three33.MOUSE.PAN:
12769
12986
  if (event.ctrlKey || event.metaKey || event.shiftKey) {
12770
12987
  if (scope.enableRotate === false) return;
12771
12988
  handleMouseDownRotate(event);
@@ -12821,12 +13038,12 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12821
13038
  switch (pointers.length) {
12822
13039
  case 1:
12823
13040
  switch (scope.touches.ONE) {
12824
- case import_three32.TOUCH.ROTATE:
13041
+ case import_three33.TOUCH.ROTATE:
12825
13042
  if (scope.enableRotate === false) return;
12826
13043
  handleTouchStartRotate();
12827
13044
  state = STATE.TOUCH_ROTATE;
12828
13045
  break;
12829
- case import_three32.TOUCH.PAN:
13046
+ case import_three33.TOUCH.PAN:
12830
13047
  if (scope.enablePan === false) return;
12831
13048
  handleTouchStartPan();
12832
13049
  state = STATE.TOUCH_PAN;
@@ -12837,12 +13054,12 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12837
13054
  break;
12838
13055
  case 2:
12839
13056
  switch (scope.touches.TWO) {
12840
- case import_three32.TOUCH.DOLLY_PAN:
13057
+ case import_three33.TOUCH.DOLLY_PAN:
12841
13058
  if (scope.enableZoom === false && scope.enablePan === false) return;
12842
13059
  handleTouchStartDollyPan();
12843
13060
  state = STATE.TOUCH_DOLLY_PAN;
12844
13061
  break;
12845
- case import_three32.TOUCH.DOLLY_ROTATE:
13062
+ case import_three33.TOUCH.DOLLY_ROTATE:
12846
13063
  if (scope.enableZoom === false && scope.enableRotate === false) return;
12847
13064
  handleTouchStartDollyRotate();
12848
13065
  state = STATE.TOUCH_DOLLY_ROTATE;
@@ -12909,7 +13126,7 @@ var OrbitControls = class extends import_three32.EventDispatcher {
12909
13126
  function trackPointer(event) {
12910
13127
  let position = pointerPositions[event.pointerId];
12911
13128
  if (position === void 0) {
12912
- position = new import_three32.Vector2();
13129
+ position = new import_three33.Vector2();
12913
13130
  pointerPositions[event.pointerId] = position;
12914
13131
  }
12915
13132
  position.set(event.pageX, event.pageY);
@@ -12929,10 +13146,10 @@ var MapControls = class extends OrbitControls {
12929
13146
  constructor(object, domElement) {
12930
13147
  super(object, domElement);
12931
13148
  this.screenSpacePanning = false;
12932
- this.mouseButtons.LEFT = import_three32.MOUSE.PAN;
12933
- this.mouseButtons.RIGHT = import_three32.MOUSE.ROTATE;
12934
- this.touches.ONE = import_three32.TOUCH.PAN;
12935
- this.touches.TWO = import_three32.TOUCH.DOLLY_ROTATE;
13149
+ this.mouseButtons.LEFT = import_three33.MOUSE.PAN;
13150
+ this.mouseButtons.RIGHT = import_three33.MOUSE.ROTATE;
13151
+ this.touches.ONE = import_three33.TOUCH.PAN;
13152
+ this.touches.TWO = import_three33.TOUCH.DOLLY_ROTATE;
12936
13153
  }
12937
13154
  };
12938
13155
 
@@ -12991,8 +13208,8 @@ var Renderer = class _Renderer {
12991
13208
  top: void 0,
12992
13209
  bottom: void 0
12993
13210
  },
12994
- position: new import_three33.Vector3(50, 50, 50),
12995
- lookingAt: new import_three33.Vector3(0, 0, 0)
13211
+ position: new import_three34.Vector3(50, 50, 50),
13212
+ lookingAt: new import_three34.Vector3(0, 0, 0)
12996
13213
  },
12997
13214
  render: {
12998
13215
  fpsLimit: 60,
@@ -13023,14 +13240,14 @@ var Renderer = class _Renderer {
13023
13240
  switch (this.options.camera.type) {
13024
13241
  case "perspective":
13025
13242
  default:
13026
- return new import_three33.PerspectiveCamera(
13243
+ return new import_three34.PerspectiveCamera(
13027
13244
  this.options.camera.perspective.fov,
13028
13245
  this.options.camera.perspective.aspect ?? this.viewWidth / this.viewHeight,
13029
13246
  this.options.camera.near,
13030
13247
  this.options.camera.far
13031
13248
  );
13032
13249
  case "orthographic":
13033
- return new import_three33.OrthographicCamera(
13250
+ return new import_three34.OrthographicCamera(
13034
13251
  this.options.camera.orthographic.left ?? this.viewWidth / -2,
13035
13252
  this.options.camera.orthographic.right ?? this.viewWidth / 2,
13036
13253
  this.options.camera.orthographic.top ?? this.viewHeight / 2,
@@ -13041,7 +13258,7 @@ var Renderer = class _Renderer {
13041
13258
  }
13042
13259
  }
13043
13260
  createRenderer() {
13044
- const renderer = new import_three33.WebGLRenderer({
13261
+ const renderer = new import_three34.WebGLRenderer({
13045
13262
  antialias: this.options.render.antialias,
13046
13263
  alpha: true,
13047
13264
  powerPreference: "high-performance",
@@ -13049,8 +13266,8 @@ var Renderer = class _Renderer {
13049
13266
  });
13050
13267
  renderer.setClearColor(0, 0);
13051
13268
  renderer.shadowMap.enabled = true;
13052
- renderer.shadowMap.type = import_three33.PCFSoftShadowMap;
13053
- renderer.outputColorSpace = import_three33.SRGBColorSpace;
13269
+ renderer.shadowMap.type = import_three34.PCFSoftShadowMap;
13270
+ renderer.outputColorSpace = import_three34.SRGBColorSpace;
13054
13271
  renderer.setPixelRatio(this.options.render.pixelRatio ?? 1);
13055
13272
  renderer.setSize(this.viewWidth, this.viewHeight);
13056
13273
  return renderer;
@@ -13085,20 +13302,20 @@ var Renderer = class _Renderer {
13085
13302
  window["__THREE_DEVTOOLS__"].dispatchEvent(new CustomEvent("observe", { detail: this.scene }));
13086
13303
  }
13087
13304
  if (this.options.debug.grid) {
13088
- const gridHelper = new import_three33.GridHelper(128, 16);
13305
+ const gridHelper = new import_three34.GridHelper(128, 16);
13089
13306
  this._debugHelpers.push(gridHelper);
13090
13307
  this.scene.add(gridHelper);
13091
- const gridHelper2 = new import_three33.GridHelper(128, 16);
13308
+ const gridHelper2 = new import_three34.GridHelper(128, 16);
13092
13309
  this._debugHelpers.push(gridHelper2);
13093
13310
  gridHelper2.rotation.x = 90 * (Math.PI / 180);
13094
13311
  this.scene.add(gridHelper2);
13095
- const gridHelper3 = new import_three33.GridHelper(128, 16);
13312
+ const gridHelper3 = new import_three34.GridHelper(128, 16);
13096
13313
  this._debugHelpers.push(gridHelper3);
13097
13314
  gridHelper3.rotation.z = 90 * (Math.PI / 180);
13098
13315
  this.scene.add(gridHelper3);
13099
13316
  }
13100
13317
  if (this.options.debug.axes) {
13101
- const axesHelper = new import_three33.AxesHelper(64);
13318
+ const axesHelper = new import_three34.AxesHelper(64);
13102
13319
  this._debugHelpers.push(axesHelper);
13103
13320
  this.scene.add(axesHelper);
13104
13321
  }
@@ -13783,19 +14000,20 @@ var AnvilParser = class {
13783
14000
  };
13784
14001
 
13785
14002
  // src/world/Chunk.ts
13786
- var import_three38 = require("three");
14003
+ var import_three39 = require("three");
13787
14004
  init_BlockStates();
13788
14005
  init_AssetKey();
13789
14006
 
13790
14007
  // src/world/MineRenderWorld.ts
13791
- var import_three36 = require("three");
14008
+ var import_three37 = require("three");
14009
+ init_Model();
13792
14010
  init_BatchedExecutor();
13793
14011
  init_AssetKey();
13794
14012
  init_BlockStates();
13795
14013
  init_CubeFace();
13796
14014
 
13797
14015
  // src/world/SectionModels.ts
13798
- var import_three35 = require("three");
14016
+ var import_three36 = require("three");
13799
14017
  init_AssetKey();
13800
14018
  init_Models();
13801
14019
  init_CubeFace();
@@ -13861,12 +14079,12 @@ var SectionModels = class {
13861
14079
  });
13862
14080
  await object.init();
13863
14081
  const geometry = object.children[0].geometry;
13864
- geometry.applyMatrix4(new import_three35.Matrix4().makeRotationFromEuler(rotation));
14082
+ geometry.applyMatrix4(new import_three36.Matrix4().makeRotationFromEuler(rotation));
13865
14083
  object.clear();
13866
14084
  const cullFaces = CUBE_FACES.map((face) => {
13867
14085
  const local = CUBE_FACES.findIndex((name) => name === atlas.model.elements[0].faces[face]?.cullface);
13868
14086
  if (local < 0) return 0;
13869
- const normal = new import_three35.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
14087
+ const normal = new import_three36.Vector3(...CUBE_FACE_OFFSETS[local]).applyEuler(rotation);
13870
14088
  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);
13871
14089
  return 1 << world;
13872
14090
  });
@@ -13896,20 +14114,20 @@ var MineRenderWorld = class {
13896
14114
  }
13897
14115
  getBlockAt(posOrX, y, z) {
13898
14116
  if (typeof posOrX == "number") {
13899
- return this.getBlockAt(new import_three36.Vector3(posOrX, y, z));
14117
+ return this.getBlockAt(new import_three37.Vector3(posOrX, y, z));
13900
14118
  }
13901
14119
  if (isTripleArray(posOrX)) {
13902
- return this.getBlockAt(new import_three36.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14120
+ return this.getBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]));
13903
14121
  }
13904
14122
  this.validatePosBounds(posOrX);
13905
14123
  return this.getChunkAt(posOrX)?.getBlockAt(posOrX);
13906
14124
  }
13907
14125
  async setBlockAt(posOrX, yOrBlock, z, block) {
13908
14126
  if (typeof posOrX == "number") {
13909
- return this.setBlockAt(new import_three36.Vector3(posOrX, yOrBlock, z), block);
14127
+ return this.setBlockAt(new import_three37.Vector3(posOrX, yOrBlock, z), block);
13910
14128
  }
13911
14129
  if (isTripleArray(posOrX)) {
13912
- return this.setBlockAt(new import_three36.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14130
+ return this.setBlockAt(new import_three37.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
13913
14131
  }
13914
14132
  return this.placeBlock(posOrX, yOrBlock);
13915
14133
  }
@@ -13930,7 +14148,7 @@ var MineRenderWorld = class {
13930
14148
  const collect = async (positions2) => {
13931
14149
  for (const pos of positions2) changes.set(pos.toArray().join(","), pos);
13932
14150
  };
13933
- const place = (block) => this.placeBlock(new import_three36.Vector3(...block.position), block, collect);
14151
+ const place = (block) => this.placeBlock(new import_three37.Vector3(...block.position), block, collect);
13934
14152
  const keys = /* @__PURE__ */ new Map();
13935
14153
  for (const block of multiblock.blocks) {
13936
14154
  if (Chunk.isAir(block)) continue;
@@ -14008,13 +14226,13 @@ var MineRenderWorld = class {
14008
14226
  for (const pos of positions) {
14009
14227
  this.pendingCulling.set(pos.toArray().join(","), pos.clone());
14010
14228
  for (const offset of CUBE_FACE_OFFSETS) {
14011
- const neighbor = pos.clone().add(new import_three36.Vector3(...offset));
14229
+ const neighbor = pos.clone().add(new import_three37.Vector3(...offset));
14012
14230
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14013
14231
  }
14014
14232
  for (let y = -1; y <= 1; y++) {
14015
14233
  for (let z = -1; z <= 1; z++) {
14016
14234
  for (let x = -1; x <= 1; x++) {
14017
- const neighbor = pos.clone().add(new import_three36.Vector3(x, y, z));
14235
+ const neighbor = pos.clone().add(new import_three37.Vector3(x, y, z));
14018
14236
  if (this.getBlockAt(neighbor)?.object?.fluidKind) {
14019
14237
  this.pendingCulling.set(neighbor.toArray().join(","), neighbor);
14020
14238
  }
@@ -14036,7 +14254,7 @@ var MineRenderWorld = class {
14036
14254
  if (!block) continue;
14037
14255
  if (block.object?.fluidKind) {
14038
14256
  await block.object.updateFluid((x, y, z) => {
14039
- const neighbor = pos.clone().add(new import_three36.Vector3(x, y, z));
14257
+ const neighbor = pos.clone().add(new import_three37.Vector3(x, y, z));
14040
14258
  const section = this.getChunkAt(neighbor);
14041
14259
  const object = section?.getBlockAt(neighbor)?.object;
14042
14260
  return {
@@ -14048,7 +14266,7 @@ var MineRenderWorld = class {
14048
14266
  }
14049
14267
  let mask = 0;
14050
14268
  for (const [face, offset] of CUBE_FACE_OFFSETS.entries()) {
14051
- const neighbor = pos.clone().add(new import_three36.Vector3(...offset));
14269
+ const neighbor = pos.clone().add(new import_three37.Vector3(...offset));
14052
14270
  if (this.getChunkAt(neighbor)?.isOccludingAt(neighbor)) {
14053
14271
  mask |= 1 << face;
14054
14272
  }
@@ -14082,14 +14300,14 @@ var MineRenderWorld = class {
14082
14300
  return this._chunks.get(this.worldPosToChunkKey(pos));
14083
14301
  }
14084
14302
  static worldToScenePosition(pos) {
14085
- return new import_three36.Vector3(
14303
+ return new import_three37.Vector3(
14086
14304
  pos.x * 16,
14087
14305
  pos.y * 16,
14088
14306
  pos.z * 16
14089
14307
  );
14090
14308
  }
14091
14309
  static sceneToWorldPosition(pos) {
14092
- return new import_three36.Vector3(
14310
+ return new import_three37.Vector3(
14093
14311
  pos.x / 16,
14094
14312
  pos.y / 16,
14095
14313
  pos.z / 16
@@ -14108,11 +14326,14 @@ var MineRenderWorld = class {
14108
14326
  }
14109
14327
  };
14110
14328
 
14329
+ // src/world/Chunk.ts
14330
+ init_Model();
14331
+
14111
14332
  // src/world/SectionMesh.ts
14112
- var import_three37 = require("three");
14333
+ var import_three38 = require("three");
14113
14334
  init_CanvasCompat();
14114
14335
  init_Materials();
14115
- var SectionMesh = class _SectionMesh extends import_three37.Group {
14336
+ var SectionMesh = class _SectionMesh extends import_three38.Group {
14116
14337
  constructor() {
14117
14338
  super(...arguments);
14118
14339
  this.ownedMeshes = [];
@@ -14185,18 +14406,18 @@ var SectionMesh = class _SectionMesh extends import_three37.Group {
14185
14406
  for (let corner = 0; corner < 6; corner++) indices.push(start + sourceIndices.getX(face * 6 + corner) - face * 4);
14186
14407
  }
14187
14408
  }
14188
- const geometry = new import_three37.BufferGeometry();
14189
- geometry.setAttribute("position", new import_three37.Float32BufferAttribute(positions, 3));
14190
- geometry.setAttribute("normal", new import_three37.Float32BufferAttribute(normals, 3));
14191
- geometry.setAttribute("uv", new import_three37.Float32BufferAttribute(uvs, 2));
14192
- geometry.setAttribute("color", new import_three37.Float32BufferAttribute(colors, 3));
14409
+ const geometry = new import_three38.BufferGeometry();
14410
+ geometry.setAttribute("position", new import_three38.Float32BufferAttribute(positions, 3));
14411
+ geometry.setAttribute("normal", new import_three38.Float32BufferAttribute(normals, 3));
14412
+ geometry.setAttribute("uv", new import_three38.Float32BufferAttribute(uvs, 2));
14413
+ geometry.setAttribute("color", new import_three38.Float32BufferAttribute(colors, 3));
14193
14414
  geometry.setIndex(indices);
14194
14415
  geometry.computeBoundingBox();
14195
14416
  geometry.computeBoundingSphere();
14196
14417
  const material = Materials.createShadedCanvasMaterial(canvas, false);
14197
14418
  material.vertexColors = true;
14198
14419
  const texture = material.uniforms?.map?.value ?? material.map;
14199
- const mesh = new import_three37.Mesh(geometry, material);
14420
+ const mesh = new import_three38.Mesh(geometry, material);
14200
14421
  section.add(mesh);
14201
14422
  section.ownedMeshes.push({ mesh, texture });
14202
14423
  }
@@ -14230,10 +14451,10 @@ var Chunk = class _Chunk {
14230
14451
  }
14231
14452
  getBlockAt(posOrX, y, z) {
14232
14453
  if (typeof posOrX == "number") {
14233
- return this.getBlockAt(new import_three38.Vector3(posOrX, y, z));
14454
+ return this.getBlockAt(new import_three39.Vector3(posOrX, y, z));
14234
14455
  }
14235
14456
  if (isTripleArray(posOrX)) {
14236
- return this.getBlockAt(new import_three38.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14457
+ return this.getBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]));
14237
14458
  }
14238
14459
  const pos = this.worldPosToChunkPos(posOrX);
14239
14460
  const index = _Chunk.chunkPosToBlockIndex(pos);
@@ -14241,10 +14462,10 @@ var Chunk = class _Chunk {
14241
14462
  }
14242
14463
  async setBlockAt(posOrX, yOrBlock, z, block) {
14243
14464
  if (typeof posOrX == "number") {
14244
- return this.setBlockAt(new import_three38.Vector3(posOrX, yOrBlock, z), block);
14465
+ return this.setBlockAt(new import_three39.Vector3(posOrX, yOrBlock, z), block);
14245
14466
  }
14246
14467
  if (isTripleArray(posOrX)) {
14247
- return this.setBlockAt(new import_three38.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14468
+ return this.setBlockAt(new import_three39.Vector3(posOrX[0], posOrX[1], posOrX[2]), yOrBlock);
14248
14469
  }
14249
14470
  const worldPos = posOrX;
14250
14471
  const pos = this.worldPosToChunkPos(worldPos);
@@ -14330,7 +14551,7 @@ var Chunk = class _Chunk {
14330
14551
  }
14331
14552
  async clear(onBlocksChanged = this.onBlocksChanged) {
14332
14553
  const positions = [...this.renderedBlocks.keys()].map((index) => this.chunkPosToWorldPos(
14333
- new import_three38.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
14554
+ new import_three39.Vector3(index % 16, Math.floor(index / 256), Math.floor(index / 16) % 16)
14334
14555
  ));
14335
14556
  for (const info of this.renderedBlocks.values()) info.object?.removeFromScene();
14336
14557
  this.sectionBlocks.clear();
@@ -14354,14 +14575,14 @@ var Chunk = class _Chunk {
14354
14575
  return pos.y * 16 * 16 + pos.z * 16 + pos.x;
14355
14576
  }
14356
14577
  worldPosToChunkPos(pos) {
14357
- return new import_three38.Vector3(
14578
+ return new import_three39.Vector3(
14358
14579
  pos.x - this.x * 16,
14359
14580
  pos.y - this.y * 16,
14360
14581
  pos.z - this.z * 16
14361
14582
  );
14362
14583
  }
14363
14584
  chunkPosToWorldPos(pos) {
14364
- return new import_three38.Vector3(
14585
+ return new import_three39.Vector3(
14365
14586
  this.x * 16 + pos.x,
14366
14587
  this.y * 16 + pos.y,
14367
14588
  this.z * 16 + pos.z
@@ -14457,6 +14678,7 @@ var Chunk = class _Chunk {
14457
14678
  SkinPart,
14458
14679
  SkinTextures,
14459
14680
  Skins,
14681
+ SpecialItems,
14460
14682
  StructureParser,
14461
14683
  TextureAtlas,
14462
14684
  TextureLoader,