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.
@@ -325,7 +325,7 @@ function isDisposable(obj) {
325
325
  import { BoxGeometry, Float32BufferAttribute } from "three";
326
326
 
327
327
  // src/util/util.ts
328
- import * as CryptoJS from "crypto-js";
328
+ import CryptoJS from "crypto-js";
329
329
  var changeEvent = { type: "change" };
330
330
  function md5(str) {
331
331
  return CryptoJS.MD5(str).toString(CryptoJS.enc.Hex);
@@ -2721,26 +2721,40 @@ var Entities = class {
2721
2721
  };
2722
2722
  return collect("");
2723
2723
  }
2724
- static async getEntity(modelKey, textureKey, options) {
2724
+ static async getModelFile(modelKey) {
2725
2725
  const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
2726
2726
  const key = new AssetKey(modelKey.namespace, path, void 0, void 0, "entity-models", ".json");
2727
- const model = await Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
2727
+ return Caching.entityModelCache.get(key.serialize(), () => AssetLoader.get(key, "json" /* JSON */));
2728
+ }
2729
+ static async getLayerList(modelKey) {
2730
+ return Object.keys((await this.getModelFile(modelKey))?.layers ?? {});
2731
+ }
2732
+ static async getEntity(modelKey, textureKey, options) {
2733
+ const model = await this.getModelFile(modelKey);
2728
2734
  if (!model) return void 0;
2729
- const layerName = options?.layer ?? "main";
2730
- const layer = model.layers[layerName];
2731
- if (!layer) {
2732
- throw new MineRenderError(`Entity ${model.id} has no layer "${layerName}". Available layers: ${Object.keys(model.layers).join(", ")}`);
2733
- }
2734
- let texture;
2735
- if (textureKey) {
2736
- const path2 = isAssetKey(textureKey) ? textureKey.getFullPath() : textureKey.path;
2737
- 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);
2738
- } else if (layer.textureLocation !== void 0) {
2739
- texture = AssetKey.parse("textures", layer.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
2740
- } else {
2741
- texture = await this.resolveTexture(modelKey);
2742
- }
2743
- return { key: textureKey ?? modelKey, texture, layer, id: model.id };
2735
+ const names = [...new Set(options?.layers ?? [options?.layer ?? "main"])];
2736
+ if (names.length === 0) throw new MineRenderError(`Entity ${model.id} requires at least one layer`);
2737
+ const selected = names.map((name) => {
2738
+ const layer = model.layers[name];
2739
+ if (!layer) {
2740
+ throw new MineRenderError(`Entity ${model.id} has no layer "${name}". Available layers: ${Object.keys(model.layers).join(", ")}`);
2741
+ }
2742
+ return { name, layer };
2743
+ });
2744
+ const layers = Object.fromEntries(await Promise.all(selected.map(async ({ name, layer }, index) => {
2745
+ const override = options?.textures?.[name] ?? (index === 0 ? textureKey : void 0);
2746
+ let texture;
2747
+ if (override) {
2748
+ const path = isAssetKey(override) ? override.getFullPath() : override.path;
2749
+ 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);
2750
+ } else if (layer.textureLocation !== void 0) {
2751
+ texture = AssetKey.parse("textures", layer.textureLocation.replace(/^([^:]+:)?textures\//, "$1"));
2752
+ } else {
2753
+ texture = await this.resolveTexture(modelKey);
2754
+ }
2755
+ return [name, { key: override ?? modelKey, texture, layer }];
2756
+ })));
2757
+ return { ...layers[names[0]], id: model.id, layers };
2744
2758
  }
2745
2759
  static async resolveTexture(modelKey) {
2746
2760
  const path = isAssetKey(modelKey) ? modelKey.getFullPath() : modelKey.path;
@@ -3205,9 +3219,21 @@ var _EntityObject = class _EntityObject extends SceneObject {
3205
3219
  dispose() {
3206
3220
  super.dispose();
3207
3221
  }
3208
- get textureKey() {
3209
- if (this.entity.texture) return this.entity.texture;
3210
- const key = this.entity.key;
3222
+ getLayerGroup(name) {
3223
+ return super.getGroupByName(`layer:${name}`);
3224
+ }
3225
+ getGroupByName(name, layerName) {
3226
+ return layerName === void 0 ? super.getGroupByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`group:${name}`);
3227
+ }
3228
+ getMeshByName(name, layerName) {
3229
+ return layerName === void 0 ? super.getMeshByName(name) : this.getLayerGroup(layerName)?.getObjectByName(`mesh:${name}`);
3230
+ }
3231
+ get entityLayers() {
3232
+ return this.entity.layers ?? { main: this.entity };
3233
+ }
3234
+ getTextureKey(layer) {
3235
+ if (layer.texture) return layer.texture;
3236
+ const key = layer.key;
3211
3237
  return new AssetKey(
3212
3238
  key.namespace,
3213
3239
  isAssetKey(key) ? key.getFullPath() : key.path,
@@ -3217,18 +3243,22 @@ var _EntityObject = class _EntityObject extends SceneObject {
3217
3243
  ".png"
3218
3244
  );
3219
3245
  }
3220
- async loadTextures() {
3221
- this.imageData = await ModelTextures.get(this.textureKey);
3246
+ async loadTextures(layer = this.entity) {
3247
+ return ModelTextures.get(this.getTextureKey(layer));
3222
3248
  }
3223
3249
  createMeshes(force = false) {
3224
3250
  if (this.meshesCreated && !force) return;
3225
3251
  const modelRoot = new Object3D3();
3226
3252
  if (this.options.flip) modelRoot.scale.set(-1, -1, 1);
3227
3253
  this.add(modelRoot);
3228
- this.createPart("root", this.entity.layer.root, modelRoot, this.entity.layer.texture, Materials.MISSING_TEXTURE);
3254
+ Object.entries(this.entityLayers).forEach(([name, layer], index) => {
3255
+ const group = this.createGroup(`layer:${name}`);
3256
+ modelRoot.add(group);
3257
+ this.createPart("root", layer.layer.root, group, layer.layer.texture, Materials.MISSING_TEXTURE, index);
3258
+ });
3229
3259
  this.meshesCreated = true;
3230
3260
  }
3231
- createPart(name, part, parent, textureSize, material) {
3261
+ createPart(name, part, parent, textureSize, material, renderOrder) {
3232
3262
  const anchor = this.createGroup(name);
3233
3263
  anchor.position.fromArray(part.pose.offset);
3234
3264
  anchor.rotation.set(...part.pose.rotation, "ZYX");
@@ -3248,30 +3278,31 @@ var _EntityObject = class _EntityObject extends SceneObject {
3248
3278
  ).clone();
3249
3279
  geometry.translate(cube.origin[0] + width / 2, cube.origin[1] + height / 2, cube.origin[2] + depth / 2);
3250
3280
  const mesh = this.createMesh(name, geometry, material);
3281
+ mesh.renderOrder = renderOrder;
3251
3282
  anchor.add(mesh);
3252
3283
  if (this.options.wireframe) addWireframeToMesh(geometry, mesh);
3253
3284
  }
3254
3285
  for (const [childName, child] of Object.entries(part.children)) {
3255
- this.createPart(childName, child, anchor, size, material);
3286
+ this.createPart(childName, child, anchor, size, material, renderOrder);
3256
3287
  }
3257
3288
  }
3258
3289
  async applyTextures() {
3259
- const assetKeyStr = this.textureKey.serialize();
3260
- const keyStr = `entity:${assetKeyStr}`;
3261
- let mat = Caching.materialCache.getIfPresent(keyStr);
3262
- if (!mat) {
3263
- const pending = this.loadTextures();
3264
- const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3265
- await pending;
3266
- if (!this.imageData) return;
3267
- const canvas = this.imageData.data.canvas;
3268
- const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3269
- mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3270
- this.imageData = void 0;
3271
- }
3272
- this.iterateAllMeshes((mesh) => {
3273
- mesh.material = mat;
3274
- });
3290
+ await Promise.all(Object.entries(this.entityLayers).map(async ([name, layer]) => {
3291
+ const assetKeyStr = this.getTextureKey(layer).serialize();
3292
+ const keyStr = `entity:${assetKeyStr}`;
3293
+ let mat = Caching.materialCache.getIfPresent(keyStr);
3294
+ if (!mat) {
3295
+ const cachedAsset = Caching.textureAssetCache.getIfPresent(assetKeyStr);
3296
+ const imageData = await this.loadTextures(layer);
3297
+ if (!imageData) return;
3298
+ const canvas = imageData.data.canvas;
3299
+ const createMaterial = () => Materials.createBasicCanvasMaterial(canvas);
3300
+ mat = cachedAsset && Caching.textureAssetCache.getIfPresent(assetKeyStr) === cachedAsset ? Caching.materialCache.get(keyStr, createMaterial) : createMaterial();
3301
+ }
3302
+ this.getLayerGroup(name)?.traverse((object) => {
3303
+ if (isMesh(object)) object.material = mat;
3304
+ });
3305
+ }));
3275
3306
  this.notifyDirty();
3276
3307
  }
3277
3308
  };