minerender 2.1.0-alpha.6 → 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.
@@ -1,21 +1,22 @@
1
1
  import * as three from 'three';
2
- import { Vector3, PixelFormat, BoxGeometry, Material, Mesh, Euler, Vector2, BufferAttribute, Float32BufferAttribute, BufferGeometry, Object3D, Box3, InstancedMesh, PerspectiveCamera, OrthographicCamera, Matrix4, Scene, Object3DEventMap, Texture, Camera, MOUSE, TOUCH, WebGLRenderer, EventDispatcher, Raycaster, Intersection, CanvasTexture, InterleavedBufferAttribute, TrianglesDrawModes, Line, Points } from 'three';
2
+ import { Vector3, PixelFormat, BoxGeometry, Material, ColorRepresentation, MeshBasicMaterial, Mesh, Euler, Vector2, BufferAttribute, Float32BufferAttribute, BufferGeometry, Object3D, Box3, InstancedMesh, PerspectiveCamera, OrthographicCamera, Matrix4, Box2, Scene, Object3DEventMap, Texture, Camera, MOUSE, TOUCH, WebGLRenderer, EventDispatcher, Raycaster, Intersection, CanvasTexture, InterleavedBufferAttribute, TrianglesDrawModes, Line, Points, Group } from 'three';
3
3
  import * as nodeCanvas from 'canvas';
4
4
  import { ImageData as ImageData$1, CanvasRenderingContext2D } from 'canvas';
5
- import { AxiosResponse, AxiosRequestConfig } from 'axios';
6
- import { Buffer as Buffer$1 } from 'buffer';
7
- import { NBT } from 'prismarine-nbt';
5
+ import { Buffer } from 'buffer';
6
+ import { NBT, NBTFormat, Metadata } from 'prismarine-nbt';
8
7
  import { ZipReader } from '@zip.js/zip.js';
9
8
  import { AsyncLoadingCache, SimpleCache } from '@inventivetalent/loading-cache';
9
+ import { PLYExporterOptions } from 'three/examples/jsm/exporters/PLYExporter.js';
10
+ export { PLYExporterOptions } from 'three/examples/jsm/exporters/PLYExporter.js';
10
11
  import Stats from 'stats.js';
11
12
  import { EffectComposer } from 'postprocessing';
12
13
 
13
14
  interface AnimatorFunction {
14
- (): void;
15
+ (): boolean | void;
15
16
  }
16
17
 
17
18
  declare enum Axis {
18
- X = "X",
19
+ X = "x",
19
20
  Y = "y",
20
21
  Z = "z"
21
22
  }
@@ -39,6 +40,7 @@ declare enum CubeFaceIndex {
39
40
  NORTH = 5
40
41
  }
41
42
  declare const CUBE_FACES: CubeFace[];
43
+ declare const CUBE_FACE_OFFSETS: readonly [readonly [1, 0, 0], readonly [-1, 0, 0], readonly [0, 1, 0], readonly [0, -1, 0], readonly [0, 0, 1], readonly [0, 0, -1]];
42
44
 
