minerender 2.1.0-alpha.23 → 2.1.0-alpha.25

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.
@@ -137,7 +137,6 @@ __export(index_node_exports, {
137
137
  BUILTIN_GENERATED: () => BUILTIN_GENERATED,
138
138
  BasicAssetKey: () => BasicAssetKey,
139
139
  BatchedExecutor: () => BatchedExecutor,
140
- BlockEntityModels: () => BlockEntityModels,
141
140
  BlockObject: () => BlockObject,
142
141
  BlockStates: () => BlockStates,
143
142
  BlockTints: () => BlockTints,
@@ -157,7 +156,6 @@ __export(index_node_exports, {
157
156
  DisplayPosition: () => DisplayPosition,
158
157
  DisplayTransforms: () => DisplayTransforms,
159
158
  Entities: () => Entities,
160
- EntityModels: () => EntityModels,
161
159
  EntityObject: () => EntityObject,
162
160
  Env: () => Env,
163
161
  Geometries: () => Geometries,
@@ -211,7 +209,6 @@ __export(index_node_exports, {
211
209
  addWireframeToObject: () => addWireframeToObject,
212
210
  applyElementRotation: () => applyElementRotation,
213
211
  applyGenericRotation: () => applyGenericRotation,
214
- applyModelPartRotation: () => applyModelPartRotation,
215
212
  axisToVec3: () => axisToVec3,
216
213
  base64decode: () => base64decode,
217
214
  base64encode: () => base64encode,
@@ -562,7 +559,10 @@ var Caching = class _Caching {
562
559
  this.blockTintCache = _Caching.createAssetCache();
563
560
  }
564
561
  static {
565
- this.entityModelsCache = _Caching.createAssetCache();
562
+ this.entityModelCache = _Caching.createAssetCache();
563
+ }
564
+ static {
565
+ this.entityTextureCache = _Caching.createAssetCache();
566
566
  }
567
567
  static createAssetCache() {
568
568
  return import_loading_cache.Caches.builder().expireAfterWrite(import_time.Time.minutes(10)).expireAfterAccess(import_time.Time.minutes(5)).expirationInterval(import_time.Time.seconds(30)).buildAsync();
@@ -587,7 +587,8 @@ var Caching = class _Caching {
587
587
  this.listAssetCache,
588
588
  this.defaultBlockStatesCache,
589
589
  this.blockTintCache,
590
- this.entityModelsCache
590
+ this.entityModelCache,
591
+ this.entityTextureCache
591
592
  ];
592
593
  }
593
594
  static clear() {
@@ -1697,14 +1698,6 @@ function applyElementRotation(rotation, geometry) {
1697
1698
  }
1698
1699
  geometry.translate(origin.x, origin.y, origin.z);
1699
1700
  }
1700
- function applyModelPartRotation(modelPart, geometry) {
1701
- const origin = new import_three8.Vector3(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1702
- geometry.translate(-origin.x, -origin.y, -origin.z);
1703
- geometry.rotateX(toRadians(modelPart.pitch));
1704
- geometry.rotateY(toRadians(modelPart.yaw));
1705
- geometry.rotateZ(toRadians(modelPart.roll));
1706
- geometry.translate(origin.x, origin.y, origin.z);
1707
- }
1708
1701
  function applyGenericRotation(axis, rotation, obj) {
1709
1702
  switch (axis) {
1710
1703
  case "x" /* X */:
@@ -2761,18 +2754,18 @@ var MinecraftCubeTexture = class {
2761
2754
  }
2762
2755
  getUvEast(w, h, l) {
2763
2756
  return [
2764
- [this.mapW(this.u), this.mapH(this.v + l + h)],
2765
- [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2766
- [this.mapW(this.u), this.mapH(this.v + l)],
2767
- [this.mapW(this.u + l), this.mapH(this.v + l)]
2757
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2758
+ [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
2759
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
2760
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)]
2768
2761
  ];
2769
2762
  }
2770
2763
  getUvWest(w, h, l) {
2771
2764
  return [
2772
- [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
2773
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2774
- [this.mapW(this.u + l + w), this.mapH(this.v + l)],
2775
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
2765
+ [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2766
+ [this.mapW(this.u), this.mapH(this.v + l + h)],
2767
+ [this.mapW(this.u + l), this.mapH(this.v + l)],
2768
+ [this.mapW(this.u), this.mapH(this.v + l)]
2776
2769
  ];
2777
2770
  }
2778
2771
  getUvUp(w, h, l) {
@@ -2785,26 +2778,26 @@ var MinecraftCubeTexture = class {
2785
2778
  }
2786
2779
  getUvDown(w, h, l) {
2787
2780
  return [
2788
- [this.mapW(this.u + l), this.mapH(this.v + l)],
2789
- [this.mapW(this.u + l + w), this.mapH(this.v + l)],
2790
2781
  [this.mapW(this.u + l), this.mapH(this.v)],
2791
- [this.mapW(this.u + l + w), this.mapH(this.v)]
2782
+ [this.mapW(this.u + l + w), this.mapH(this.v)],
2783
+ [this.mapW(this.u + l), this.mapH(this.v + l)],
2784
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)]
2792
2785
  ];
2793
2786
  }
2794
2787
  getUvSouth(w, h, l) {
2795
2788
  return [
2796
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2797
2789
  [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l + h)],
2798
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
2799
- [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)]
2790
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2791
+ [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
2792
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
2800
2793
  ];
2801
2794
  }
2802
2795
  getUvNorth(w, h, l) {
2803
2796
  return [
2804
- [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2805
2797
  [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
2806
- [this.mapW(this.u + l), this.mapH(this.v + l)],
2807
- [this.mapW(this.u + l + w), this.mapH(this.v + l)]
2798
+ [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2799
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)],
2800
+ [this.mapW(this.u + l), this.mapH(this.v + l)]
2808
2801
  ];
2809
2802
  }
2810
2803
  getFaceUv(face, w, h, l) {
@@ -2823,10 +2816,12 @@ var MinecraftCubeTexture = class {
2823
2816
  return this.getUvNorth(w, h, l);
2824
2817
  }
2825
2818
  }
2826
- toUvArray(w, h, l) {
2819
+ toUvArray(w, h, l, mirror = false) {
2827
2820
  const uv = [];
2828
2821
  for (let i = 0; i < CUBE_FACES.length; i++) {
2829
- UVMapper.setFaceUvInArray(uv, i * 4, this.getFaceUv(CUBE_FACES[i], w, h, l));
2822
+ const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
2823
+ const corners = this.getFaceUv(face, w, h, l);
2824
+ UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
2830
2825
  }
2831
2826
  return uv;
2832
2827
  }
@@ -2856,69 +2851,79 @@ function shutdown() {
2856
2851
  Caching.end();
2857
2852
  }
2858
2853
 
2859
- // src/assets/Entities.ts
2860
- var Entities = class {
2861
- static async getBlockEntityModels() {
2862
- const key = AssetKey.parse("models", "minerender:blockEntityModels");
2863
- console.log(key);
2864
- return Caching.entityModelsCache.get(key.serialize(), () => {
2865
- return AssetLoader.get(key, "json" /* JSON */);
2866
- });
2867
- }
2868
- static async getEntityModels() {
2869
- const key = AssetKey.parse("models", "minerender:entityModels");
2870
- console.log(key);
2871
- return Caching.entityModelsCache.get(key.serialize(), () => {
2872
- return AssetLoader.get(key, "json" /* JSON */);
2873
- });
2854
+ // src/error/MineRenderError.ts
2855
+ var MineRenderError = class _MineRenderError extends Error {
2856
+ constructor(msg) {
2857
+ super(msg);
2858
+ Object.setPrototypeOf(this, _MineRenderError.prototype);
2874
2859
  }
2875
- // BlockEntity names are hardcoded
2876
- static async getBlockList() {
2877
- const models = await this.getBlockEntityModels();
2878
- if (!models) {
2879
- return [];
2880
- }
2881
- return Object.keys(models);
2860
+ get name() {
2861
+ return "MineRenderError";
2882
2862
  }
2863
+ };
2864
+
2865
+ // src/assets/Entities.ts
2866
+ var Entities = class {
2883
2867
  static async getEntityList() {
2884
- const models = await this.getEntityModels();
2885
- if (!models) {
2886
- return [];
2887
- }
2888
- return Object.keys(models);
2889
- }
2890
- static async getBlock(modelKey, textureKey) {
2891
- const models = await this.getBlockEntityModels();
2892
- if (!models) {
2893
- return void 0;
2894
- }
2895
- if (!textureKey) {
2896
- textureKey = modelKey;
2897
- }
2898
- const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
2899
- return {
2900
- key: textureKey,
2901
- parts: models[baseKey.toNamespacedString()]
2868
+ const collect = async (path) => {
2869
+ const prefix2 = path ? `${path}/` : "";
2870
+ const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
2871
+ const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
2872
+ if (!list) return [];
2873
+ const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
2874
+ const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
2875
+ return [...files, ...children.flat()];
2902
2876
  };
2877
+ return collect("");
2878
+ }
2879
+ static async getEntity(modelKey, textureKey, options) {
2880
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
2881
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
2882
+ const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
2883
+ if (!model) return void 0;
2884
+ const layerName = options?.layer ?? "main";
2885
+ const layer = model.layers[layerName];
2886
+ if (!layer) {
2887
+ throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
2888
+ }
2889
+ let texture;
2890
+ if (textureKey) {
2891
+ const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
2892
+ texture = isAssetKey(textureKey) && textureKey.assetType === "textures" && path2.startsWith("entity/") ? textureKey : new AssetKey(textureKey.namespace, path2, "textures", "entity", "assets", ".png", isAssetKey(textureKey) ? textureKey.root : void 0);
2893
+ } else {
2894
+ texture = await this.resolveTexture(modelKey);
2895
+ }
2896
+ return { key: textureKey ?? modelKey, texture, layer, id: model.id };
2897
+ }
2898
+ static async resolveTexture(modelKey) {
2899
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
2900
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
2901
+ return Caching.entityTextureCache.get(key.serialize(), async () => {
2902
+ const name = path.split("/").pop();
2903
+ for (const candidate of [path, `${path}/${name}`]) {
2904
+ const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
2905
+ if (await ModelTextures.get(texture)) return texture;
2906
+ }
2907
+ const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json");
2908
+ const list = await AssetLoader.get(listKey, "list" /* LIST */);
2909
+ const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
2910
+ const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
2911
+ if (!file) return void 0;
2912
+ const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json");
2913
+ const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
2914
+ const assets = variant?.assets;
2915
+ const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
2916
+ return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
2917
+ });
2903
2918
  }
2904
- static async getEntity(modelKey, textureKey) {
2905
- const models = await this.getEntityModels();
2906
- if (!models) {
2907
- return void 0;
2908
- }
2909
- if (!textureKey) {
2910
- textureKey = modelKey;
2911
- }
2912
- const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
2913
- return {
2914
- key: textureKey,
2915
- parts: models[baseKey.toNamespacedString()]
2916
- };
2919
+ /** @deprecated Use getEntityList(); block entities share the entity dataset. */
2920
+ static getBlockList() {
2921
+ return this.getEntityList();
2922
+ }
2923
+ /** @deprecated Use getEntity(); block entities share the entity dataset. */
2924
+ static getBlock(modelKey, textureKey, options) {
2925
+ return this.getEntity(modelKey, textureKey, options);
2917
2926
  }
2918
- };
2919
- var EntityModels = class {
2920
- };
2921
- var BlockEntityModels = class {
2922
2927
  };
2923
2928
 
2924
2929
  // src/renderer/SceneObject.ts
@@ -2967,17 +2972,6 @@ function isInstanceReference(obj) {
2967
2972
  return obj.isInstanceReference;
2968
2973
  }
2969
2974
 
2970
- // src/error/MineRenderError.ts
2971
- var MineRenderError = class _MineRenderError extends Error {
2972
- constructor(msg) {
2973
- super(msg);
2974
- Object.setPrototypeOf(this, _MineRenderError.prototype);
2975
- }
2976
- get name() {
2977
- return "MineRenderError";
2978
- }
2979
- };
2980
-
2981
2975
  // src/renderer/SceneObject.ts
2982
2976
  var import_ts_deepmerge3 = __toESM(require_dist());
2983
2977
  var p6 = prefix("SceneObject");
@@ -3111,15 +3105,8 @@ var SceneObject = class _SceneObject extends import_three10.Object3D {
3111
3105
  return this.toggleObjectVisibility(this.getMeshByName(name), visible);
3112
3106
  }
3113
3107
  iterateAllMeshes(cb) {
3114
- this.children.forEach((obj) => {
3115
- if (obj.isMesh) {
3116
- cb(obj);
3117
- }
3118
- obj.children.forEach((obj1) => {
3119
- if (obj1.isMesh) {
3120
- cb(obj1);
3121
- }
3122
- });
3108
+ this.traverse((obj) => {
3109
+ if (isMesh(obj)) cb(obj);
3123
3110
  });
3124
3111
  }
3125
3112
  //</editor-fold>
@@ -3357,17 +3344,16 @@ function isSceneObject(obj) {
3357
3344
  // src/entity/scene/EntityObject.ts
3358
3345
  var import_ts_deepmerge4 = __toESM(require_dist());
3359
3346
  var import_three12 = require("three");
3360
- var THREE3 = __toESM(require("three"));
3361
- var EntityObject = class extends SceneObject {
3347
+ var EntityObject = class _EntityObject extends SceneObject {
3362
3348
  constructor(entity, options) {
3363
3349
  super();
3364
3350
  this.entity = entity;
3365
3351
  this.isEntityObject = true;
3366
3352
  this.meshesCreated = false;
3367
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3353
+ this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
3368
3354
  }
3369
3355
  static {
3370
- this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3356
+ this.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, { flip: true });
3371
3357
  }
3372
3358
  async init() {
3373
3359
  this.createMeshes();
@@ -3377,10 +3363,11 @@ var EntityObject = class extends SceneObject {
3377
3363
  super.dispose();
3378
3364
  }
3379
3365
  get textureKey() {
3366
+ if (this.entity.texture) return this.entity.texture;
3367
+ const key = this.entity.key;
3380
3368
  return new AssetKey(
3381
- this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
3382
- this.entity.key.path,
3383
- //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
3369
+ key.namespace,
3370
+ isAssetKey(key) ? key.getFullPath() : key.path,
3384
3371
  "textures",
3385
3372
  "entity",
3386
3373
  "assets",
@@ -3390,36 +3377,41 @@ var EntityObject = class extends SceneObject {
3390
3377
  async loadTextures() {
3391
3378
  this.imageData = await ModelTextures.get(this.textureKey);
3392
3379
  }
3393
- //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3394
3380
  createMeshes(force = false) {
3395
3381
  if (this.meshesCreated && !force) return;
3396
- const mat = Materials.MISSING_TEXTURE;
3397
- for (let partName in this.entity.parts) {
3398
- const part = this.entity.parts[partName];
3399
- const texture = new MinecraftCubeTexture(part.textureOffsetU, part.textureOffsetV, part.textureWidth, part.textureHeight);
3400
- const partAnchor = new import_three12.Object3D();
3401
- partAnchor.position.x = part.pivotX;
3402
- partAnchor.position.y = part.pivotY;
3403
- partAnchor.position.z = part.pivotZ;
3404
- for (let cube of part.cubes) {
3405
- const w = cube.maxX - cube.minX;
3406
- const h = cube.maxY - cube.minY;
3407
- const l = cube.maxZ - cube.minZ;
3408
- const uv = texture.toUvArray(w, h, l);
3409
- const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3410
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3411
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
3412
- applyModelPartRotation(part, cubeGeo);
3413
- const mesh = this.createMesh(partName, cubeGeo, mat);
3414
- partAnchor.add(mesh);
3415
- if (this.options.wireframe) {
3416
- addWireframeToMesh(cubeGeo, mesh);
3417
- }
3418
- }
3419
- this.add(partAnchor);
3420
- }
3382
+ const modelRoot = new import_three12.Object3D();
3383
+ if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
3384
+ this.add(modelRoot);
3385
+ this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
3421
3386
  this.meshesCreated = true;
3422
3387
  }
3388
+ createPart(name, part, parent, textureSize, material) {
3389
+ const anchor = this.createGroup(name);
3390
+ anchor.position.fromArray(part.pose.offset);
3391
+ anchor.rotation.set(...part.pose.rotation, "ZYX");
3392
+ anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
3393
+ parent.add(anchor);
3394
+ const size = part.texture ?? textureSize;
3395
+ for (const cube of part.cubes) {
3396
+ const [width, height, depth] = cube.size;
3397
+ const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
3398
+ const texture = new MinecraftCubeTexture(...cube.uv, ...size);
3399
+ const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
3400
+ const geometry = this._getBoxGeometryForDimensionsAndUv(
3401
+ width + growX * 2,
3402
+ height + growY * 2,
3403
+ depth + growZ * 2,
3404
+ uv
3405
+ ).clone();
3406
+ geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
3407
+ const mesh = this.createMesh(name, geometry, material);
3408
+ anchor.add(mesh);
3409
+ if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
3410
+ }
3411
+ for (const [childName, child] of Object.entries(part.children)) {
3412
+ this.createPart(childName, child, anchor, size, material);
3413
+ }
3414
+ }
3423
3415
  async applyTextures() {
3424
3416
  const assetKeyStr = this.textureKey.serialize();
3425
3417
  const keyStr = `entity:${assetKeyStr}`;
@@ -7328,7 +7320,6 @@ var Chunk = class _Chunk {
7328
7320
  BUILTIN_GENERATED,
7329
7321
  BasicAssetKey,
7330
7322
  BatchedExecutor,
7331
- BlockEntityModels,
7332
7323
  BlockObject,
7333
7324
  BlockStates,
7334
7325
  BlockTints,
@@ -7348,7 +7339,6 @@ var Chunk = class _Chunk {
7348
7339
  DisplayPosition,
7349
7340
  DisplayTransforms,
7350
7341
  Entities,
7351
- EntityModels,
7352
7342
  EntityObject,
7353
7343
  Env,
7354
7344
  Geometries,
@@ -7402,7 +7392,6 @@ var Chunk = class _Chunk {
7402
7392
  addWireframeToObject,
7403
7393
  applyElementRotation,
7404
7394
  applyGenericRotation,
7405
- applyModelPartRotation,
7406
7395
  axisToVec3,
7407
7396
  base64decode,
7408
7397
  base64encode,