UNPKG

2.79 kBJavaScriptView Raw
1import { ResourceLocation } from "@xmcl/resourcepack";
2import { System } from "@xmcl/system";
3/**
4 * The model loader load the resource
5 */
6export class ModelLoader {
7 /**
8 * @param manager The resource manager
9 */
10 constructor(manager) {
11 this.manager = manager;
12 /**
13 * All required texture raw resources
14 */
15 this.textures = {};
16 /**
17 * All the resolved model
18 */
19 this.models = {};
20 }
21 static findRealTexturePath(model, variantKey) {
22 let texturePath = model.textures[variantKey];
23 while (texturePath.startsWith("#")) {
24 const next = model.textures[texturePath.substring(1, texturePath.length)];
25 if (!next) {
26 return undefined;
27 }
28 texturePath = next;
29 }
30 return texturePath;
31 }
32 /**
33 * Load a model by search its parent. It will throw an error if the model is not found.
34 */
35 async loadModel(modelPath) {
36 const res = await this.manager.load(ResourceLocation.ofModelPath(modelPath));
37 if (!res) {
38 throw new Error(`Model ${modelPath} (${ResourceLocation.ofModelPath(modelPath)}) not found`);
39 }
40 const raw = JSON.parse(System.bufferToText(res.content));
41 if (!raw.textures) {
42 raw.textures = {};
43 }
44 if (raw.parent) {
45 const parentModel = await this.loadModel(raw.parent);
46 if (!parentModel) {
47 throw new Error(`Missing parent model ${raw.parent} for ${location.toString()}`);
48 }
49 if (!raw.elements) {
50 raw.elements = parentModel.elements;
51 }
52 if (!raw.ambientocclusion) {
53 raw.ambientocclusion = parentModel.ambientocclusion;
54 }
55 if (!raw.display) {
56 raw.display = parentModel.display;
57 }
58 if (!raw.overrides) {
59 raw.overrides = parentModel.overrides;
60 }
61 if (parentModel.textures) {
62 Object.assign(raw.textures, parentModel.textures);
63 }
64 }
65 raw.ambientocclusion = raw.ambientocclusion || false;
66 raw.overrides = raw.overrides || [];
67 delete raw.parent;
68 const model = raw;
69 this.models[modelPath] = model;
70 const reg = this.textures;
71 for (const variant of Object.keys(model.textures)) {
72 const texPath = ModelLoader.findRealTexturePath(model, variant);
73 if (texPath) {
74 const load = await this.manager.load(ResourceLocation.ofTexturePath(texPath));
75 if (load) {
76 reg[texPath] = load;
77 }
78 }
79 }
80 return model;
81 }
82}