43
45
  interface Disposable {
44
46
  dispose(): void;
@@ -64,6 +66,7 @@ declare abstract class PersistentCache<B = unknown> {
64
66
  static open(name: string): PersistentCache;
65
67
  protected constructor(backing: B);
66
68
  abstract get<T>(key: string): Promise<T>;
69
+ /** Loads a missing entry and stores only non-nullish results. */
67
70
  getOrLoad<T>(key: string, loader: (key: string) => Promise<T>): Promise<T>;
68
71
  abstract put<T>(key: string, value: T): Promise<T>;
69
72
  abstract delete<T>(key: string): Promise<void>;
@@ -173,6 +176,7 @@ declare class AssetKey extends BasicAssetKey {
173
176
  rootType: "assets" | "data" | string;
174
177
  extension: ".json" | ".png" | string;
175
178
  root?: string | undefined;
179
+ readonly isAssetKey: true;
176
180
  constructor(namespace: string, path: string, assetType?: AssetType | undefined, type?: string | undefined, rootType?: "assets" | "data" | string, extension?: ".json" | ".png" | string, root?: string | undefined);
177
181
  static parse(assetType: AssetType, str: string, origin?: AssetKey): AssetKey;
178
182
  toString(): string;
@@ -195,11 +199,99 @@ interface ListAsset extends MinecraftAsset {
195
199
  files: string[];
196
200
  }
197
201
 
202
+ interface EntityLayer {
203
+ key: BasicAssetKey;
204
+ texture?: AssetKey;
205
+ layer: EntityModelLayer;
206
+ /** How this draw is rendered; defaults to the geometry layer's own mode, then `cutout`. */
207
+ render?: EntityRenderMode;
208
+ /** Label of the state colour that multiplies the texture, from the pass that selected this draw. */
209
+ tint?: string;
210
+ }
211
+ interface EntityModel extends EntityLayer {
212
+ id: string;
213
+ /** Root transform from the dataset; see {@link EntityTransformOp}. */
214
+ transform?: EntityTransformOp[];
215
+ /**
216
+ * Selected draws in draw order; the top-level fields describe the first selection.
217
+ * A key is the geometry layer's name; a further draw of the same geometry (a pass with another texture) is keyed `<layer>#<n>`, from 2.
218
+ */
219
+ layers?: Record<string, EntityLayer>;
220
+ }
221
+ interface EntityModelFile extends MinecraftAsset {
222
+ id: string;
223
+ transform?: EntityTransformOp[];
224
+ layers: Record<string, EntityModelLayer>;
225
+ /** Extra draws vanilla adds on top of `main`, in draw order. */
226
+ passes?: EntityModelPass[];
227
+ }
228
+ /** Vanilla render type of a draw; see the dataset README for the mode table. */
229
+ type EntityRenderMode = "cutout" | "cutout_cull" | "cutout_z_offset" | "solid" | "translucent" | "translucent_emissive" | "eyes" | "energy_swirl" | "breeze_wind" | "water_mask";
230
+ interface EntityModelPass {
231
+ /** Geometry layer of the same file; a pass on `main` draws that geometry again. */
232
+ layer: string;
233
+ /** Present only when it differs from the layer's own. */
234
+ textureLocation?: string;
235
+ /** Present only when it differs from the layer's own. */
236
+ render?: EntityRenderMode;
237
+ /** Entity state that enables the draw, e.g. `powered`; without it the pass is always drawn. */
238
+ when?: string;
239
+ /** State colour that multiplies the texture, e.g. `wool_color`. */
240
+ tint?: string;
241
+ }
242
+ /**
243
+ * One operation vanilla's renderer applies before drawing a model, in call order:
244
+ * each one is applied on top of the previous, so the last reaches the vertices first.
245
+ * Translations use model units and rotations use radians, like part poses.
246
+ */
247
+ type EntityTransformOp = {
248
+ scale: [number, number, number];
249
+ } | {
250
+ translate: [number, number, number];
251
+ } | {
252
+ rotate: [number, number, number];
253
+ };
254
+ interface EntityModelLayer {
255
+ texture: [number, number];
256
+ textureLocation?: string;
257
+ /** Omitted for `cutout`. */
258
+ render?: EntityRenderMode;
259
+ root: EntityModelPart;
260
+ }
261
+ interface EntityModelPart {
262
+ pose: {
263
+ offset: [number, number, number];
264
+ rotation: [number, number, number];
265
+ scale?: [number, number, number];
266
+ };
267
+ texture?: [number, number];
268
+ cubes: EntityModelCube[];
269
+ children: Record<string, EntityModelPart>;
270
+ }
271
+ interface EntityModelCube {
272
+ origin: [number, number, number];
273
+ size: [number, number, number];
274
+ uv: [number, number];
275
+ grow?: [number, number, number];
276
+ mirror?: boolean;
277
+ }
278
+
198
279
  declare class Materials {
199
280
  private static readonly MISSING_TEXTURE_SRC;
200
281
  static get MISSING_TEXTURE(): Material;
201
282
  static createImage(key: MaterialKey): Material;
202
283
  static createBasicCanvasMaterial(canvas: HTMLCanvasElement, transparent?: boolean, shade?: boolean): Material;
284
+ /** Whether vanilla's render type for the mode culls back faces. */
285
+ static entityModeCulls(mode?: EntityRenderMode): boolean;
286
+ /** UV offset per tick of entity age for the scrolling modes, as vanilla's texture matrix applies it. */
287
+ static entityModeScroll(mode?: EntityRenderMode): [number, number] | undefined;
288
+ /**
289
+ * Entity material for one of vanilla's render types. Entities are unlit here, so the lit and full-bright modes
290
+ * differ only in blending and depth state. Culling is not a material property: {@link entityModeCulls} decides
291
+ * whether the geometry gets inward faces.
292
+ */
293
+ static createEntityCanvasMaterial(canvas: HTMLCanvasElement, mode?: EntityRenderMode, tint?: ColorRepresentation): MeshBasicMaterial;
294
+ static createGuiCanvasMaterial(canvas: HTMLCanvasElement): MeshBasicMaterial;
203
295
  static createShadedCanvasMaterial(canvas: HTMLCanvasElement, transparent?: boolean, shade?: boolean): Material;
204
296
  static getImage(key: MaterialKey): Material;
205
297
  static needsUpdate(mat: Material): void;
@@ -245,7 +337,8 @@ declare enum DisplayPosition {
245
337
  GUI = "gui",
246
338
  HEAD = "head",
247
339
  GROUND = "ground",
248
- FIXED = "fixed"
340
+ FIXED = "fixed",
341
+ ON_SHELF = "on_shelf"
249
342
  }
250
343
  declare const DISPLAY_POSITIONS: DisplayPosition[];
251
344
 
@@ -254,6 +347,46 @@ declare enum GuiLight {
254
347
  SIDE = "side"
255
348
  }
256
349
 
350
+ interface RequestConfig extends RequestInit {
351
+ url: string;
352
+ /** Prepended to relative URLs, preserving any path in the base URL. */
353
+ baseURL?: string;
354
+ /** Timeout per attempt in milliseconds, including body reading. Defaults to 5000; 0 disables it. */
355
+ timeout?: number;
356
+ responseType?: "json" | "arraybuffer";
357
+ }
358
+ interface RequestResponse<T = any> {
359
+ data: T;
360
+ status: number;
361
+ statusText: string;
362
+ headers: Headers;
363
+ /** Final URL after redirects. */
364
+ url: string;
365
+ }
366
+ declare class RequestError extends Error {
367
+ readonly response?: RequestResponse<undefined> | undefined;
368
+ readonly cause?: unknown;
369
+ constructor(message: string, response?: RequestResponse<undefined> | undefined, cause?: unknown);
370
+ }
371
+ declare class Requests {
372
+ private static genericQueue;
373
+ private static mcAssetRequestQueue;
374
+ static genericRequest(request: RequestConfig): Promise<RequestResponse>;
375
+ static mcAssetRequest(request: RequestConfig): Promise<RequestResponse>;
376
+ static setMcAssetRoot(root: string): void;
377
+ /** Counts unsettled calls, including retry delays and requests still running after shutdown. */
378
+ static get queueSizes(): {
379
+ generic: number;
380
+ mcAsset: number;
381
+ };
382
+ /**
383
+ * Permanently stops both queues and rejects waiting, retrying, and future requests.
384
+ * Requests already running can finish. Idle queues hold no timer, so Node can exit without
385
+ * this cleanup. See {@link shutdown}.
386
+ */
387
+ static end(): void;
388
+ }
389
+
257
390
  declare class WrappedImage {
258
391
  readonly dta: ExtractableImageData;
259
392
  constructor(dta: ExtractableImageData);
@@ -277,7 +410,7 @@ interface ImageInfo {
277
410
  width: number;
278
411
  height: number;
279
412
  type?: string;
280
- data: Buffer$1;
413
+ data: Buffer;
281
414
  }
282
415
  declare class ImageLoader {
283
416
  protected static _createImage(): CompatImage;
@@ -289,7 +422,7 @@ declare class ImageLoader {
289
422
  static infoToData(info: ImageInfo): Promise<ImageData>;
290
423
  static getData(src: string): Promise<ImageData>;
291
424
  static getCanvasData(src: string): Promise<ExtractableImageData>;
292
- static processResponse(response: Partial<AxiosResponse>): Promise<ImageInfo>;
425
+ static processResponse(response: Pick<RequestResponse<ArrayBuffer>, "data" | "url">): Promise<ImageInfo>;
293
426
  static loadInfo(src: string): Promise<ImageInfo>;
294
427
  static getInfo(src: string): Promise<ImageInfo>;
295
428
  static loadWrapped(src: string): Promise<WrappedImage>;
@@ -303,7 +436,7 @@ declare const DEFAULT_ELEMENTS: ModelElement[];
303
436
  interface Model extends MinecraftAsset {
304
437
  textures?: IModelTextures;
305
438
  parent?: string;
306
- display?: ModelDisplay;
439
+ display?: Partial<Record<DisplayPosition, ModelDisplay>>;
307
440
  elements?: ModelElement[];
308
441
  hierarchy?: string[];
309
442
  }
@@ -314,11 +447,24 @@ interface BlockModel extends Model {
314
447
  interface ItemModel extends Model {
315
448
  textures?: ItemModelTextures;
316
449
  gui_light?: GuiLight;
450
+ special?: SpecialItemRenderer;
317
451
  }
452
+ type SpecialItemRenderer = {
453
+ type: "chest" | "minecraft:chest";
454
+ texture: string;
455
+ openness?: number;
456
+ } | {
457
+ type: "bed" | "minecraft:bed";
458
+ texture: string;
459
+ } | {
460
+ type: "head" | "minecraft:head";
461
+ kind: string;
462
+ texture?: string;
463
+ animation?: number;
464
+ };
318
465
  interface TextureAsset extends MinecraftAsset, ImageInfo {
319
466
  }
320
467
  interface ModelDisplay {
321
- position?: DisplayPosition;
322
468
  translation?: TripleArray;
323
469
  rotation?: TripleArray;
324
470
  scale?: TripleArray;
@@ -338,13 +484,7 @@ declare function isDoubleArray(obj: any): obj is DoubleArray;
338
484
  declare function isTripleArray(obj: any): obj is TripleArray;
339
485
  declare function isQuadArray(obj: any): obj is QuadArray;
340
486
 
341
- /**
342
- * down up
343
- * east north west south
344
- *
345
- * bottom-left to top-right
346
- * [bl, br, tl, tr]
347
- */
487
+ /** Vanilla Minecraft cube UVs in Three.js BoxGeometry face and vertex order. */
348
488
  declare class MinecraftCubeTexture {
349
489
  readonly u: number;
350
490
  readonly v: number;
@@ -360,7 +500,7 @@ declare class MinecraftCubeTexture {
360
500
  getUvSouth(w: number, h: number, l: number): QuadArray<DoubleArray>;
361
501
  getUvNorth(w: number, h: number, l: number): QuadArray<DoubleArray>;
362
502
  getFaceUv(face: CubeFace, w: number, h: number, l: number): QuadArray<DoubleArray>;
363
- toUvArray(w: number, h: number, l: number): number[];
503
+ toUvArray(w: number, h: number, l: number, mirror?: boolean): number[];
364
504
  }
365
505
 
366
506
  interface MinecraftTextureMeta extends MinecraftAsset {
@@ -488,6 +628,7 @@ declare class TextureAtlas implements Disposable {
488
628
  };
489
629
  readonly hasTransparency: boolean;
490
630
  ticker?: number;
631
+ private readonly subscribers;
491
632
  constructor(model: Model, image: CanvasImage, sizes: {
492
633
  [texture: string]: DoubleArray;
493
634
  }, positions: {
@@ -495,6 +636,8 @@ declare class TextureAtlas implements Disposable {
495
636
  }, hasAnimation: boolean, animatorFunctions: {
496
637
  [p: string]: AnimatorFunction;
497
638
  }, hasTransparency: boolean);
639
+ /** Calls subscribers when an animation frame changes; unused atlases do not tick. */
640
+ subscribe(callback: () => void): () => void;
498
641
  getData(texture: string): ImageData$1;
499
642
  dispose(): void;
500
643
  }
@@ -513,6 +656,7 @@ declare class UVMapper {
513
656
  static setCubeUvs(geometry: BoxGeometry, originalTextureSize: DoubleArray, actualTextureSize: DoubleArray, faces: ModelFaces): void;
514
657
  static facesToUvArray(faces: ModelFaces, originalTextureSize: DoubleArray, actualTextureSize: DoubleArray): number[];
515
658
  static facesToUv(faces: ModelFaces, originalTextureSize: DoubleArray, actualTextureSize: DoubleArray): Float32BufferAttribute;
659
+ static lockUvs(geometry: BoxGeometry, faces: ModelFaces, atlas: TextureAtlas, rotation: Euler): void;
516
660
  static getAtlas(model: Model): Promise<Maybe<TextureAtlas>>;
517
661
  static fillMissingTextureKeys<T>(textures: ModelTextures, target: {
518
662
  [k: string]: T;
@@ -534,14 +678,13 @@ declare class MinecraftFaceUV {
534
678
  }
535
679
 
536
680
  /**
537
- * Releases every long-lived timer MineRender holds, so a Node process can exit.
681
+ * Stops the shared Ticker and request queues, and clears the in-memory caches.
538
682
  *
539
- * Both `@inventivetalent/loading-cache` (cache expiry) and `jobqu` (request queue draining) use
540
- * self-rescheduling timers that are not unref'd, which keeps the event loop alive for as long as
541
- * the library is loaded. Browsers don't care, but anything headless - a render server, a CLI, a
542
- * test run - has to call this when it's done.
683
+ * Idle Node processes can exit without calling this: cache and Ticker timers are unref'd,
684
+ * and idle request queues hold no timer. Pending requests keep their normal timer references.
543
685
  *
544
- * The library stays usable afterwards; the caches and queues simply start over.
686
+ * Call this only when finished with MineRender. Queued, retrying, and future requests reject;
687
+ * HTTP requests already running can finish. Queue shutdown is permanent, and cache expiry timers do not restart.
545
688
  */
546
689
  declare function shutdown(): void;
547
690
 
@@ -549,46 +692,19 @@ declare class BatchedExecutor {
549
692
  readonly interval: number;
550
693
  readonly batch: number;
551
694
  private readonly queue;
552
- private readonly task;
553
695
  constructor(interval?: number, batch?: number);
554
- submit(task: Task): void;
555
- private run;
556
- private runNext;
696
+ submit<T>(task: Task<T>): Promise<T>;
697
+ stop(): void;
557
698
  }
558
- type Task = () => any | Promise<any>;
699
+ type Task<T = unknown> = () => T | Promise<T>;
559
700
 
560
701
  declare function prefix(prefix?: string): string;
561
702
 
562
- interface ModelPart {
563
- textureWidth: number;
564
- textureHeight: number;
565
- textureOffsetU: number;
566
- textureOffsetV: number;
567
- pivotX: number;
568
- pivotY: number;
569
- pivotZ: number;
570
- pitch: number;
571
- yaw: number;
572
- roll: number;
573
- mirror: boolean;
574
- cubes: Cube[];
575
- children: ModelPart[];
576
- }
577
- interface Cube {
578
- minX: number;
579
- minY: number;
580
- minZ: number;
581
- maxX: number;
582
- maxY: number;
583
- maxZ: number;
584
- }
585
-
586
703
  declare function applyElementRotation(rotation: ElementRotation, geometry: BufferGeometry): void;
587
- declare function applyModelPartRotation(modelPart: ModelPart, geometry: BufferGeometry): void;
588
704
  declare function applyGenericRotation(axis: Axis, rotation: number, obj: Object3D): void;
589
705
  declare function addBox3WireframeToObject(box: Box3, obj: Object3D, color?: number, w?: number): void;
590
706
  declare function addWireframeToObject(obj: Object3D, color?: number, w?: number): void;
591
- declare function addWireframeToMesh(geo: BufferGeometry, mesh: Mesh, color?: number, w?: number): void;
707
+ declare function addWireframeToMesh(geo: BufferGeometry, mesh: Mesh, color?: number, w?: number): () => void;
592
708
 
593
709
  declare function captureException(e: any, ...extra: any[]): void;
594
710
  declare function timingStart(marker: string): void;
@@ -613,16 +729,47 @@ declare enum AssetParser {
613
729
  declare abstract class AssetSource {
614
730
  protected constructor();
615
731
  abstract get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<Maybe<T>>;
732
+ /**
733
+ * Identifies this source's content across sessions for persistent caching. Sources that
734
+ * cannot tell whether their content changed (an unnamed archive, for example) return
735
+ * undefined, which keeps their results out of long-lived caches.
736
+ */
737
+ get cacheId(): Maybe<string>;
738
+ }
739
+ /** A source failed to load or parse an asset; cause retains the original failure. */
740
+ declare class AssetLoadError extends Error {
741
+ readonly source: AssetSource;
742
+ readonly key: AssetKey;
743
+ readonly path: string;
744
+ readonly cause: unknown;
745
+ constructor(source: AssetSource, key: AssetKey, path: string, cause: unknown);
616
746
  }
617
747
 
618
748
  declare class AssetLoader {
619
749
  static ROOT: string;
620
750
  private static _SOURCES;
751
+ /** Used when a registered source cannot identify its content, so nothing persists past this session. */
752
+ private static readonly SESSION_SCOPE;
753
+ static get version(): string;
754
+ static setVersion(version: string): void;
755
+ /**
756
+ * Scope for persistent cache keys. Empty with only the default vanilla sources, so their
757
+ * entries stay valid across sessions; otherwise it names every added source (resource packs,
758
+ * mirrors) so their results never masquerade as vanilla assets after a reload.
759
+ */
760
+ static get persistentScope(): string;
761
+ /** Prefixes a persistent cache key with the current source scope. */
762
+ static persistentKey(key: string): string;
621
763
  static addSource(key: string, source: AssetSource, override?: boolean): void;
622
764
  static removeSource(key: string): Maybe<AssetSource>;
623
765
  static getAll<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<T[]>;
624
766
  /** Returns the first defined result in source-priority order, without merging assets. */
625
767
  static get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<Maybe<T>>;
768
+ /** Tries each path within a source before considering lower-priority sources. */
769
+ static getFirst<T extends MinecraftAsset>(keys: readonly AssetKey[], parser: AssetParser | string): Promise<Maybe<{
770
+ key: AssetKey;
771
+ asset: T;
772
+ }>>;
626
773
  }
627
774
 
628
775
  interface BlockState extends MinecraftAsset {
@@ -637,18 +784,19 @@ interface BlockStateVariant {
637
784
  y?: number;
638
785
  x?: number;
639
786
  uvlock?: boolean;
787
+ weight?: number;
640
788
  }
641
789
  interface BlockStateMultipart {
642
- when?: MultipartCondition | {
643
- OR: MultipartCondition[];
644
- };
645
- apply?: BlockStateVariant;
646
- }
647
- interface MultipartCondition {
648
- [key: string]: string;
790
+ when?: MultipartCondition;
791
+ apply?: BlockStateVariant | BlockStateVariant[];
649
792
  }
793
+ type MultipartCondition = Record<string, string> | {
794
+ OR: MultipartCondition[];
795
+ } | {
796
+ AND: MultipartCondition[];
797
+ };
650
798
 
651
- declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.17.1";
799
+ declare const DEFAULT_ROOT = "https://assets.mcasset.cloud/1.21.11";
652
800
  declare const DEFAULT_NAMESPACE = "minecraft";
653
801
  declare class Assets {
654
802
  /**
@@ -673,6 +821,55 @@ type BlockStateProperties = {
673
821
  [key: string]: string;
674
822
  };
675
823
 
824
+ /** One model drawn by a block-entity renderer. */
825
+ interface BlockEntityPart {
826
+ model: string;
827
+ /** Model layer; defaults to "main". */
828
+ layer?: string;
829
+ /** Set only when the texture differs from the layer's default. */
830
+ textureLocation?: string;
831
+ /** Blockstate multipart syntax: every property must match, and "a|b" matches either value. */
832
+ when?: Record<string, string>;
833
+ }
834
+ /** Degrees per property value, or degrees per unit of a numeric property. */
835
+ type BlockEntityRotation = {
836
+ property: string;
837
+ degrees: Record<string, number>;
838
+ } | {
839
+ property: string;
840
+ step: number;
841
+ };
842
+ interface BlockEntityEntry {
843
+ parts: BlockEntityPart[];
844
+ rotation?: BlockEntityRotation;
845
+ /** Offset in model units, applied before the rotation. */
846
+ translation?: TripleArray;
847
+ }
848
+ /** The dataset's `blocks.json`: block ID to the models its block-entity renderer draws. */
849
+ type BlockEntityIndex = MinecraftAsset & {
850
+ [block: string]: BlockEntityEntry;
851
+ };
852
+ interface ResolvedBlockEntity {
853
+ parts: BlockEntityPart[];
854
+ /** Degrees counter-clockwise seen from above, about the block's vertical centre axis. */
855
+ rotation: number;
856
+ translation: TripleArray;
857
+ }
858
+ declare class BlockEntities {
859
+ /**
860
+ * Loads the block index of a version. Versions and sources without one yield an empty index, and so does
861
+ * a failed load: the index is optional, and blocks must not retry or fail with it one by one. The empty
862
+ * result is cached like any other; `Caching.clear()` or `AssetLoader.setVersion()` forces a new attempt.
863
+ */
864
+ static getIndex(root?: string): Promise<BlockEntityIndex>;
865
+ /** The index entry of a block ID such as `minecraft:chest`. */
866
+ static entry(index: BlockEntityIndex, block: string): Maybe<BlockEntityEntry>;
867
+ /** Selects the parts and placement for a block ID such as `minecraft:chest`; undefined when nothing is drawn. */
868
+ static resolve(index: BlockEntityIndex, block: string, state?: BlockStateProperties): Maybe<ResolvedBlockEntity>;
869
+ /** Placement in block space (0..16 per axis), applied on top of the model's own transform. */
870
+ static matrix(resolved: ResolvedBlockEntity, matrix?: Matrix4): Matrix4;
871
+ }
872
+
676
873
  declare class BlockStates {
677
874
  private static _persistentCache;
678
875
  private static get PERSISTENT_CACHE();
@@ -687,25 +884,72 @@ declare class DefaultBlockStates implements MinecraftAsset {
687
884
  [k: string]: BlockStatePropertyDefaults;
688
885
  }
689
886
 
690
- interface EntityModel extends BasicMinecraftAsset {
691
- parts?: {
692
- [p: string]: ModelPart;
693
- };
887
+ /** `entity-models/animations/<namespace>/<model id>.json`: vanilla's keyframe animations of one model. */
888
+ interface EntityAnimationFile extends MinecraftAsset {
889
+ id: string;
890
+ animations: Record<string, EntityAnimation>;
891
+ }
892
+ interface EntityAnimation {
893
+ /** Seconds. */
894
+ length: number;
895
+ loop: boolean;
896
+ /** Part name anywhere in a layer; `root` is the layer's root part. */
897
+ bones: Record<string, EntityAnimationBone>;
694
898
  }
899
+ type EntityAnimationChannel = "position" | "rotation" | "scale";
900
+ /** Keyframes in time order per channel. */
901
+ type EntityAnimationBone = Partial<Record<EntityAnimationChannel, EntityAnimationKeyframe[]>>;
902
+ interface EntityAnimationKeyframe {
903
+ /** Seconds. */
904
+ time: number;
905
+ /** Offset from the default pose: model units, radians, or scale minus one. */
906
+ value: TripleArray;
907
+ /** Value to arrive at when it differs from `value`; linear interpolation only. */
908
+ pre?: TripleArray;
909
+ /** Applies between the previous keyframe and this one. */
910
+ interpolation: "linear" | "catmullrom";
911
+ }
912
+ /** Sampled offsets from the default pose, per bone and channel. */
913
+ type EntityAnimationPose = Record<string, Partial<Record<EntityAnimationChannel, TripleArray>>>;
914
+ declare const ENTITY_ANIMATION_CHANNELS: readonly EntityAnimationChannel[];
915
+ /**
916
+ * Samples one channel like vanilla's `KeyframeAnimation.Entry`: the first value holds before the
917
+ * first keyframe and the last value after the last one; in between, the later keyframe selects the interpolation.
918
+ */
919
+ declare function sampleEntityKeyframes(keyframes: readonly EntityAnimationKeyframe[], time: number): TripleArray;
920
+ /** Elapsed seconds within the animation: modulo `length` when looping, as vanilla does. */
921
+ declare function entityAnimationTime(animation: EntityAnimation, time: number, loop?: boolean): number;
922
+ /** Samples every bone and channel of an animation at `time` seconds. */
923
+ declare function sampleEntityAnimation(animation: EntityAnimation, time: number, loop?: boolean): EntityAnimationPose;
695
924
 
696
925
  declare class Entities {
697
- static getBlockEntityModels(): Promise<Maybe<BlockEntityModels>>;
698
- static getEntityModels(): Promise<Maybe<EntityModels>>;
699
- static getBlockList(): Promise<string[]>;
700
926
  static getEntityList(): Promise<string[]>;
701
- static getBlock(modelKey: BasicAssetKey, textureKey?: BasicAssetKey): Promise<Maybe<EntityModel>>;
702
- static getEntity(modelKey: BasicAssetKey, textureKey?: BasicAssetKey): Promise<Maybe<EntityModel>>;
703
- }
704
- declare class EntityModels implements MinecraftAsset {
705
- [k: string]: any;
927
+ private static getModelFile;
928
+ static getLayerList(modelKey: BasicAssetKey): Promise<string[]>;
929
+ /** The dataset's extra draws on top of `main`; their `when` labels are the states `EntityModelOptions.when` can enable. */
930
+ static getPassList(modelKey: BasicAssetKey): Promise<EntityModelPass[]>;
931
+ static getEntity(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>>;
932
+ /**
933
+ * Vanilla's keyframe animations of a model by name, or undefined when the model or the selected version has none.
934
+ */
935
+ static getAnimations(modelKey: BasicAssetKey): Promise<Maybe<Record<string, EntityAnimation>>>;
936
+ static resolveTexture(modelKey: BasicAssetKey): Promise<Maybe<AssetKey>>;
937
+ /** @deprecated Use getEntityList(); block entities share the entity dataset. */
938
+ static getBlockList(): Promise<string[]>;
939
+ /** @deprecated Use getEntity(); block entities share the entity dataset. */
940
+ static getBlock(modelKey: BasicAssetKey, textureKey?: BasicAssetKey, options?: EntityModelOptions): Promise<Maybe<EntityModel>>;
706
941
  }
707
- declare class BlockEntityModels implements MinecraftAsset {
708
- [k: string]: any;
942
+ interface EntityModelOptions {
943
+ layer?: string;
944
+ /** Layer names in draw order; an explicit selection draws exactly these layers and no dataset passes. */
945
+ layers?: string[];
946
+ /**
947
+ * Entity states that enable the dataset's conditional passes, e.g. `["powered"]` for a charged creeper.
948
+ * Without `layer`/`layers`, `main` and every unconditional pass are always drawn.
949
+ */
950
+ when?: string[];
951
+ /** Per-layer texture overrides, keyed like `EntityModel.layers`. The positional texture key applies to the first selected layer. */
952
+ textures?: Record<string, BasicAssetKey>;
709
953
  }
710
954
 
711
955
  declare class Models {
@@ -713,15 +957,34 @@ declare class Models {
713
957
  private static get PERSISTENT_CACHE();
714
958
  static getItemList(): Promise<string[]>;
715
959
  static loadAndMerge(key: AssetKey): Promise<Maybe<Model>>;
960
+ private static getItemModel;
961
+ private static defaultItemModel;
716
962
  static getRaw(key: AssetKey): Promise<Maybe<Model>>;
717
963
  static getMerged(key: AssetKey): Promise<Maybe<Model>>;
718
964
  static get(key: AssetKey): Promise<Maybe<Model>>;
719
965
  static clearCache(): Promise<void>;
720
966
  }
721
967
 
968
+ declare class DisplayTransforms {
969
+ /** Resolve hand fallbacks within one model, before inheriting parent display entries. */
970
+ static withHandFallbacks(display: Model["display"]): Model["display"];
971
+ /** Build a display pose for geometry already centered at the model's [8, 8, 8] pivot. */
972
+ static getMatrix(display: Model["display"], position: DisplayPosition): Matrix4;
973
+ static apply(geometry: BufferGeometry, matrix: Matrix4): void;
974
+ }
975
+
976
+ declare class ModelCulling {
977
+ static toLocalMask(worldMask: number, rotation: Euler): number;
978
+ static isOpaqueFullCube(atlas: Maybe<TextureAtlas>): boolean;
979
+ }
980
+
722
981
  declare class ModelGenerator {
723
982
  static readonly ITEM_LAYERS: string[];
724
- static generateItemModel(imageData: ImageData$1, layer: string): ModelElement[];
983
+ /**
984
+ * Front and back faces plus one zero-thickness side face per run of texels that border a transparent texel,
985
+ * like vanilla's ItemModelGenerator. Pass the pixels of a single (first) animation frame.
986
+ */
987
+ static generateItemModel(imageData: Pick<ImageData$1, "width" | "height" | "data">, layer: string): ModelElement[];
725
988
  }
726
989
 
727
990
  declare class ModelMerger {
@@ -729,14 +992,42 @@ declare class ModelMerger {
729
992
  protected static collectAllParents(model: Model): Promise<Model[]>;
730
993
  }
731
994
 
995
+ interface SpecialItemPart {
996
+ model: EntityModel;
997
+ transform: Matrix4;
998
+ rotations: Record<string, TripleArray>;
999
+ }
1000
+ declare class SpecialItems {
1001
+ /** Resolves the static entity parts drawn by a special item renderer, in model units. */
1002
+ static getParts(special: SpecialItemRenderer, root?: string): Promise<SpecialItemPart[]>;
1003
+ /** An owned material with model-preview shading; its entity texture remains shared. */
1004
+ static createMaterial(source: MeshBasicMaterial, shade: boolean): MeshBasicMaterial;
1005
+ }
1006
+
732
1007
  interface Block {
733
1008
  type: string;
734
1009
  properties?: BlockStateProperties;
735
1010
  nbt?: any;
736
1011
  }
737
1012
 
1013
+ declare class BlockStateResolver {
1014
+ static defaults(blockState: BlockState): Promise<BlockStateProperties>;
1015
+ static select(blockState: BlockState, state: BlockStateProperties, choose?: (variants: BlockStateVariant | BlockStateVariant[]) => BlockStateVariant): BlockStateVariant[];
1016
+ static matching(blockState: BlockState, state: BlockStateProperties): (BlockStateVariant | BlockStateVariant[])[];
1017
+ static choose(variants: BlockStateVariant | BlockStateVariant[]): BlockStateVariant;
1018
+ static rotation(variant: BlockStateVariant): Euler;
1019
+ }
1020
+
1021
+ declare class BlockTints {
1022
+ /** Resolves block preview colors without biome context; explicit tints take precedence. */
1023
+ static get(key: AssetKey | undefined, state: BlockStateProperties, model: Model, tints?: Record<number, number>): Promise<Record<number, number> | undefined>;
1024
+ private static grassColor;
1025
+ }
1026
+
738
1027
  interface Instanceable {
739
1028
  nextInstance(): InstanceReference<SceneObject>;
1029
+ removeInstanceAt(index: number): void;
1030
+ isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean;
740
1031
  getMatrixAt(index: number, matrix?: Matrix4): Matrix4;
741
1032
  setMatrixAt(index: number, matrix: Matrix4): void;
742
1033
  setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -749,12 +1040,15 @@ interface Instanceable {
749
1040
  }
750
1041
  declare function isInstanceable(obj: any): obj is Instanceable;
751
1042
 
752
- declare class InstanceReference<T extends Instanceable> implements Transformable {
1043
+ declare class InstanceReference<T extends Instanceable> implements Transformable, Disposable {
753
1044
  readonly instanceable: T;
754
1045
  readonly index: number;
755
1046
  readonly isInstanceReference: true;
756
1047
  constructor(instanceable: T, index: number);
757
1048
  nextInstance(): InstanceReference<SceneObject>;
1049
+ private get activeInstanceable();
1050
+ removeFromScene(): void;
1051
+ dispose(): void;
758
1052
  getMatrix(matrix?: Matrix4): Matrix4;
759
1053
  setMatrix(matrix: Matrix4): void;
760
1054
  setPositionRotationScale(position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -779,18 +1073,34 @@ declare class ModelObject extends SceneObject {
779
1073
  readonly isModelObject: true;
780
1074
  static readonly DEFAULT_OPTIONS: ModelObjectOptions;
781
1075
  readonly options: ModelObjectOptions;
782
- private atlas?;
1076
+ protected atlas?: TextureAtlas;
1077
+ private atlasMaterial?;
1078
+ private atlasTexture?;
1079
+ private unsubscribeAtlas?;
1080
+ private readonly specialMaterials;
783
1081
  blockParent: Maybe<BlockObject>;
784
1082
  private meshesCreated;
785
1083
  constructor(originalModel: Model, options?: Partial<ModelObjectOptions>);
786
1084
  init(): Promise<void>;
787
- dispose(): void;
788
1085
  get textureAtlas(): Maybe<TextureAtlas>;
1086
+ get isOpaqueFullCube(): boolean;
789
1087
  protected loadTextures(): Promise<void>;
790
1088
  protected createMeshes(force?: boolean): void;
791
1089
  protected applyTextures(): void;
1090
+ private updateAnimationSubscription;
1091
+ nextInstance(): InstanceReference<SceneObject>;
1092
+ removeInstanceAt(index: number): void;
1093
+ disposeAndRemoveAllChildren(): void;
792
1094
  }
793
1095
  interface ModelObjectOptions extends SceneObjectOptions {
1096
+ /** Minecraft display pose applied around the model center, before scene transforms. */
1097
+ displayPosition?: DisplayPosition;
1098
+ /** Quarter-turn block rotation in radians to compensate when locking UVs. */
1099
+ uvLockRotation?: TripleArray;
1100
+ /** sRGB 0xRRGGBB colors by face tint index; omitted indices stay white. */
1101
+ tints?: Record<number, number>;
1102
+ /** Hidden neighbor directions in CUBE_FACES order, before the model's block rotation. */
1103
+ cullMask?: number;
794
1104
  }
795
1105
  declare function isModelObject(obj: any): obj is ModelObject;
796
1106
 
@@ -823,24 +1133,71 @@ declare enum SkinPart {
823
1133
  }
824
1134
  declare const SKIN_PARTS: SkinPart[];
825
1135
 
1136
+ type CapeLayout = "minecraft" | "optifine" | "labymod";
1137
+ declare const capeTextureSizes: Record<CapeLayout, DoubleArray>;
1138
+
1139
+ /** A player model facing +Z. Left and right parts are the player's own: left is +X, right is -X. */
826
1140
  declare class SkinObject extends SceneObject {
827
1141
  readonly options: SkinObjectOptions;
828
1142
  private slim;
829
- private legacy;
1143
+ private detectedSlim;
830
1144
  private skinTextureSrc?;
831
- private skinTextureWidth;
832
- private skinTextureHeight;
833
- private capeTextureSrc?;
1145
+ private skinMaterial?;
1146
+ private skinLoad;
1147
+ private capeLoad;
834
1148
  constructor(options?: DeepPartial<SkinObjectOptions>);
835
1149
  init(): Promise<void>;
836
1150
  protected removeMeshes(): void;
837
1151
  protected createMeshes(): void;
838
- setSkinTexture(src: string): void;
839
- setSlim(slim: boolean): void;
840
- setLegacy(legacy: boolean): void;
1152
+ setSkinTexture(src: string): Promise<void>;
1153
+ /** Load a cape texture in the selected layout, or pass undefined to remove the cape. */
1154
+ setCapeTexture(src?: string, layout?: CapeLayout): Promise<void>;
1155
+ /** Select the arm model, or pass undefined to use texture detection. */
1156
+ setSlim(slim?: boolean): void;
1157
+ private updateSlim;
1158
+ /** Select the texture layout, or pass undefined to detect it from image dimensions. */
1159
+ setLegacy(legacy?: boolean): Promise<void>;
1160
+ dispose(): void;
841
1161
  protected getBoxGeometry(part: SkinPart): BoxGeometry;
842
1162
  }
843
1163
  interface SkinObjectOptions extends SceneObjectOptions {
1164
+ slim?: boolean;
1165
+ legacy?: boolean;
1166
+ }
1167
+
1168
+ interface EntityAnimationOptions {
1169
+ /** Overrides the animation's own `loop` flag. */
1170
+ loop?: boolean;
1171
+ /** Playback rate applied to advanced time; defaults to 1. */
1172
+ speed?: number;
1173
+ /** Start time in seconds; defaults to 0. */
1174
+ time?: number;
1175
+ }
1176
+ /**
1177
+ * Poses part groups from a keyframe animation the way vanilla does: every update restores the
1178
+ * default pose of each animated part, then adds the sampled offsets to its position, Euler angles and scale.
1179
+ * It owns no timer; the owner advances it.
1180
+ */
1181
+ declare class EntityAnimationPlayer {
1182
+ private parts;
1183
+ private _animation?;
1184
+ private _time;
1185
+ private loop;
1186
+ private speed;
1187
+ get animation(): EntityAnimation | undefined;
1188
+ get time(): number;
1189
+ /**
1190
+ * Starts an animation on the named parts below each layer root. The current pose of a part becomes its default;
1191
+ * bones without a matching part are skipped.
1192
+ */
1193
+ play(layers: Object3D[], animation: EntityAnimation, options?: EntityAnimationOptions): void;
1194
+ /** Restores the default poses. Returns whether an animation was active. */
1195
+ stop(): boolean;
1196
+ /** Forgets the animation without touching the parts, for parts that no longer exist. */
1197
+ clear(): void;
1198
+ setTime(seconds: number): boolean;
1199
+ advance(deltaSeconds: number): boolean;
1200
+ private apply;
844
1201
  }
845
1202
 
846
1203
  declare class EntityObject extends SceneObject {
@@ -848,19 +1205,99 @@ declare class EntityObject extends SceneObject {
848
1205
  readonly isEntityObject: true;
849
1206
  static readonly DEFAULT_OPTIONS: EntityObjectOptions;
850
1207
  readonly options: EntityObjectOptions;
851
- private imageData?;
852
1208
  private meshesCreated;
1209
+ private readonly geometries;
1210
+ private readonly disposeWireframes;
1211
+ /** Scrolling materials are owned: their texture offset follows this entity's age. */
1212
+ private readonly scrollMaterials;
1213
+ private scrollTicker;
1214
+ /** Entity age in ticks, as vanilla's `ageInTicks`; drives the scrolling render modes. */
1215
+ age: number;
1216
+ private readonly animationPlayer;
853
1217
  constructor(entity: EntityModel, options?: Partial<EntityObjectOptions>);
854
1218
  init(): Promise<void>;
855
1219
  dispose(): void;
856
- protected loadTextures(): Promise<void>;
1220
+ disposeAndRemoveAllChildren(): void;
1221
+ private clearScrollMaterials;
1222
+ private updateScrollSubscription;
1223
+ /** Applies the entity age to the scrolling materials; the ticker calls this 20 times per second. */
1224
+ private updateScroll;
1225
+ /** The animation started by {@link playAnimation}, until {@link stopAnimation} or disposal. */
1226
+ get animation(): Maybe<EntityAnimation>;
1227
+ /** Seconds since the animation started, before looping. */
1228
+ get animationTime(): number;
1229
+ /**
1230
+ * Poses the object from a keyframe animation of {@link Entities.getAnimations}, replacing the current one.
1231
+ * Parts of every layer are matched by name and their current pose is the default the offsets add to.
1232
+ * The object owns no clock: call {@link advanceAnimation} per frame, or {@link setAnimationTime}.
1233
+ */
1234
+ playAnimation(animation: EntityAnimation, options?: EntityAnimationOptions): void;
1235
+ /** Stops the animation and restores the default pose. */
1236
+ stopAnimation(): void;
1237
+ /** Poses the object at an explicit time in seconds. Has no effect without an animation. */
1238
+ setAnimationTime(seconds: number): void;
1239
+ /** Advances the animation by a frame delta in seconds, scaled by its speed. Has no effect without an animation. */
1240
+ advanceAnimation(deltaSeconds: number): void;
1241
+ getLayerGroup(name: string): Maybe<Object3D>;
1242
+ getGroupByName(name: string, layerName?: string): Maybe<Object3D>;
1243
+ getMeshByName(name: string, layerName?: string): Maybe<Mesh>;
1244
+ private get entityLayers();
1245
+ private getTextureKey;
1246
+ protected loadTextures(layer?: EntityLayer): Promise<Maybe<ExtractableImageData>>;
857
1247
  protected createMeshes(force?: boolean): void;
1248
+ private createPart;
858
1249
  protected applyTextures(): Promise<void>;
859
1250
  }
860
1251
  interface EntityObjectOptions extends SceneObjectOptions {
1252
+ /**
1253
+ * `true` applies only vanilla's entity flip, scale (-1, -1, 1); `false` keeps raw model space.
1254
+ * By default the model's dataset transform is used, or the flip for models without one.
1255
+ */
1256
+ flip?: boolean;
1257
+ /** Colours for the dataset's tint labels, e.g. `{ wool_color: 0xf9801d }`; a pass whose label is absent stays untinted. */
1258
+ tints?: Record<string, ColorRepresentation>;
861
1259
  }
862
1260
  declare function isEntityObject(obj: any): obj is EntityObject;
863
1261
 
1262
+ /** GUI layers use pixel coordinates. Later layers draw above earlier layers. */
1263
+ type GuiLayer = GuiTextureLayer | GuiItemLayer;
1264
+ interface GuiLayerLayout {
1265
+ name?: string;
1266
+ /** Top-left position; x grows right and y grows down. Defaults to [0, 0]. */
1267
+ position?: [number, number];
1268
+ /** Output width and height; defaults to the texture crop size or [16, 16] for items. */
1269
+ size?: [number, number];
1270
+ }
1271
+ interface GuiTextureLayer extends GuiLayerLayout {
1272
+ texture: AssetKey | string;
1273
+ /** Source-image pixels: [x, y, width, height], measured from the top left. */
1274
+ crop?: [number, number, number, number];
1275
+ }
1276
+ interface GuiItemLayer extends GuiLayerLayout {
1277
+ /** Model key, such as minecraft:item/stone; uses the model's GUI display pose. */
1278
+ item: AssetKey | string;
1279
+ /** sRGB 0xRRGGBB colors by face tint index; omitted indices stay white. */
1280
+ tints?: Record<number, number>;
1281
+ }
1282
+
1283
+ declare class GuiObject extends SceneObject {
1284
+ readonly textureLayers: readonly GuiLayer[];
1285
+ readonly isGuiObject: true;
1286
+ /** Local bounds in GUI pixels, with y growing down from the origin. */
1287
+ readonly bounds: Box2;
1288
+ private readonly geometries;
1289
+ private readonly ownedMaterials;
1290
+ private initialized;
1291
+ constructor(textureLayers: readonly GuiLayer[], options?: Partial<GuiObjectOptions>);
1292
+ init(): Promise<void>;
1293
+ private createItem;
1294
+ private loadMaterial;
1295
+ disposeAndRemoveAllChildren(): void;
1296
+ }
1297
+ interface GuiObjectOptions extends SceneObjectOptions {
1298
+ }
1299
+ declare function isGuiObject(obj: any): obj is GuiObject;
1300
+
864
1301
  declare class MineRenderScene extends Scene {
865
1302
  readonly isMineRenderScene: true;
866
1303
  static readonly DEFAULT_OPTIONS: MineRenderSceneOptions;
@@ -880,6 +1317,7 @@ declare class MineRenderScene extends Scene {
880
1317
  addBlock(blockState: BlockState, options?: Partial<BlockObjectOptions>, parent?: Object3D): Promise<BlockObject | InstanceReference<BlockObject>>;
881
1318
  addSkin(skin?: string, options?: Partial<SkinObjectOptions>, parent?: Object3D): Promise<SkinObject>;
882
1319
  addEntity(entity: EntityModel, options?: Partial<EntityObjectOptions>, parent?: Object3D): Promise<EntityObject | InstanceReference<EntityObject>>;
1320
+ addGui(layers: readonly GuiLayer[], options?: Partial<GuiObjectOptions>, parent?: Object3D): Promise<GuiObject>;
883
1321
  }
884
1322
  interface MineRenderSceneOptions {
885
1323
  }
@@ -895,6 +1333,9 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
895
1333
  private materialCallbacks;
896
1334
  protected _isInstanced: boolean;
897
1335
  _instanceCounter: number;
1336
+ protected instanceMesh?: InstancedMesh;
1337
+ private readonly instanceReferences;
1338
+ private readonly freeInstanceIndices;
898
1339
  constructor(options?: Partial<SceneObjectOptions>);
899
1340
  set scene(scene: MineRenderScene);
900
1341
  get scene(): MineRenderScene;
@@ -934,6 +1375,12 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
934
1375
  get instanceCounter(): number;
935
1376
  protected constructInstanceReference(i: number): InstanceReference<SceneObject>;
936
1377
  nextInstance(): InstanceReference<SceneObject>;
1378
+ /** Returns the live reference for a raycast hit on this object's instance mesh. */
1379
+ getInstanceReference(mesh: Object3D, index: number): Maybe<InstanceReference<SceneObject>>;
1380
+ isInstanceActive(index: number, reference: InstanceReference<Instanceable>): boolean;
1381
+ removeInstanceAt(index: number): void;
1382
+ private growInstances;
1383
+ protected activeInstanceIndices(): Iterable<number>;
937
1384
  getMatrixAt(index: number, matrix?: Matrix4): Matrix4;
938
1385
  setMatrixAt(index: number, matrix: Matrix4): void;
939
1386
  setPositionRotationScaleAt(index: number, position?: Vector3, rotation?: Euler, scale?: Vector3): void;
@@ -957,6 +1404,23 @@ declare class SceneObject extends Object3D<Object3DEventMap & {
957
1404
  }
958
1405
  declare function isSceneObject(obj: any): obj is SceneObject;
959
1406
 
1407
+ type FluidKind = "water" | "lava";
1408
+ interface BlockFluidState {
1409
+ kind: FluidKind;
1410
+ level: number;
1411
+ renderModel: boolean;
1412
+ }
1413
+ declare function getBlockFluidState(key?: AssetKey, state?: BlockStateProperties): BlockFluidState | undefined;
1414
+ declare function getFluidKind(key?: AssetKey, state?: BlockStateProperties): FluidKind | undefined;
1415
+ interface FluidSample {
1416
+ fluid?: FluidKind;
1417
+ level?: number;
1418
+ solid?: boolean;
1419
+ }
1420
+ type FluidSampler = (x: number, y: number, z: number) => FluidSample;
1421
+ /** Builds centered fluid faces with material groups 0 (still) and 1 (flowing). */
1422
+ declare function createFluidGeometry(kind: FluidKind, sample: FluidSampler): BufferGeometry;
1423
+
960
1424
  declare class BlockObject extends SceneObject {
961
1425
  readonly blockState: BlockState;
962
1426
  readonly isBlockObject: true;
@@ -970,16 +1434,43 @@ declare class BlockObject extends SceneObject {
970
1434
  private _instanceModel;
971
1435
  private _variants;
972
1436
  private _models;
1437
+ private _cullMask;
1438
+ private _fluidKey?;
1439
+ private _fluidSampler?;
1440
+ private _fluidModel?;
1441
+ private _entities;
1442
+ private _entityPlacement;
1443
+ private _entityGeneration;
973
1444
  constructor(blockState: BlockState, options?: Partial<BlockObjectOptions>);
974
1445
  init(): Promise<void>;
975
1446
  dispose(): void;
976
1447
  removeFromScene(): void;
1448
+ private clearModels;
1449
+ private removeModels;
1450
+ private removeEntities;
1451
+ /** Entity models drawn for this block instead of its block model; they are scene children, unlike the block. */
1452
+ get blockEntities(): readonly EntityObject[];
1453
+ /**
1454
+ * Draws the block through the dataset's block-entity index. Returns false, leaving nothing behind,
1455
+ * when the block is not listed or one of its models cannot be loaded.
1456
+ */
1457
+ private createBlockEntities;
1458
+ private placeEntities;
1459
+ get isOccluding(): boolean;
1460
+ private getModelMatrix;
1461
+ private getModelCullMask;
1462
+ setCullMask(worldMask: number): Promise<void>;
977
1463
  get state(): {
978
1464
  [key: string]: string;
979
1465
  };
1466
+ get fluidKind(): FluidKind | undefined;
1467
+ get fluidLevel(): number;
1468
+ /** Refreshes fluid surfaces from relative neighbors; standalone previews use air around the block. */
1469
+ updateFluid(sample?: FluidSampler): Promise<void>;
980
1470
  nextInstance(): InstanceReference<SceneObject>;
981
1471
  protected mapStateToVariant(state: BlockStateProperties): Promise<BlockStateVariant[]>;
982
1472
  recreateModels(): Promise<void>;
1473
+ private hasGeometry;
983
1474
  protected getSingleVariant(variants: BlockStateVariant | BlockStateVariant[]): BlockStateVariant;
984
1475
  protected createAVariant(variants: BlockStateVariant | BlockStateVariant[], instanceInfo: Matrix4[]): Promise<void>;
985
1476
  protected createVariant(variant: BlockStateVariant): Promise<ModelObject | InstanceReference<ModelObject>>;
@@ -995,26 +1486,50 @@ declare class BlockObject extends SceneObject {
995
1486
  }
996
1487
  interface BlockObjectOptions extends ModelObjectOptions {
997
1488
  applyDefaultState: boolean;
1489
+ /** Properties applied before model creation, overriding defaults when applyDefaultState is enabled. */
1490
+ initialState?: BlockStateProperties;
998
1491
  }
999
1492
  declare function isBlockObject(obj: any): obj is BlockObject;
1000
1493
 
1494
+ /** Saved fluid levels and solid neighbors determine the geometry shared by an instance pool. */
1495
+ declare function sampleFluid(kind: FluidKind, sample: FluidSampler): {
1496
+ key: string;
1497
+ sample: FluidSampler;
1498
+ };
1499
+ declare class FluidModelObject extends ModelObject {
1500
+ readonly kind: FluidKind;
1501
+ private readonly sample;
1502
+ private geometry?;
1503
+ constructor(kind: FluidKind, sample: FluidSampler, origin?: AssetKey, options?: Partial<ModelObjectOptions>);
1504
+ protected createMeshes(): void;
1505
+ protected applyTextures(): void;
1506
+ disposeAndRemoveAllChildren(): void;
1507
+ }
1508
+
1001
1509
  interface MultiBlockStructure {
1002
1510
  readonly size: TripleArray;
1003
1511
  readonly blocks: MultiBlockBlock[];
1512
+ readonly dataVersion?: number;
1513
+ readonly entities?: MultiBlockEntity[];
1514
+ }
1515
+ interface MultiBlockEntity {
1516
+ position: TripleArray;
1517
+ blockPosition?: TripleArray;
1518
+ nbt: unknown;
1004
1519
  }
1005
1520
  interface MultiBlockBlock extends Block {
1006
1521
  position: TripleArray;
1007
1522
  }
1008
1523
 
1009
1524
  declare class SchematicParser {
1010
- static parse(): Promise<MultiBlockStructure>;
1525
+ static parse(nbt: NBT): Promise<MultiBlockStructure>;
1011
1526
  }
1012
1527
 
1013
1528
  declare class StructureParser {
1014
1529
  static parse(_nbt: NBT, paletteIndex?: number): Promise<MultiBlockStructure>;
1015
1530
  }
1016
1531
  interface StructureNBT {
1017
- DataVersion: {
1532
+ DataVersion?: {
1018
1533
  type: "int";
1019
1534
  value: number;
1020
1535
  };
@@ -1026,7 +1541,13 @@ interface StructureNBT {
1026
1541
  };
1027
1542
  };
1028
1543
  palette?: Palette;
1029
- palettes?: Palette[];
1544
+ palettes?: {
1545
+ type: "list";
1546
+ value: {
1547
+ type: "list";
1548
+ value: Palette["value"][];
1549
+ };
1550
+ };
1030
1551
  blocks: {
1031
1552
  type: "list";
1032
1553
  value: {
@@ -1034,7 +1555,32 @@ interface StructureNBT {
1034
1555
  value: BlockEntry[];
1035
1556
  };
1036
1557
  };
1037
- entities: {};
1558
+ entities?: {
1559
+ type: "list";
1560
+ value: {
1561
+ type: "compound";
1562
+ value: {
1563
+ pos: {
1564
+ type: "list";
1565
+ value: {
1566
+ type: "double";
1567
+ value: TripleArray;
1568
+ };
1569
+ };
1570
+ blockPos: {
1571
+ type: "list";
1572
+ value: {
1573
+ type: "int";
1574
+ value: TripleArray;
1575
+ };
1576
+ };
1577
+ nbt: {
1578
+ type: "compound";
1579
+ value: any;
1580
+ };
1581
+ }[];
1582
+ };
1583
+ };
1038
1584
  }
1039
1585
  interface Palette {
1040
1586
  type: "list";
@@ -1078,14 +1624,17 @@ interface BlockEntry {
1078
1624
  }
1079
1625
 
1080
1626
  declare class NBTHelper {
1081
- static fromBuffer(buffer: Buffer): Promise<NBTAsset>;
1627
+ static fromBuffer(data: Uint8Array | ArrayBuffer, format?: NBTFormat): Promise<NBTAsset>;
1082
1628
  }
1083
1629
  interface NBTAsset extends MinecraftAsset, NBT {
1630
+ format?: NBTFormat;
1631
+ metadata?: Metadata;
1632
+ compression?: "gzip" | "none";
1084
1633
  }
1085
1634
 
1086
1635
  interface ResponseParser<T extends MinecraftAsset> {
1087
- config(request: AxiosRequestConfig): any;
1088
- parse(response: AxiosResponse): Maybe<T> | Promise<Maybe<T>>;
1636
+ config(request: RequestConfig): any;
1637
+ parse(response: RequestResponse): Maybe<T> | Promise<Maybe<T>>;
1089
1638
  }
1090
1639
 
1091
1640
  declare class HostedAssetSource extends AssetSource {
@@ -1104,6 +1653,7 @@ declare class HostedAssetSource extends AssetSource {
1104
1653
  private readonly _options;
1105
1654
  constructor(root: string, options?: Partial<HostedAssetSourceOptions>);
1106
1655
  get root(): string;
1656
+ get cacheId(): string;
1107
1657
  get options(): HostedAssetSourceOptions;
1108
1658
  get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser): Promise<Maybe<T>>;
1109
1659
  }
@@ -1118,6 +1668,8 @@ interface ArchiveEntry {
1118
1668
  }
1119
1669
 
1120
1670
  interface ArchiveProxy {
1671
+ /** Identifies the archive's content across sessions; undefined when it cannot be identified. */
1672
+ readonly id?: string;
1121
1673
  getEntries(): Promise<ArchiveEntry[]>;
1122
1674
  }
1123
1675
 
@@ -1125,6 +1677,7 @@ declare class ArchiveAssetSource extends AssetSource implements ArchiveProxy {
1125
1677
  readonly _archiveProxy: ArchiveProxy;
1126
1678
  constructor(archiveProxy: ArchiveProxy);
1127
1679
  static blob(blob: Blob): ArchiveAssetSource;
1680
+ get cacheId(): Maybe<string>;
1128
1681
  getEntries(): Promise<ArchiveEntry[]>;
1129
1682
  getEntry(path: string): Promise<Maybe<ArchiveEntry>>;
1130
1683
  get<T extends MinecraftAsset>(key: AssetKey, parser: AssetParser | string): Promise<Maybe<T>>;
@@ -1135,7 +1688,8 @@ declare class ArchiveAssetSource extends AssetSource implements ArchiveProxy {
1135
1688
  declare class BrowserArchiveProxy implements ArchiveProxy {
1136
1689
  readonly _blob: Blob;
1137
1690
  readonly _reader: ZipReader<Blob>;
1138
- constructor(blob: Blob);
1691
+ readonly id?: string;
1692
+ constructor(blob: Blob, id?: string);
1139
1693
  getEntries(): Promise<ArchiveEntry[]>;
1140
1694
  }
1141
1695
 
@@ -1213,27 +1767,84 @@ declare class Caching {
1213
1767
  static readonly mergedModelCache: AsyncLoadingCache<CacheKey, Model>;
1214
1768
  static readonly modelTextureAtlasCache: AsyncLoadingCache<CacheKey, TextureAtlas>;
1215
1769
  static readonly blockStateCache: AsyncLoadingCache<CacheKey, BlockState>;
1770
+ static readonly listAssetCache: AsyncLoadingCache<CacheKey, ListAsset>;
1771
+ static readonly defaultBlockStatesCache: AsyncLoadingCache<CacheKey, DefaultBlockStates>;
1772
+ static readonly blockTintCache: AsyncLoadingCache<CacheKey, number>;
1773
+ static readonly entityModelCache: AsyncLoadingCache<CacheKey, EntityModelFile>;
1774
+ static readonly entityTextureCache: AsyncLoadingCache<CacheKey, AssetKey>;
1775
+ static readonly entityAnimationCache: AsyncLoadingCache<CacheKey, EntityAnimationFile>;
1776
+ static readonly blockEntityIndexCache: AsyncLoadingCache<CacheKey, BlockEntityIndex>;
1777
+ private static createAssetCache;
1216
1778
  /** Every cache above, so clear()/end() can never fall out of sync with the field list again. */
1217
1779
  private static get all();
1218
1780
  static clear(): void;
1219
1781
  /**
1220
1782
  * Clears every cache and stops its expiry timer.
1221
1783
  *
1222
- * loading-cache reschedules that timer indefinitely, so a Node process will not exit until
1223
- * this is called - see {@link shutdown}.
1784
+ * Expiry timers are unref'd in Node, so idle processes can exit without this cleanup.
1785
+ * Use {@link shutdown} to also stop requests and the shared Ticker.
1224
1786
  */
1225
1787
  static end(): void;
1226
1788
  static get cacheSizes(): {};
1227
1789
  }
1228
1790
 
1791
+ /** Copies the nontransparent bounds without resizing the source; empty images become one transparent pixel. */
1792
+ declare function trimCanvas(source: CompatCanvas): CompatCanvas;
1793
+
1229
1794
  declare class MineRenderError extends Error {
1230
1795
  constructor(msg: any);
1231
1796
  get name(): string;
1232
1797
  }
1233
1798
 
1234
- declare class GuiObject extends SceneObject {
1799
+ interface SceneGLTFExportOptions {
1800
+ /** Returns a GLB ArrayBuffer instead of a glTF object. */
1801
+ binary?: boolean;
1802
+ /** Maximum width and height of each exported texture, in pixels. */
1803
+ maxTextureSize?: number;
1235
1804
  }
1236
- interface GuiObjectOptions extends SceneObjectOptions {
1805
+ /** Exports the visible meshes at their current poses without changing the source scene. */
1806
+ declare class SceneExporter {
1807
+ /** Returns OBJ geometry with normals and UVs; material files and textures are not included. */
1808
+ static toObj(root: Object3D): string;
1809
+ /** Returns PLY geometry with vertex colors and UVs; texture images are not included. */
1810
+ static toPLY(root: Object3D, options?: PLYExporterOptions): string | ArrayBuffer;
1811
+ /**
1812
+ * Exports a static glTF/GLB snapshot in a browser. Atlas textures and vertex tints are retained;
1813
+ * MineRender's custom directional lighting is not baked into the exported materials.
1814
+ */
1815
+ static toGLTF(root: Object3D, options?: SceneGLTFExportOptions): Promise<Record<string, any> | ArrayBuffer>;
1816
+ }
1817
+
1818
+ declare class GuiHelper {
1819
+ static inventorySlot(slot: number | [number, number], origin?: [number, number], offset?: [number, number], rowSize?: number): [number, number];
1820
+ /** Creates crafting-table layers for ingredients and the result; stack counts are not drawn. */
1821
+ static recipe(recipe: GuiRecipe, options?: GuiRecipeOptions): GuiLayer[];
1822
+ }
1823
+ type GuiRecipeIngredientValue = string | {
1824
+ item: string;
1825
+ } | {
1826
+ tag: string;
1827
+ };
1828
+ type GuiRecipeIngredient = GuiRecipeIngredientValue | readonly GuiRecipeIngredientValue[];
1829
+ type GuiRecipe = ({
1830
+ type: "minecraft:crafting_shaped" | "crafting_shaped";
1831
+ pattern: readonly string[];
1832
+ key: Readonly<Record<string, GuiRecipeIngredient>>;
1833
+ } | {
1834
+ type: "minecraft:crafting_shapeless" | "crafting_shapeless";
1835
+ ingredients: readonly GuiRecipeIngredient[];
1836
+ }) & {
1837
+ result: {
1838
+ id: string;
1839
+ count?: number;
1840
+ } | {
1841
+ item: string;
1842
+ count?: number;
1843
+ };
1844
+ };
1845
+ interface GuiRecipeOptions {
1846
+ /** Selects a concrete item ID or model AssetKey for a tag or alternatives array. */
1847
+ resolveIngredient?: (ingredient: GuiRecipeIngredient) => string | AssetKey;
1237
1848
  }
1238
1849
 
1239
1850
  declare class OrbitControls {
@@ -1328,7 +1939,10 @@ declare class Renderer implements Disposable {
1328
1939
  protected _frameInterval?: number;
1329
1940
  protected _resizeListener?: () => void;
1330
1941
  private _nextFrameTime?;
1942
+ private _running;
1943
+ private _inAnimationLoop;
1331
1944
  private _disposed;
1945
+ private readonly _frameCallbacks;
1332
1946
  private readonly _debugHelpers;
1333
1947
  private readonly _eventDispatchers;
1334
1948
  private readonly _changeListener;
@@ -1349,6 +1963,12 @@ declare class Renderer implements Disposable {
1349
1963
  resize(width: number, height: number): void;
1350
1964
  get dirty(): boolean;
1351
1965
  set dirty(dirty: boolean);
1966
+ /**
1967
+ * Calls a synchronous animation update before each FPS-limited draw while started.
1968
+ * Subscriptions keep the scene drawing without manual dirty flags. Returns an unsubscribe function.
1969
+ * Registering the same callback twice has no effect. Image exports do not invoke callbacks.
1970
+ */
1971
+ onFrame(callback: FrameCallback): () => void;
1352
1972
  start(): void;
1353
1973
  stop(): void;
1354
1974
  /**
@@ -1358,7 +1978,16 @@ declare class Renderer implements Disposable {
1358
1978
  */
1359
1979
  dispose(): void;
1360
1980
  private animate;
1361
- toImage(): string;
1981
+ private drawFrame;
1982
+ /**
1983
+ * Renders a fresh frame and returns an image data URL, including while the animation loop is stopped.
1984
+ * Trimming removes transparent borders; an empty image becomes one transparent pixel.
1985
+ * MIME type support and lossy quality (0–1) follow the canvas encoder.
1986
+ */
1987
+ toImage(trim?: boolean, mime?: string, quality?: number): string;
1988
+ toObj(): string;
1989
+ toPLY(options?: PLYExporterOptions): string | ArrayBuffer;
1990
+ toGLTF(options?: SceneGLTFExportOptions): Promise<Record<string, any> | ArrayBuffer>;
1362
1991
  protected get attachedToBody(): boolean;
1363
1992
  protected get viewWidth(): number;
1364
1993
  protected get viewHeight(): number;
@@ -1369,6 +1998,13 @@ declare class Renderer implements Disposable {
1369
1998
  /** Renderer-owned controls, or undefined when disabled at construction or after disposal. */
1370
1999
  get controls(): Maybe<OrbitControls>;
1371
2000
  }
2001
+ interface RendererFrame {
2002
+ /** Animation-loop timestamp in seconds, relative to the browser's performance time origin. */
2003
+ readonly time: number;
2004
+ /** Seconds since this callback's previous update; zero on its first update after subscribing or starting. */
2005
+ readonly delta: number;
2006
+ }
2007
+ type FrameCallback = (frame: RendererFrame) => void;
1372
2008
  interface RendererOptions {
1373
2009
  camera: CameraOptions;
1374
2010
  render: RenderOptions;
@@ -1396,6 +2032,8 @@ interface CameraOptions {
1396
2032
  interface RenderOptions {
1397
2033
  /** Maximum draw rate (60 by default); zero or a negative value disables the limit. */
1398
2034
  fpsLimit: number;
2035
+ /** Drawing-buffer pixels per CSS pixel (default 1); also scales toImage() output. */
2036
+ pixelRatio?: number;
1399
2037
  stats: boolean;
1400
2038
  antialias: boolean;
1401
2039
  shade: boolean;
@@ -1420,17 +2058,21 @@ declare class SceneInspector {
1420
2058
  protected readonly raycaster: Raycaster;
1421
2059
  private readonly mouse;
1422
2060
  private selectedObject?;
2061
+ private pointer?;
2062
+ private readonly listeners;
1423
2063
  constructor(renderer: Renderer);
1424
2064
  protected init(): void;
2065
+ dispose(): void;
1425
2066
  findMeshChildren(from: Object3D, out?: Mesh[]): Mesh<three.BufferGeometry<three.NormalBufferAttributes>, three.Material | three.Material[], three.Object3DEventMap>[];
1426
- onClick(event: any): void;
2067
+ onClick(event: MouseEvent): void;
1427
2068
  appendTo(el: HTMLElement): void;
1428
2069
  protected handleRaycasterObjects(intersections: Intersection[]): void;
1429
- selectObject(targetObject: Object3D, targetIntersection?: Intersection): void;
1430
- protected redraw(targetObject: Object3D, targetIntersection?: Intersection): void;
1431
- protected addControls(object: Object3D, intersection?: Intersection): void;
2070
+ private getIntersectionInstance;
2071
+ selectObject(targetObject: Object3D, targetIntersection?: Intersection, instance?: Maybe<InstanceReference<SceneObject>>): void;
2072
+ protected redraw(targetObject: Object3D, targetIntersection?: Intersection, instance?: InstanceReference<SceneObject>): void;
2073
+ protected addControls(object: Object3D, intersection?: Intersection, instance?: InstanceReference<SceneObject>): void;
1432
2074
  protected addInfoLine(name: string, id: string, value: any): HTMLElement;
1433
- protected addObjectControls(target: Object3D, intersection: Maybe<Intersection>, container: HTMLElement): void;
2075
+ protected addObjectControls(target: Object3D, intersection: Maybe<Intersection>, container: HTMLElement, instance?: InstanceReference<SceneObject>): void;
1434
2076
  protected buttonControl(name: string, id: string, click: () => void): HTMLElement;
1435
2077
  protected selectControl(name: string, id: string, options: string[], change: (v: string) => void): HTMLElement;
1436
2078
  protected toggleControl(name: string, id: string, val: boolean, change: (v: boolean) => void): HTMLElement;
@@ -1438,13 +2080,15 @@ declare class SceneInspector {
1438
2080
  protected separator(name?: string): HTMLElement;
1439
2081
  }
1440
2082
 
1441
- declare class SceneStatsDisplay {
2083
+ declare class SceneStatsDisplay implements Disposable {
1442
2084
  readonly renderer: Renderer;
1443
2085
  readonly statsContainer: HTMLDivElement;
1444
2086
  private readonly lines;
2087
+ private interval?;
1445
2088
  constructor(renderer: Renderer);
1446
2089
  protected init(): void;
1447
2090
  appendTo(el: HTMLElement): void;
2091
+ dispose(): void;
1448
2092
  add(line?: StatLine): void;
1449
2093
  }
1450
2094
  declare class StatLine {
@@ -1459,34 +2103,33 @@ declare class StatLine {
1459
2103
  update(): void;
1460
2104
  }
1461
2105
 
1462
- declare class Requests {
1463
- private static axiosInstance;
1464
- private static mcAssetInstance;
1465
- private static genericQueue;
1466
- private static mcAssetRequestQueue;
1467
- static genericRequest(request: AxiosRequestConfig): Promise<AxiosResponse>;
1468
- static mcAssetRequest(request: AxiosRequestConfig): Promise<AxiosResponse>;
1469
- private static shouldRetry;
1470
- static setMcAssetRoot(root: string): void;
1471
- static get queueSizes(): {
1472
- generic: number;
1473
- mcAsset: number;
1474
- };
1475
- /**
1476
- * Stops both queue timers. jobqu reschedules itself indefinitely, so a Node process will not
1477
- * exit until this is called - see {@link shutdown}.
1478
- */
1479
- static end(): void;
1480
- }
1481
-
1482
2106
  type SkinGeometries = Record<SkinPart, TripleArray>;
1483
2107
  declare const classicSkinGeometries: SkinGeometries;
1484
2108
  declare const slimSkinGeometries: SkinGeometries;
1485
2109
 
2110
+ declare class SkinImage {
2111
+ static getData(src: string): Promise<ImageData>;
2112
+ private static decodePng;
2113
+ }
2114
+
1486
2115
  type SkinTextureCoordinates = Record<SkinPart, ModelFaces>;
1487
2116
  declare const classicSkinTextureCoordinates: Readonly<SkinTextureCoordinates>;
1488
2117
  declare const slimSkinTextureCoordinates: Readonly<SkinTextureCoordinates>;
1489
2118
 
2119
+ interface SkinTexture {
2120
+ material: MeshBasicMaterial;
2121
+ slim: boolean;
2122
+ legacy: boolean;
2123
+ }
2124
+ declare class SkinTextures {
2125
+ static get(src: string, legacy?: boolean): Promise<SkinTexture>;
2126
+ static getCape(src: string, layout?: CapeLayout): Promise<MeshBasicMaterial>;
2127
+ private static createMaterial;
2128
+ private static isSlim;
2129
+ private static normalizeLegacy;
2130
+ private static makeBaseOpaque;
2131
+ }
2132
+
1490
2133
  declare class Skins {
1491
2134
  static fromUuidOrUsername(uuidOrUsername: string): Promise<Maybe<string>>;
1492
2135
  static fromUuid(uuid: string): Promise<Maybe<string>>;
@@ -1495,8 +2138,11 @@ declare class Skins {
1495
2138
  static capeFromUuidOrUsername(uuidOrUsername: string): Promise<Maybe<string>>;
1496
2139
  static capeFromUuid(uuid: string): Promise<Maybe<string>>;
1497
2140
  static capeFromUsername(username: string): Promise<Maybe<string>>;
1498
- static capeFromCapesDev(uuid: string, capeType?: string): Promise<Maybe<string>>;
2141
+ /** Returns a full static cape texture for a username or UUID. */
2142
+ static capeFromCapesDev(player: string, capeType?: string): Promise<Maybe<string>>;
1499
2143
  private static usernameToUuid;
2144
+ private static usernameToUuidMcProxy;
2145
+ /** @deprecated **/
1500
2146
  private static usernameToUuidSkinProxy;
1501
2147
  private static usernameToUuidMineTools;
1502
2148
  private static getProfileFromMinetools;
@@ -1506,11 +2152,18 @@ declare class Skins {
1506
2152
  private static getCrafatarCapeUrl;
1507
2153
  private static getMcHeadsSkinUrl;
1508
2154
  private static getMineSkinPlayerSkinUrl;
2155
+ /** @deprecated **/
1509
2156
  private static getSkinProxySkinUrl;
2157
+ /** @deprecated **/
1510
2158
  private static getSkinProxyCapeUrl;
2159
+ private static getMcProxySkinUrl;
2160
+ private static getMcProxyCapeUrl;
1511
2161
  }
1512
2162
 
1513
2163
  declare class TextureLoader {
2164
+ private static readonly failedTextures;
2165
+ /** Reports whether image loading failed, so cached textures can be retried. */
2166
+ static hasFailed(texture: Texture): boolean;
1514
2167
  protected static createTexture(): Texture;
1515
2168
  static loadInBackground(src: string, format?: PixelFormat, rotation?: number): Texture;
1516
2169
  static load(src: string, format?: PixelFormat, rotation?: number): Texture;
@@ -1532,61 +2185,155 @@ declare function mergeVertices(geometry: BufferGeometry, tolerance?: number): Bu
1532
2185
  declare function toTrianglesDrawMode(geometry: BufferGeometry, drawMode: TrianglesDrawModes): BufferGeometry;
1533
2186
  declare function computeMorphedAttributes(object: Mesh | Line | Points): object;
1534
2187
 
1535
- interface BlockInfo {
1536
- block: Block;
1537
- object: BlockObject;
2188
+ declare class ChunkData {
2189
+ private readonly indices;
2190
+ private readonly palette;
2191
+ private readonly paletteIds;
2192
+ private readonly freeIds;
2193
+ private readonly nbt;
2194
+ get(index: number): Maybe<Block>;
2195
+ snapshot(index: number): Maybe<() => Block>;
2196
+ set(index: number, block?: Block): void;
2197
+ clear(): void;
2198
+ static isAir(block: Maybe<Block>): boolean;
2199
+ private static copyBlock;
2200
+ private static validateIndex;
2201
+ }
2202
+
2203
+ type RegionInput = Uint8Array | ArrayBuffer;
2204
+ interface AnvilRegion {
2205
+ chunks: AnvilChunk[];
2206
+ }
2207
+ interface AnvilChunk {
2208
+ x: number;
2209
+ z: number;
2210
+ dataVersion?: number;
2211
+ sections: {
2212
+ y: number;
2213
+ data: ChunkData;
2214
+ }[];
2215
+ entities?: MultiBlockEntity[];
2216
+ }
2217
+ declare class AnvilParser {
2218
+ static getChunkList(data: RegionInput): {
2219
+ x: number;
2220
+ z: number;
2221
+ }[];
2222
+ static parse(data: RegionInput): Promise<AnvilRegion>;
2223
+ static parseChunk(data: RegionInput, localX: number, localZ: number): Promise<AnvilChunk | undefined>;
2224
+ private static bytes;
2225
+ private static locations;
2226
+ private static readChunk;
2227
+ private static compounds;
2228
+ private static integer;
2229
+ private static block;
2230
+ private static unpack;
2231
+ }
2232
+
2233
+ interface BlockInfo<SectionMeshing extends boolean = false> {
2234
+ /** Detached block data; use world or chunk setters to update stored blocks. */
2235
+ readonly block: Block;
2236
+ /** Merged terrain has no individual render object in section-meshing mode. */
2237
+ object: SectionMeshing extends false ? BlockObject : BlockObject | undefined;
2238
+ }
2239
+
2240
+ interface SectionMeshTemplate {
2241
+ geometry: BufferGeometry;
2242
+ atlas: TextureAtlas;
2243
+ cullFaces: readonly number[];
2244
+ }
2245
+ interface SectionMeshEntry {
2246
+ index: number;
2247
+ template: SectionMeshTemplate;
2248
+ cullMask: number;
2249
+ }
2250
+ declare class SectionMesh extends Group {
2251
+ private readonly ownedMeshes;
2252
+ static build(entries: readonly SectionMeshEntry[], maxAtlasSize?: number): SectionMesh;
2253
+ dispose(): void;
2254
+ }
2255
+
2256
+ declare class SectionModels {
2257
+ readonly maxAtlasSize: number;
2258
+ private states;
2259
+ private models;
2260
+ private readonly templates;
2261
+ constructor(maxAtlasSize?: number);
2262
+ get(blockState: BlockState, properties?: BlockStateProperties): Promise<SectionMeshTemplate | undefined>;
2263
+ private prepare;
2264
+ clear(): void;
1538
2265
  }
1539
2266
 
1540
- declare class Chunk {
2267
+ declare class Chunk<SectionMeshing extends boolean = false> {
2268
+ private readonly onBlocksChanged?;
2269
+ private readonly sectionModels?;
1541
2270
  readonly scene: MineRenderScene;
1542
2271
  readonly x: number;
1543
2272
  readonly y: number;
1544
2273
  readonly z: number;
1545
- private readonly _blocks;
1546
- private readonly _anchor;
1547
- constructor(scene: MineRenderScene, x: number, y: number, z: number);
1548
- getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo>;
1549
- getBlockAt(pos: Vector3): Maybe<BlockInfo>;
1550
- getBlockAt(pos: TripleArray): Maybe<BlockInfo>;
2274
+ private readonly data;
2275
+ private readonly renderedBlocks;
2276
+ private readonly sectionBlocks;
2277
+ private sectionMesh?;
2278
+ private meshDirty;
2279
+ constructor(scene: MineRenderScene, x: number, y: number, z: number, onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined, sectionModels?: SectionModels | undefined);
2280
+ getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo<SectionMeshing>>;
2281
+ getBlockAt(pos: Vector3): Maybe<BlockInfo<SectionMeshing>>;
2282
+ getBlockAt(pos: TripleArray): Maybe<BlockInfo<SectionMeshing>>;
1551
2283
  /**
1552
2284
  * Set block at a _world_ position
1553
2285
  */
1554
- setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
1555
- setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
1556
- setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo>>;
2286
+ setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;
2287
+ setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;
2288
+ setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;
1557
2289
  /**
1558
- * Set block at a _chunk_ position (0-16)
2290
+ * Set a block at integer chunk-local coordinates from 0 to 15.
1559
2291
  */
1560
- setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3): Promise<Maybe<BlockInfo>>;
1561
- clear(): Promise<void>;
2292
+ setBlockInChunkAt(pos: Vector3, block?: Block, worldPos?: Vector3, onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined): Promise<Maybe<BlockInfo<SectionMeshing>>>;
2293
+ isOccludingAt(pos: Vector3): boolean;
2294
+ setCullMaskAt(pos: Vector3, mask: number): Promise<void>;
2295
+ rebuildSectionMesh(): void;
2296
+ clear(onBlocksChanged?: ((positions: Vector3[]) => Promise<void>) | undefined): Promise<void>;
1562
2297
  dispose(): Promise<void>;
2298
+ static isAir(block: Maybe<Block>): boolean;
1563
2299
  static chunkPosToBlockIndex(pos: Vector3): number;
1564
2300
  worldPosToChunkPos(pos: Vector3): Vector3;
1565
2301
  chunkPosToWorldPos(pos: Vector3): Vector3;
1566
2302
  }
1567
2303
 
1568
- declare class MineRenderWorld {
2304
+ declare class MineRenderWorld<SectionMeshing extends boolean = false> {
1569
2305
  readonly scene: MineRenderScene;
1570
- private _size;
1571
- private _blockSize;
1572
2306
  private readonly _chunks;
1573
- constructor(scene: MineRenderScene);
1574
- getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo>;
1575
- getBlockAt(pos: Vector3): Maybe<BlockInfo>;
1576
- getBlockAt(pos: TripleArray): Maybe<BlockInfo>;
1577
- setBlockAt(x: number, y: number, z: number, block: Block): Promise<Maybe<BlockInfo>>;
1578
- setBlockAt(pos: Vector3, block: Block): Promise<Maybe<BlockInfo>>;
1579
- setBlockAt(pos: TripleArray, block: Block): Promise<Maybe<BlockInfo>>;
2307
+ private readonly sectionModels?;
2308
+ private readonly pendingCulling;
2309
+ private culling?;
2310
+ constructor(scene: MineRenderScene, options?: MineRenderWorldOptions<SectionMeshing>);
2311
+ getBlockAt(x: number, y: number, z: number): Maybe<BlockInfo<SectionMeshing>>;
2312
+ getBlockAt(pos: Vector3): Maybe<BlockInfo<SectionMeshing>>;
2313
+ getBlockAt(pos: TripleArray): Maybe<BlockInfo<SectionMeshing>>;
2314
+ setBlockAt(x: number, y: number, z: number, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;
2315
+ setBlockAt(pos: Vector3, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;
2316
+ setBlockAt(pos: TripleArray, block: Maybe<Block>): Promise<Maybe<BlockInfo<SectionMeshing>>>;
2317
+ private placeBlock;
1580
2318
  placeMultiBlock(multiblock: MultiBlockStructure, useBatches?: boolean, executor?: BatchedExecutor): Promise<void>;
2319
+ private placeBlocks;
2320
+ /** Replaces one chunk column's blocks. Entity NBT remains available on the parsed chunk. */
2321
+ placeChunk(chunk: AnvilChunk, executor?: BatchedExecutor): Promise<void>;
1581
2322
  clear(): Promise<void>;
2323
+ private updateCulling;
1582
2324
  private getOrCreateChunkAt;
1583
- getChunkAt(pos: Vector3): Maybe<Chunk>;
2325
+ getChunkAt(pos: Vector3): Maybe<Chunk<SectionMeshing>>;
1584
2326
  static worldToScenePosition(pos: Vector3): Vector3;
1585
2327
  static sceneToWorldPosition(pos: Vector3): Vector3;
1586
- worldPosToChunkIndex(pos: Vector3): number;
1587
2328
  worldPosToChunkKey(pos: Vector3): string;
1588
2329
  validatePosBounds(pos: Vector3): void;
1589
2330
  }
2331
+ interface MineRenderWorldOptions<SectionMeshing extends boolean = boolean> {
2332
+ /** Merge static opaque cubes into section meshes. Merged blocks have no individual object. */
2333
+ sectionMeshing?: SectionMeshing;
2334
+ /** Maximum width and height of each section atlas page, in pixels. */
2335
+ maxAtlasSize?: number;
2336
+ }
1590
2337
 
1591
2338
  /**
1592
2339
  * {@link EnvProvider} backed by the DOM. Uses nothing outside of standard browser APIs and
@@ -1620,8 +2367,8 @@ declare class BrowserCache extends PersistentCache<LocalForage> {
1620
2367
  *
1621
2368
  * `image-size` pulls in `fs`/`path` at module scope, so it can only live in the Node build.
1622
2369
  * Everything MineRender loads is a PNG in practice; GIF and JPEG are handled as a courtesy and
1623
- * anything else falls through to an empty result (callers treat that as 0x0).
2370
+ * anything else falls through to an empty result, which ImageLoader rejects.
1624
2371
  */
1625
2372
  declare function probeImageSize(data: Uint8Array): ImageSizeInfo;
1626
2373
 
1627
- export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, ArchiveAssetSource, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type Block, BlockEntityModels, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, type BlockStateVariant, type BlockStateVariants, BlockStates, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, type CacheKey, Caching, type CameraOptions, CanvasImage, Chunk, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsOptions, type Cube, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, type DebugOptions, type DeepPartial, DefaultBlockStates, DisplayPosition, type Disposable, type DoubleArray, type ElementFace, type ElementRotation, Entities, type EntityModel, EntityModels, EntityObject, type EntityObjectOptions, Env, type EnvProvider, type ExtractableImageData, type FromTo, Geometries, GuiLight, GuiObject, type GuiObjectOptions, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, type ItemModel, type ItemModelTextures, type ListAsset, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, type ModelPart, ModelTextures, Models, type MultiBlockBlock, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, PersistentCache, type QuadArray, type RawImageKey, type RenderOptions, Renderer, type RendererOptions, Requests, type ResponseParser, SKIN_PARTS, SceneInspector, SceneObject, type SceneObjectOptions, SceneStats, SceneStatsDisplay, SchematicParser, type Serializable, type SkinGeometries, SkinObject, type SkinObjectOptions, SkinPart, type SkinTextureCoordinates, Skins, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, applyModelPartRotation, axisToVec3, base64decode, base64encode, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, createCanvas, createImage, estimateBytesUsed, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isSceneObject, isTransformable, isTripleArray, isVector3, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, prefix, probeImageSize, registerBrowserEnv, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode };
2374
+ export { AXES, type AnimationFrame, type AnimationMeta, type AnimatorFunction, type AnvilChunk, AnvilParser, type AnvilRegion, ArchiveAssetSource, type ArchiveEntry, type ArchiveProxy, AssetKey, AssetLoadError, AssetLoader, AssetParser, AssetSource, type AssetType, Assets, Axis, BUILTIN_ENTITY, BUILTIN_GENERATED, BasicAssetKey, type BasicMinecraftAsset, BatchedExecutor, type BedrockBone, type BedrockCube, type BedrockEntityDescription, type BedrockEntityFile, type BedrockGeometry, type BedrockGeometryFile, type Block, BlockEntities, type BlockEntityEntry, type BlockEntityIndex, type BlockEntityPart, type BlockEntityRotation, type BlockFluidState, type BlockInfo, type BlockModel, type BlockModelTextures, BlockObject, type BlockObjectOptions, type BlockState, type BlockStateMultipart, type BlockStateProperties, type BlockStateProperty, type BlockStatePropertyDefaults, type BlockStatePropertyValue, BlockStateResolver, type BlockStateVariant, type BlockStateVariants, BlockStates, BlockTints, type BoxGeometryKey, BrowserArchiveProxy, BrowserCache, BrowserEnv, CUBE_FACES, CUBE_FACE_OFFSETS, type CacheKey, Caching, type CameraOptions, CanvasImage, type CapeLayout, Chunk, ChunkData, type CompatCanvas, type CompatImage, type ComposerOptions, type ControlsOptions, CubeFace, CubeFaceIndex, DEFAULT_ELEMENTS, DEFAULT_NAMESPACE, DEFAULT_ROOT, DEFAULT_UV, DISPLAY_POSITIONS, type DebugOptions, type DeepPartial, DefaultBlockStates, DisplayPosition, DisplayTransforms, type Disposable, type DoubleArray, ENTITY_ANIMATION_CHANNELS, type ElementFace, type ElementRotation, Entities, type EntityAnimation, type EntityAnimationBone, type EntityAnimationChannel, type EntityAnimationFile, type EntityAnimationKeyframe, type EntityAnimationOptions, EntityAnimationPlayer, type EntityAnimationPose, type EntityLayer, type EntityModel, type EntityModelCube, type EntityModelFile, type EntityModelLayer, type EntityModelOptions, type EntityModelPart, type EntityModelPass, EntityObject, type EntityObjectOptions, type EntityRenderMode, type EntityTransformOp, Env, type EnvProvider, type ExtractableImageData, type FluidKind, FluidModelObject, type FluidSample, type FluidSampler, type FrameCallback, type FromTo, Geometries, GuiHelper, type GuiItemLayer, type GuiLayer, GuiLight, GuiObject, type GuiObjectOptions, type GuiRecipe, type GuiRecipeIngredient, type GuiRecipeOptions, type GuiTextureLayer, HostedAssetSource, type IModelTextures, ITEM_GENERATED, type ImageInfo, ImageLoader, type ImageSizeInfo, InstanceManager, InstanceReference, type Instanceable, type ItemModel, type ItemModelTextures, type ListAsset, MapControls, type MaterialKey, Materials, type Maybe, type MeshKey, Meshes, MineRenderError, MineRenderScene, type MineRenderSceneOptions, MineRenderWorld, type MineRenderWorldOptions, type MinecraftAsset, MinecraftCubeTexture, MinecraftFaceUV, type MinecraftTextureMeta, type Model, ModelCulling, type ModelDisplay, type ModelElement, type ModelFaces, ModelGenerator, ModelMerger, ModelObject, type ModelObjectOptions, ModelTextures, Models, type MultiBlockBlock, type MultiBlockEntity, type MultiBlockStructure, type MultipartCondition, type NBTAsset, NBTHelper, OrbitControls, PersistentCache, type QuadArray, type RawImageKey, type RenderOptions, Renderer, type RendererFrame, type RendererOptions, type RequestConfig, RequestError, type RequestResponse, Requests, type ResolvedBlockEntity, type ResponseParser, SKIN_PARTS, SceneExporter, type SceneGLTFExportOptions, SceneInspector, SceneObject, type SceneObjectOptions, SceneStats, SceneStatsDisplay, SchematicParser, SectionMesh, type SectionMeshEntry, type SectionMeshTemplate, SectionModels, type Serializable, type SkinGeometries, SkinImage, SkinObject, type SkinObjectOptions, SkinPart, type SkinTexture, type SkinTextureCoordinates, SkinTextures, Skins, type SpecialItemPart, type SpecialItemRenderer, SpecialItems, type StructureNBT, StructureParser, type TextureAsset, TextureAtlas, type TextureKey, TextureLoader, Textures, Ticker, type TickerFunction, TintColors, type Transformable, type TripleArray, UVMapper, WrappedImage, addBox3WireframeToObject, addWireframeToMesh, addWireframeToObject, applyElementRotation, applyGenericRotation, axisToVec3, base64decode, base64encode, capeTextureSizes, captureException, changeEvent, clampRotationDegrees, classicSkinGeometries, classicSkinTextureCoordinates, computeMorphedAttributes, createCanvas, createFluidGeometry, createImage, entityAnimationTime, estimateBytesUsed, getBlockFluidState, getFluidKind, interleaveAttributes, isAssetKey, isBasicAssetKey, isBlockObject, isDisposable, isDoubleArray, isEntityObject, isGuiObject, isInstanceManager, isInstanceReference, isInstanceable, isInstancedMesh, isMesh, isMineRenderScene, isModelObject, isObject3D, isOrthographicCamera, isPerspectiveCamera, isQuadArray, isSceneObject, isTransformable, isTripleArray, isVector3, md5, mergeBufferAttributes, mergeBufferGeometries, mergeVertices, prefix, probeImageSize, registerBrowserEnv, sampleEntityAnimation, sampleEntityKeyframes, sampleFluid, serializeBoxGeometryKey, serializeImageKey, serializeMaterialKey, serializeMeshKey, serializeTextureKey, sha1, sha256, sha512, shutdown, sleep, slimSkinGeometries, slimSkinTextureCoordinates, timingEnd, timingStart, toDegrees, toRadians, toTrianglesDrawMode, trimCanvas };