minerender 2.1.0-alpha.31 → 2.1.0-alpha.33

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.
@@ -288,7 +288,7 @@ function isDisposable(obj) {
288
288
  import { BoxGeometry, Float32BufferAttribute } from "three";
289
289
 
290
290
  // src/util/util.ts
291
- import * as CryptoJS from "crypto-js";
291
+ import CryptoJS from "crypto-js";
292
292
  var changeEvent = { type: "change" };
293
293
  function md5(str) {
294
294
  return CryptoJS.MD5(str).toString(CryptoJS.enc.Hex);
@@ -2765,26 +2765,40 @@ var Entities = class {
2765
2765
  };
2766
2766
  return collect("");
2767
2767
  }
2768
- static async getEntity(modelKey, textureKey, options) {
2768
+ static async getModelFile(modelKey) {
2769
2769
  const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
2770
2770
  const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
2771
- const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
2771
+ return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
2772
+ }
2773
+ static async getLayerList(modelKey) {
2774
+ return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
2775
+ }
2776
+ static async getEntity(modelKey, textureKey, options) {
2777
+ const model = await this.getModelFile(modelKey);
2772
2778
  if (!model) return void 0;
2773
- const layerName = options?.layer ?? "main";
2774
- const layer = model.layers[layerName];
2775
- if (!layer) {
2776
- throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
2777
- }
2778
- let texture;
2779
- if (textureKey) {
2780
- const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
2781
- 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);
2782
- } else if (layer.textureLocation !== void 0) {
2783
- texture = AssetKey.parse("textures", layer.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
2784
- } else {
2785
- texture = await this.resolveTexture(modelKey);
2786
- }
2787
- return { key: textureKey ?? modelKey, texture, layer, id: model.id };
2779
+ const names = [...new Set(options?.layers ?? [options?.layer ?? "main"])];
2780
+ if (names.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
2781
+ const selected = names.map((name) => {
2782
+ const layer = model.layers[name];
2783
+ if (!layer) {
2784
+ throw new MineRenderError(`Entity ${model.id} has no layer "${name}". Available layers: ${Object.keys(model.layers).join(", ")}`);
2785
+ }
2786
+ return { name, layer };
2787
+ });
2788
+ const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer }, index) => {
2789
+ const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
2790
+ let texture;
2791
+ if (override) {
2792
+ const path = isAssetKey(override) ? override.getFullPath() : override.path;
2793
+ texture = isAssetKey(override) && override.assetType === "textures" && path.startsWith("entity/") ? override : new AssetKey(override.namespace, path, "textures", "entity", "assets", ".png", isAssetKey(override) ? override.root : void 0);
2794
+ } else if (layer.textureLocation !== void 0) {
2795
+ texture = AssetKey.parse("textures", layer.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
2796
+ } else {
2797
+ texture = await this.resolveTexture(modelKey);
2798
+ }
2799
+ return [name, { key: override ?? modelKey, texture, layer }];
2800
+ })));
2801
+ return { ...layers[names[0]], id: model.id, layers };
2788
2802
  }
2789
2803
  static async resolveTexture(modelKey) {
2790
2804
  const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
@@ -3253,9 +3267,21 @@ var EntityObject = class _EntityObject extends SceneObject {
3253
3267
  dispose() {
3254
3268
  super.dispose();
3255
3269
  }
3256
- get textureKey() {
3257
- if (this.entity.texture) return this.entity.texture;
3258
- const key = this.entity.key;
3270
+ getLayerGroup(name) {
3271
+ return super.getGroupByName(`layer:${name}`);
3272
+ }
3273
+ getGroupByName(name, layerName) {
3274
+ return layerName === void 0 ? super.getGroupByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name}`);
3275
+ }
3276
+ getMeshByName(name, layerName) {
3277
+ return layerName === void 0 ? super.getMeshByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name}`);
3278
+ }
3279
+ get entityLayers() {
3280
+ return this.entity.layers ?? { main: this.entity };
3281
+ }
3282
+ getTextureKey(layer) {
3283
+ if (layer.texture) return layer.texture;
3284
+ const key = layer.key;
3259
3285
  return new AssetKey(
3260
3286
  key.namespace,
3261
3287
  isAssetKey(key) ? key.getFullPath() : key.path,
@@ -3265,18 +3291,22 @@ var EntityObject = class _EntityObject extends SceneObject {
3265
3291
  ".png"
3266
3292
  );
3267
3293
  }
3268
- async loadTextures() {
3269
- this.imageData = await ModelTextures.get(this.textureKey);
3294
+ async loadTextures(layer = this.entity) {
3295
+ return ModelTextures.get(this.getTextureKey(layer));
3270
3296
  }
3271
3297
  createMeshes(force = false) {
3272
3298
  if (this.meshesCreated && !force) return;
3273
3299
  const modelRoot = new Object3D3();
3274
3300
  if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
3275
3301
  this.add(modelRoot);
3276
- this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
3302
+ Object.entries(this.entityLayers).forEach(([name, layer], index) => {
3303
+ const group = this.createGroup(`layer:${name}`);
3304
+ modelRoot.add(group);
3305
+ this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index);
3306
+ });
3277
3307
  this.meshesCreated = true;
3278
3308
  }
3279
- createPart(name, part, parent, textureSize, material) {
3309
+ createPart(name, part, parent, textureSize, material, renderOrder) {
3280
3310
  const anchor = this.createGroup(name);
3281
3311
  anchor.position.fromArray(part.pose.offset);
3282
3312
  anchor.rotation.set(...part.pose.rotation, "ZYX");
@@ -3296,30 +3326,31 @@ var EntityObject = class _EntityObject extends SceneObject {
3296
3326
  ).clone();
3297
3327
  geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
3298
3328
  const mesh = this.createMesh(name, geometry, material);
3329
+ mesh.renderOrder = renderOrder;
3299
3330
  anchor.add(mesh);
3300
3331
  if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
3301
3332
  }
3302
3333
  for (const [childName, child] of Object.entries(part.children)) {
3303
- this.createPart(childName, child, anchor, size, material);
3334
+ this.createPart(childName, child, anchor, size, material, renderOrder);
3304
3335
  }
3305
3336
  }
3306
3337
  async applyTextures() {
3307
- const assetKeyStr = this.textureKey.serialize();
3308
- const keyStr = `entity:${assetKeyStr}`;
3309
- let mat = Caching.materialCache.getIfPresent(keyStr);
3310
- if (!mat) {
3311
- const pending = this.loadTextures();
3312
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3313
- await pending;
3314
- if (!this.imageData) return;
3315
- const canvas = this.imageData.data.canvas;
3316
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3317
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3318
- this.imageData = void 0;
3319
- }
3320
- this.iterateAllMeshes((mesh) => {
3321
- mesh.material = mat;
3322
- });
3338
+ await Promise.all(Object.entries(this.entityLayers).map(async ([name, layer]) => {
3339
+ const assetKeyStr = this.getTextureKey(layer).serialize();
3340
+ const keyStr = `entity:${assetKeyStr}`;
3341
+ let mat = Caching.materialCache.getIfPresent(keyStr);
3342
+ if (!mat) {
3343
+ const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3344
+ const imageData = await this.loadTextures(layer);
3345
+ if (!imageData) return;
3346
+ const canvas = imageData.data.canvas;
3347
+ const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3348
+ mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3349
+ }
3350
+ this.getLayerGroup(name)?.traverse((object) => {
3351
+ if (isMesh(object)) object.material = mat;
3352
+ });
3353
+ }));
3323
3354
  this.notifyDirty();
3324
3355
  }
3325
3356
  };