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_browser_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,
@@ -159,7 +158,6 @@ __export(index_browser_exports, {
159
158
  DisplayPosition: () => DisplayPosition,
160
159
  DisplayTransforms: () => DisplayTransforms,
161
160
  Entities: () => Entities,
162
- EntityModels: () => EntityModels,
163
161
  EntityObject: () => EntityObject,
164
162
  Env: () => Env,
165
163
  Geometries: () => Geometries,
@@ -211,7 +209,6 @@ __export(index_browser_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,
@@ -571,7 +568,8 @@ var _Caching = class _Caching {
571
568
  this.listAssetCache,
572
569
  this.defaultBlockStatesCache,
573
570
  this.blockTintCache,
574
- this.entityModelsCache
571
+ this.entityModelCache,
572
+ this.entityTextureCache
575
573
  ];
576
574
  }
577
575
  static clear() {
@@ -614,7 +612,8 @@ _Caching.blockStateCache = import_loading_cache.Caches.builder().expireAfterWrit
614
612
  _Caching.listAssetCache = _Caching.createAssetCache();
615
613
  _Caching.defaultBlockStatesCache = _Caching.createAssetCache();
616
614
  _Caching.blockTintCache = _Caching.createAssetCache();
617
- _Caching.entityModelsCache = _Caching.createAssetCache();
615
+ _Caching.entityModelCache = _Caching.createAssetCache();
616
+ _Caching.entityTextureCache = _Caching.createAssetCache();
618
617
  var Caching = _Caching;
619
618
 
620
619
  // src/Geometries.ts
@@ -1693,14 +1692,6 @@ function applyElementRotation(rotation, geometry) {
1693
1692
  }
1694
1693
  geometry.translate(origin.x, origin.y, origin.z);
1695
1694
  }
1696
- function applyModelPartRotation(modelPart, geometry) {
1697
- const origin = new import_three8.Vector3(modelPart.pivotX, modelPart.pivotY, modelPart.pivotZ);
1698
- geometry.translate(-origin.x, -origin.y, -origin.z);
1699
- geometry.rotateX(toRadians(modelPart.pitch));
1700
- geometry.rotateY(toRadians(modelPart.yaw));
1701
- geometry.rotateZ(toRadians(modelPart.roll));
1702
- geometry.translate(origin.x, origin.y, origin.z);
1703
- }
1704
1695
  function applyGenericRotation(axis, rotation, obj) {
1705
1696
  switch (axis) {
1706
1697
  case "x" /* X */:
@@ -2722,18 +2713,18 @@ var MinecraftCubeTexture = class {
2722
2713
  }
2723
2714
  getUvEast(w, h, l) {
2724
2715
  return [
2725
- [this.mapW(this.u), this.mapH(this.v + l + h)],
2726
- [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2727
- [this.mapW(this.u), this.mapH(this.v + l)],
2728
- [this.mapW(this.u + l), this.mapH(this.v + l)]
2716
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2717
+ [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
2718
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l)],
2719
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)]
2729
2720
  ];
2730
2721
  }
2731
2722
  getUvWest(w, h, l) {
2732
2723
  return [
2733
- [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
2734
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2735
- [this.mapW(this.u + l + w), this.mapH(this.v + l)],
2736
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
2724
+ [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2725
+ [this.mapW(this.u), this.mapH(this.v + l + h)],
2726
+ [this.mapW(this.u + l), this.mapH(this.v + l)],
2727
+ [this.mapW(this.u), this.mapH(this.v + l)]
2737
2728
  ];
2738
2729
  }
2739
2730
  getUvUp(w, h, l) {
@@ -2746,26 +2737,26 @@ var MinecraftCubeTexture = class {
2746
2737
  }
2747
2738
  getUvDown(w, h, l) {
2748
2739
  return [
2749
- [this.mapW(this.u + l), this.mapH(this.v + l)],
2750
- [this.mapW(this.u + l + w), this.mapH(this.v + l)],
2751
2740
  [this.mapW(this.u + l), this.mapH(this.v)],
2752
- [this.mapW(this.u + l + w), this.mapH(this.v)]
2741
+ [this.mapW(this.u + l + w), this.mapH(this.v)],
2742
+ [this.mapW(this.u + l), this.mapH(this.v + l)],
2743
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)]
2753
2744
  ];
2754
2745
  }
2755
2746
  getUvSouth(w, h, l) {
2756
2747
  return [
2757
- [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2758
2748
  [this.mapW(this.u + l + w + 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 + l + w), this.mapH(this.v + l)]
2749
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l + h)],
2750
+ [this.mapW(this.u + l + w + l + w), this.mapH(this.v + l)],
2751
+ [this.mapW(this.u + l + w + l), this.mapH(this.v + l)]
2761
2752
  ];
2762
2753
  }
2763
2754
  getUvNorth(w, h, l) {
2764
2755
  return [
2765
- [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2766
2756
  [this.mapW(this.u + l + w), this.mapH(this.v + l + h)],
2767
- [this.mapW(this.u + l), this.mapH(this.v + l)],
2768
- [this.mapW(this.u + l + w), this.mapH(this.v + l)]
2757
+ [this.mapW(this.u + l), this.mapH(this.v + l + h)],
2758
+ [this.mapW(this.u + l + w), this.mapH(this.v + l)],
2759
+ [this.mapW(this.u + l), this.mapH(this.v + l)]
2769
2760
  ];
2770
2761
  }
2771
2762
  getFaceUv(face, w, h, l) {
@@ -2784,10 +2775,12 @@ var MinecraftCubeTexture = class {
2784
2775
  return this.getUvNorth(w, h, l);
2785
2776
  }
2786
2777
  }
2787
- toUvArray(w, h, l) {
2778
+ toUvArray(w, h, l, mirror = false) {
2788
2779
  const uv = [];
2789
2780
  for (let i = 0; i < CUBE_FACES.length; i++) {
2790
- UVMapper.setFaceUvInArray(uv, i * 4, this.getFaceUv(CUBE_FACES[i], w, h, l));
2781
+ const face = mirror && i < 2 ? CUBE_FACES[1 - i] : CUBE_FACES[i];
2782
+ const corners = this.getFaceUv(face, w, h, l);
2783
+ UVMapper.setFaceUvInArray(uv, i * 4, mirror ? [corners[1], corners[0], corners[3], corners[2]] : corners);
2791
2784
  }
2792
2785
  return uv;
2793
2786
  }
@@ -2817,69 +2810,79 @@ function shutdown() {
2817
2810
  Caching.end();
2818
2811
  }
2819
2812
 
2820
- // src/assets/Entities.ts
2821
- var Entities = class {
2822
- static async getBlockEntityModels() {
2823
- const key = AssetKey.parse("models", "minerender:blockEntityModels");
2824
- console.log(key);
2825
- return Caching.entityModelsCache.get(key.serialize(), () => {
2826
- return AssetLoader.get(key, "json" /* JSON */);
2827
- });
2828
- }
2829
- static async getEntityModels() {
2830
- const key = AssetKey.parse("models", "minerender:entityModels");
2831
- console.log(key);
2832
- return Caching.entityModelsCache.get(key.serialize(), () => {
2833
- return AssetLoader.get(key, "json" /* JSON */);
2834
- });
2813
+ // src/error/MineRenderError.ts
2814
+ var MineRenderError = class _MineRenderError extends Error {
2815
+ constructor(msg) {
2816
+ super(msg);
2817
+ Object.setPrototypeOf(this, _MineRenderError.prototype);
2835
2818
  }
2836
- // BlockEntity names are hardcoded
2837
- static async getBlockList() {
2838
- const models = await this.getBlockEntityModels();
2839
- if (!models) {
2840
- return [];
2841
- }
2842
- return Object.keys(models);
2819
+ get name() {
2820
+ return "MineRenderError";
2843
2821
  }
2822
+ };
2823
+
2824
+ // src/assets/Entities.ts
2825
+ var Entities = class {
2844
2826
  static async getEntityList() {
2845
- const models = await this.getEntityModels();
2846
- if (!models) {
2847
- return [];
2848
- }
2849
- return Object.keys(models);
2850
- }
2851
- static async getBlock(modelKey, textureKey) {
2852
- const models = await this.getBlockEntityModels();
2853
- if (!models) {
2854
- return void 0;
2855
- }
2856
- if (!textureKey) {
2857
- textureKey = modelKey;
2858
- }
2859
- const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
2860
- return {
2861
- key: textureKey,
2862
- parts: models[baseKey.toNamespacedString()]
2827
+ const collect = async (path) => {
2828
+ const prefix2 = path ? `${path}/` : "";
2829
+ const key = new AssetKey(DEFAULT_NAMESPACE, `${prefix2}_list`, void 0, void 0, "entity-models", ".json");
2830
+ const list = await Caching.listAssetCache.get(key.serialize(), () => AssetLoader.get(key, "list" /* LIST */));
2831
+ if (!list) return [];
2832
+ const files = list.files.filter((file) => file.endsWith(".json") && file !== "_list.json").map((file) => `${prefix2}${file.slice(0, -5)}`);
2833
+ const children = await Promise.all(list.directories.map((directory) => collect(`${prefix2}${directory}`)));
2834
+ return [...files, ...children.flat()];
2863
2835
  };
2836
+ return collect("");
2837
+ }
2838
+ static async getEntity(modelKey, textureKey, options) {
2839
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
2840
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
2841
+ const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
2842
+ if (!model) return void 0;
2843
+ const layerName = options?.layer ?? "main";
2844
+ const layer = model.layers[layerName];
2845
+ if (!layer) {
2846
+ throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
2847
+ }
2848
+ let texture;
2849
+ if (textureKey) {
2850
+ const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
2851
+ 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);
2852
+ } else {
2853
+ texture = await this.resolveTexture(modelKey);
2854
+ }
2855
+ return { key: textureKey ?? modelKey, texture, layer, id: model.id };
2856
+ }
2857
+ static async resolveTexture(modelKey) {
2858
+ const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
2859
+ const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
2860
+ return Caching.entityTextureCache.get(key.serialize(), async () => {
2861
+ const name = path.split("/").pop();
2862
+ for (const candidate of [path, `${path}/${name}`]) {
2863
+ const texture = new AssetKey(modelKey.namespace, candidate, "textures", "entity", "assets", ".png");
2864
+ if (await ModelTextures.get(texture)) return texture;
2865
+ }
2866
+ const listKey = new AssetKey(modelKey.namespace, "_list", `${name}_variant`, void 0, "data", ".json");
2867
+ const list = await AssetLoader.get(listKey, "list" /* LIST */);
2868
+ const files = list?.files.filter((file2) => file2.endsWith(".json") && file2 !== "_list.json");
2869
+ const file = files?.find((file2) => file2 === "temperate.json") ?? files?.[0];
2870
+ if (!file) return void 0;
2871
+ const variantKey = new AssetKey(modelKey.namespace, file.slice(0, -5), `${name}_variant`, void 0, "data", ".json");
2872
+ const variant = await AssetLoader.get(variantKey, "json" /* JSON */);
2873
+ const assets = variant?.assets;
2874
+ const textureId = variant?.asset_id ?? (typeof assets?.wild === "string" ? assets.wild : Object.values(assets ?? {}).find((value) => typeof value === "string"));
2875
+ return typeof textureId === "string" ? AssetKey.parse("textures", textureId) : void 0;
2876
+ });
2864
2877
  }
2865
- static async getEntity(modelKey, textureKey) {
2866
- const models = await this.getEntityModels();
2867
- if (!models) {
2868
- return void 0;
2869
- }
2870
- if (!textureKey) {
2871
- textureKey = modelKey;
2872
- }
2873
- const baseKey = modelKey.path.includes("/") ? new BasicAssetKey(modelKey.namespace, modelKey.path.split("/")[0]) : modelKey;
2874
- return {
2875
- key: textureKey,
2876
- parts: models[baseKey.toNamespacedString()]
2877
- };
2878
+ /** @deprecated Use getEntityList(); block entities share the entity dataset. */
2879
+ static getBlockList() {
2880
+ return this.getEntityList();
2881
+ }
2882
+ /** @deprecated Use getEntity(); block entities share the entity dataset. */
2883
+ static getBlock(modelKey, textureKey, options) {
2884
+ return this.getEntity(modelKey, textureKey, options);
2878
2885
  }
2879
- };
2880
- var EntityModels = class {
2881
- };
2882
- var BlockEntityModels = class {
2883
2886
  };
2884
2887
 
2885
2888
  // src/renderer/SceneObject.ts
@@ -2928,17 +2931,6 @@ function isInstanceReference(obj) {
2928
2931
  return obj.isInstanceReference;
2929
2932
  }
2930
2933
 
2931
- // src/error/MineRenderError.ts
2932
- var MineRenderError = class _MineRenderError extends Error {
2933
- constructor(msg) {
2934
- super(msg);
2935
- Object.setPrototypeOf(this, _MineRenderError.prototype);
2936
- }
2937
- get name() {
2938
- return "MineRenderError";
2939
- }
2940
- };
2941
-
2942
2934
  // src/renderer/SceneObject.ts
2943
2935
  var import_ts_deepmerge3 = __toESM(require_dist());
2944
2936
  var p6 = prefix("SceneObject");
@@ -3064,15 +3056,8 @@ var _SceneObject = class _SceneObject extends import_three10.Object3D {
3064
3056
  return this.toggleObjectVisibility(this.getMeshByName(name), visible);
3065
3057
  }
3066
3058
  iterateAllMeshes(cb) {
3067
- this.children.forEach((obj) => {
3068
- if (obj.isMesh) {
3069
- cb(obj);
3070
- }
3071
- obj.children.forEach((obj1) => {
3072
- if (obj1.isMesh) {
3073
- cb(obj1);
3074
- }
3075
- });
3059
+ this.traverse((obj) => {
3060
+ if (isMesh(obj)) cb(obj);
3076
3061
  });
3077
3062
  }
3078
3063
  //</editor-fold>
@@ -3317,14 +3302,13 @@ function isSceneObject(obj) {
3317
3302
  // src/entity/scene/EntityObject.ts
3318
3303
  var import_ts_deepmerge4 = __toESM(require_dist());
3319
3304
  var import_three12 = require("three");
3320
- var THREE3 = __toESM(require("three"));
3321
- var EntityObject = class extends SceneObject {
3305
+ var _EntityObject = class _EntityObject extends SceneObject {
3322
3306
  constructor(entity, options) {
3323
3307
  super();
3324
3308
  this.entity = entity;
3325
3309
  this.isEntityObject = true;
3326
3310
  this.meshesCreated = false;
3327
- this.options = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, options ?? {});
3311
+ this.options = (0, import_ts_deepmerge4.default)({}, _EntityObject.DEFAULT_OPTIONS, options ?? {});
3328
3312
  }
3329
3313
  async init() {
3330
3314
  this.createMeshes();
@@ -3334,10 +3318,11 @@ var EntityObject = class extends SceneObject {
3334
3318
  super.dispose();
3335
3319
  }
3336
3320
  get textureKey() {
3321
+ if (this.entity.texture) return this.entity.texture;
3322
+ const key = this.entity.key;
3337
3323
  return new AssetKey(
3338
- this.entity.key?.namespace ?? DEFAULT_NAMESPACE,
3339
- this.entity.key.path,
3340
- //TODO: texture may differ from entity name; most of them are in subdirectories for multiple variants etc.
3324
+ key.namespace,
3325
+ isAssetKey(key) ? key.getFullPath() : key.path,
3341
3326
  "textures",
3342
3327
  "entity",
3343
3328
  "assets",
@@ -3347,36 +3332,41 @@ var EntityObject = class extends SceneObject {
3347
3332
  async loadTextures() {
3348
3333
  this.imageData = await ModelTextures.get(this.textureKey);
3349
3334
  }
3350
- //TODO: abstract this, since extracted model data can be used for entities, blocks, players
3351
3335
  createMeshes(force = false) {
3352
3336
  if (this.meshesCreated && !force) return;
3353
- const mat = Materials.MISSING_TEXTURE;
3354
- for (let partName in this.entity.parts) {
3355
- const part = this.entity.parts[partName];
3356
- const texture = new MinecraftCubeTexture(part.textureOffsetU, part.textureOffsetV, part.textureWidth, part.textureHeight);
3357
- const partAnchor = new import_three12.Object3D();
3358
- partAnchor.position.x = part.pivotX;
3359
- partAnchor.position.y = part.pivotY;
3360
- partAnchor.position.z = part.pivotZ;
3361
- for (let cube of part.cubes) {
3362
- const w = cube.maxX - cube.minX;
3363
- const h = cube.maxY - cube.minY;
3364
- const l = cube.maxZ - cube.minZ;
3365
- const uv = texture.toUvArray(w, h, l);
3366
- const cubeGeo = this._getBoxGeometryForDimensionsAndUv(w, h, l, uv).clone();
3367
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(w / 2, h / 2, l / 2));
3368
- cubeGeo.applyMatrix4(new THREE3.Matrix4().makeTranslation(cube.minX, cube.minY, cube.minZ));
3369
- applyModelPartRotation(part, cubeGeo);
3370
- const mesh = this.createMesh(partName, cubeGeo, mat);
3371
- partAnchor.add(mesh);
3372
- if (this.options.wireframe) {
3373
- addWireframeToMesh(cubeGeo, mesh);
3374
- }
3375
- }
3376
- this.add(partAnchor);
3377
- }
3337
+ const modelRoot = new import_three12.Object3D();
3338
+ if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
3339
+ this.add(modelRoot);
3340
+ this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
3378
3341
  this.meshesCreated = true;
3379
3342
  }
3343
+ createPart(name, part, parent, textureSize, material) {
3344
+ const anchor = this.createGroup(name);
3345
+ anchor.position.fromArray(part.pose.offset);
3346
+ anchor.rotation.set(...part.pose.rotation, "ZYX");
3347
+ anchor.scale.fromArray(part.pose.scale ?? [1, 1, 1]);
3348
+ parent.add(anchor);
3349
+ const size = part.texture ?? textureSize;
3350
+ for (const cube of part.cubes) {
3351
+ const [width, height, depth] = cube.size;
3352
+ const [growX, growY, growZ] = cube.grow ?? [0, 0, 0];
3353
+ const texture = new MinecraftCubeTexture(...cube.uv, ...size);
3354
+ const uv = size[0] === 0 || size[1] === 0 ? new Array(48).fill(0) : texture.toUvArray(width, height, depth, cube.mirror);
3355
+ const geometry = this._getBoxGeometryForDimensionsAndUv(
3356
+ width + growX * 2,
3357
+ height + growY * 2,
3358
+ depth + growZ * 2,
3359
+ uv
3360
+ ).clone();
3361
+ geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
3362
+ const mesh = this.createMesh(name, geometry, material);
3363
+ anchor.add(mesh);
3364
+ if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
3365
+ }
3366
+ for (const [childName, child] of Object.entries(part.children)) {
3367
+ this.createPart(childName, child, anchor, size, material);
3368
+ }
3369
+ }
3380
3370
  async applyTextures() {
3381
3371
  const assetKeyStr = this.textureKey.serialize();
3382
3372
  const keyStr = `entity:${assetKeyStr}`;
@@ -3397,7 +3387,8 @@ var EntityObject = class extends SceneObject {
3397
3387
  this.notifyDirty();
3398
3388
  }
3399
3389
  };
3400
- EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, {});
3390
+ _EntityObject.DEFAULT_OPTIONS = (0, import_ts_deepmerge4.default)({}, SceneObject.DEFAULT_OPTIONS, { flip: true });
3391
+ var EntityObject = _EntityObject;
3401
3392
  function isEntityObject(obj) {
3402
3393
  return obj.isEntityObject;
3403
3394
  }