mc-assets 0.2.29 → 0.2.31
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.
- package/dist/assetsParser.d.ts +18 -1
- package/dist/assetsParser.js +6 -0
- package/dist/itemsRenderer.d.ts +5 -2
- package/dist/itemsRenderer.js +22 -14
- package/dist/itemsRenderer.test.js +16 -4
- package/dist/worldBlockProvider.d.ts +39 -4
- package/dist/worldBlockProvider.js +53 -48
- package/package.json +1 -1
package/dist/assetsParser.d.ts
CHANGED
|
@@ -19,7 +19,24 @@ export declare class AssetsParser {
|
|
|
19
19
|
getElements(queriedBlock: Omit<QueriedBlock, 'stateId'>, fallbackVariant?: boolean): 0 | 1 | BlockElement[];
|
|
20
20
|
private resolvedModel;
|
|
21
21
|
private getModelsByBlock;
|
|
22
|
-
|
|
22
|
+
getResolvedModelsByModel(model: string, debugQueryName?: string, clearModel?: boolean): {
|
|
23
|
+
resolvedModel: Pick<BlockModel, "textures" | "ao" | "elements"> & {
|
|
24
|
+
x?: number;
|
|
25
|
+
y?: number;
|
|
26
|
+
z?: number;
|
|
27
|
+
uvlock?: boolean;
|
|
28
|
+
weight?: number;
|
|
29
|
+
};
|
|
30
|
+
} | undefined;
|
|
31
|
+
getResolvedModelsByModelData(modelData: BlockModel, debugQueryName?: string, clearModel?: boolean): {
|
|
32
|
+
resolvedModel: Pick<BlockModel, "textures" | "ao" | "elements"> & {
|
|
33
|
+
x?: number;
|
|
34
|
+
y?: number;
|
|
35
|
+
z?: number;
|
|
36
|
+
uvlock?: boolean;
|
|
37
|
+
weight?: number;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
23
40
|
getResolvedModelFirst(queriedBlock: Omit<QueriedBlock, 'stateId'>, fallbackVariant?: boolean): (Pick<BlockModel, "textures" | "ao" | "elements"> & {
|
|
24
41
|
x?: number;
|
|
25
42
|
y?: number;
|
package/dist/assetsParser.js
CHANGED
|
@@ -143,6 +143,12 @@ export class AssetsParser {
|
|
|
143
143
|
const modelData = this.blockModelsStore.get(this.version, model);
|
|
144
144
|
if (!modelData)
|
|
145
145
|
return;
|
|
146
|
+
return this.getResolvedModelsByModelData(modelData, debugQueryName, clearModel);
|
|
147
|
+
}
|
|
148
|
+
getResolvedModelsByModelData(modelData, debugQueryName, clearModel = true) {
|
|
149
|
+
if (clearModel) {
|
|
150
|
+
this.resolvedModel = {};
|
|
151
|
+
}
|
|
146
152
|
const collectedParentModels = [];
|
|
147
153
|
const collectModels = (model) => {
|
|
148
154
|
collectedParentModels.push(model);
|
package/dist/itemsRenderer.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AtlasParser } from './atlasParser';
|
|
2
2
|
import { AssetsParser } from './assetsParser';
|
|
3
3
|
import { BlockModelsStore, BlockStatesStore } from './stores';
|
|
4
|
+
import { BlockModel } from './types';
|
|
4
5
|
export declare class ItemsRenderer {
|
|
5
6
|
version: string;
|
|
6
7
|
itemsAtlasParser: AtlasParser;
|
|
@@ -15,7 +16,7 @@ export declare class ItemsRenderer {
|
|
|
15
16
|
/** @deprecated */
|
|
16
17
|
path: string;
|
|
17
18
|
} | undefined;
|
|
18
|
-
tryGetFullBlock(
|
|
19
|
+
tryGetFullBlock(model: any, blockName: string): {
|
|
19
20
|
top: {
|
|
20
21
|
slice: [number, number, number, number];
|
|
21
22
|
type: string;
|
|
@@ -34,8 +35,9 @@ export declare class ItemsRenderer {
|
|
|
34
35
|
/** @deprecated */
|
|
35
36
|
path: string;
|
|
36
37
|
};
|
|
38
|
+
resolvedModel: BlockModel;
|
|
37
39
|
} | undefined;
|
|
38
|
-
getItemTexture(itemNameOrModel: string,
|
|
40
|
+
getItemTexture(itemNameOrModel: string, _properties?: Record<string, string | boolean>, exactItemResolve?: boolean): {
|
|
39
41
|
slice: [number, number, number, number];
|
|
40
42
|
type: string;
|
|
41
43
|
/** @deprecated */
|
|
@@ -59,5 +61,6 @@ export declare class ItemsRenderer {
|
|
|
59
61
|
/** @deprecated */
|
|
60
62
|
path: string;
|
|
61
63
|
};
|
|
64
|
+
resolvedModel: BlockModel;
|
|
62
65
|
} | undefined;
|
|
63
66
|
}
|
package/dist/itemsRenderer.js
CHANGED
|
@@ -34,14 +34,10 @@ export class ItemsRenderer {
|
|
|
34
34
|
path: type
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
tryGetFullBlock(
|
|
37
|
+
tryGetFullBlock(model, blockName) {
|
|
38
38
|
if (!this.blocksAtlasParser)
|
|
39
39
|
return;
|
|
40
|
-
const
|
|
41
|
-
name: blockName,
|
|
42
|
-
properties,
|
|
43
|
-
}, true);
|
|
44
|
-
const resolvedModel = resolvedModelParts?.[0];
|
|
40
|
+
const { resolvedModel } = this.assetsParser.getResolvedModelsByModelData(model);
|
|
45
41
|
if (!resolvedModel?.elements?.length)
|
|
46
42
|
return;
|
|
47
43
|
const isAllFullModels = resolvedModel.elements.every(elem => elem.from[0] === 0 && elem.from[1] === 0 && elem.from[2] === 0 && elem.to[0] === 16 && elem.to[1] === 16 && elem.to[2] === 16);
|
|
@@ -66,23 +62,35 @@ export class ItemsRenderer {
|
|
|
66
62
|
top: topTextureResolved,
|
|
67
63
|
left: leftTextureResolved,
|
|
68
64
|
right: rightTextureResolved,
|
|
65
|
+
resolvedModel: resolvedModel
|
|
69
66
|
};
|
|
70
67
|
}
|
|
71
|
-
getItemTexture(itemNameOrModel,
|
|
72
|
-
|
|
68
|
+
getItemTexture(itemNameOrModel, _properties = {}, exactItemResolve = false) {
|
|
69
|
+
let [_namespace, _name] = itemNameOrModel.includes(':') ? itemNameOrModel.split(':') : ['minecraft', itemNameOrModel];
|
|
70
|
+
const namespace = _namespace === 'minecraft' ? '' : _namespace;
|
|
71
|
+
const name = _name;
|
|
72
|
+
const itemModelPath = namespace ? `${namespace}:item/${name}` : `item/${name}`;
|
|
73
|
+
const blockModelPath = namespace ? `${namespace}:block/${name}` : `block/${name}`;
|
|
74
|
+
const cleanFullModelPath = namespace ? `${namespace}:${name}` : name;
|
|
73
75
|
let model;
|
|
74
|
-
if (
|
|
75
|
-
model = this.modelsStore.get(this.version,
|
|
76
|
+
if (cleanFullModelPath.includes('/') || exactItemResolve) {
|
|
77
|
+
model = this.modelsStore.get(this.version, cleanFullModelPath);
|
|
76
78
|
}
|
|
77
79
|
else {
|
|
78
|
-
model = this.modelsStore.get(this.version,
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
model = this.modelsStore.get(this.version, itemModelPath);
|
|
81
|
+
let blockModel = model?.parent?.includes('block/');
|
|
82
|
+
if (!model) {
|
|
83
|
+
model = this.modelsStore.get(this.version, blockModelPath);
|
|
84
|
+
if (model)
|
|
85
|
+
blockModel = true;
|
|
86
|
+
}
|
|
87
|
+
if (blockModel) {
|
|
88
|
+
return this.tryGetFullBlock(model, cleanFullModelPath);
|
|
81
89
|
}
|
|
82
90
|
}
|
|
83
91
|
if (!model)
|
|
84
92
|
return;
|
|
85
|
-
const texture =
|
|
93
|
+
const texture = cleanFullModelPath.includes('block/') ?
|
|
86
94
|
// first defined block texture
|
|
87
95
|
Object.values(model.textures ?? {})[0] :
|
|
88
96
|
model.textures?.layer0; // classic item texture
|
|
@@ -10,11 +10,19 @@ describe('ItemsRenderer', () => {
|
|
|
10
10
|
const itemsAtlasParser = new AtlasParser(itemsAtlases, '');
|
|
11
11
|
const blocksAtlasParser = new AtlasParser(blocksAtlases, '');
|
|
12
12
|
const renderer = new ItemsRenderer('latest', blockstatesModels, itemsAtlasParser, blocksAtlasParser);
|
|
13
|
+
const getItemTexture = (item) => {
|
|
14
|
+
const result = renderer.getItemTexture(item);
|
|
15
|
+
if (!result)
|
|
16
|
+
return result;
|
|
17
|
+
result['resolvedModel'] = !!result['resolvedModel'];
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
13
20
|
describe('getItemTexture', () => {
|
|
14
21
|
it('items texture', () => {
|
|
15
|
-
expect(
|
|
22
|
+
expect(getItemTexture('item_frame')).toMatchInlineSnapshot(`
|
|
16
23
|
{
|
|
17
24
|
"path": "items",
|
|
25
|
+
"resolvedModel": false,
|
|
18
26
|
"slice": [
|
|
19
27
|
720,
|
|
20
28
|
128,
|
|
@@ -26,7 +34,7 @@ describe('ItemsRenderer', () => {
|
|
|
26
34
|
`);
|
|
27
35
|
});
|
|
28
36
|
it('full blocks texture', () => {
|
|
29
|
-
expect(
|
|
37
|
+
expect(getItemTexture('stone')).toMatchInlineSnapshot(`
|
|
30
38
|
{
|
|
31
39
|
"left": {
|
|
32
40
|
"path": "blocks",
|
|
@@ -38,6 +46,7 @@ describe('ItemsRenderer', () => {
|
|
|
38
46
|
],
|
|
39
47
|
"type": "blocks",
|
|
40
48
|
},
|
|
49
|
+
"resolvedModel": true,
|
|
41
50
|
"right": {
|
|
42
51
|
"path": "blocks",
|
|
43
52
|
"slice": [
|
|
@@ -62,9 +71,10 @@ describe('ItemsRenderer', () => {
|
|
|
62
71
|
`);
|
|
63
72
|
});
|
|
64
73
|
it('invsprite textures', () => {
|
|
65
|
-
expect(
|
|
74
|
+
expect(getItemTexture('chest')).toMatchInlineSnapshot(`
|
|
66
75
|
{
|
|
67
76
|
"path": "items",
|
|
77
|
+
"resolvedModel": false,
|
|
68
78
|
"slice": [
|
|
69
79
|
400,
|
|
70
80
|
0,
|
|
@@ -76,7 +86,8 @@ describe('ItemsRenderer', () => {
|
|
|
76
86
|
`);
|
|
77
87
|
});
|
|
78
88
|
it('not implemented logic', () => {
|
|
79
|
-
expect(
|
|
89
|
+
expect(getItemTexture('cut_copper_slab')).toMatchInlineSnapshot(`undefined`);
|
|
90
|
+
expect(getItemTexture('bla_bla')).toMatchInlineSnapshot(`undefined`);
|
|
80
91
|
});
|
|
81
92
|
});
|
|
82
93
|
describe('resolveTexture', () => {
|
|
@@ -93,6 +104,7 @@ describe('ItemsRenderer', () => {
|
|
|
93
104
|
"type": "items",
|
|
94
105
|
}
|
|
95
106
|
`);
|
|
107
|
+
expect(renderer.resolveTexture('bla')).toMatchInlineSnapshot(`undefined`);
|
|
96
108
|
});
|
|
97
109
|
});
|
|
98
110
|
});
|
|
@@ -1,12 +1,47 @@
|
|
|
1
1
|
import { QueriedBlock } from './assetsParser';
|
|
2
|
+
import { BlockModel } from './types';
|
|
2
3
|
export default function worldBlockProvider(blockstatesModels: any, blocksAtlas: any, version: string): {
|
|
3
|
-
getAllResolvedModels0_1(block: Omit<QueriedBlock, "stateId">, fallbackVariant?: boolean): {
|
|
4
|
-
|
|
4
|
+
getAllResolvedModels0_1(block: Omit<QueriedBlock, "stateId">, fallbackVariant?: boolean): ({
|
|
5
|
+
elements: {
|
|
6
|
+
faces: {
|
|
7
|
+
[k: string]: {
|
|
8
|
+
texture: {
|
|
9
|
+
u: number;
|
|
10
|
+
v: number;
|
|
11
|
+
su: number;
|
|
12
|
+
sv: number;
|
|
13
|
+
tileIndex: number;
|
|
14
|
+
debugName: string;
|
|
15
|
+
};
|
|
16
|
+
uv?: number[];
|
|
17
|
+
cullface?: string;
|
|
18
|
+
rotation?: number;
|
|
19
|
+
tintindex?: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
from: import("./types").BlockElementPos;
|
|
23
|
+
to: import("./types").BlockElementPos;
|
|
24
|
+
rotation?: {
|
|
25
|
+
origin: [number, number, number];
|
|
26
|
+
axis: string;
|
|
27
|
+
angle: number;
|
|
28
|
+
rescale?: boolean;
|
|
29
|
+
};
|
|
30
|
+
}[];
|
|
31
|
+
} & Omit<Pick<BlockModel, "textures" | "ao" | "elements"> & {
|
|
32
|
+
x?: number;
|
|
33
|
+
y?: number;
|
|
34
|
+
z?: number;
|
|
35
|
+
uvlock?: boolean;
|
|
36
|
+
weight?: number;
|
|
37
|
+
}, "textures" | "elements">)[][];
|
|
38
|
+
transformModel: <T extends BlockModel | (Pick<BlockModel, "textures" | "ao" | "elements"> & {
|
|
5
39
|
x?: number;
|
|
6
40
|
y?: number;
|
|
7
41
|
z?: number;
|
|
8
42
|
uvlock?: boolean;
|
|
9
43
|
weight?: number;
|
|
44
|
+
})>(model: T, block: Omit<QueriedBlock, "stateId">) => {
|
|
10
45
|
elements: {
|
|
11
46
|
faces: {
|
|
12
47
|
[k: string]: {
|
|
@@ -33,8 +68,8 @@ export default function worldBlockProvider(blockstatesModels: any, blocksAtlas:
|
|
|
33
68
|
rescale?: boolean;
|
|
34
69
|
};
|
|
35
70
|
}[];
|
|
36
|
-
}
|
|
37
|
-
getTextureInfo(textureName: string)
|
|
71
|
+
} & Omit<T, "textures" | "elements">;
|
|
72
|
+
getTextureInfo: (textureName: string) => {
|
|
38
73
|
su: number;
|
|
39
74
|
sv: number;
|
|
40
75
|
getLoadedImage: () => Promise<HTMLImageElement>;
|
|
@@ -6,62 +6,67 @@ export default function worldBlockProvider(blockstatesModels, blocksAtlas, versi
|
|
|
6
6
|
const blockModelsStore = getLoadedModelsStore(blockstatesModels);
|
|
7
7
|
const assetsParser = new AssetsParser(version, blockStatesStore, blockModelsStore);
|
|
8
8
|
const atlasParser = new AtlasParser(blocksAtlas, 'latest', 'legacy');
|
|
9
|
+
const getTextureInfo = (textureName) => {
|
|
10
|
+
return atlasParser.getTextureInfo(textureName.replace('block/', '').replace('blocks/', ''), version);
|
|
11
|
+
};
|
|
12
|
+
const transformModel = (model, block) => {
|
|
13
|
+
const { elements, textures, ...rest } = model;
|
|
14
|
+
return {
|
|
15
|
+
// todo validate elements
|
|
16
|
+
elements: elements?.map((elem) => {
|
|
17
|
+
return {
|
|
18
|
+
...elem,
|
|
19
|
+
faces: Object.fromEntries(Object.entries(elem.faces).map(([faceName, face]) => {
|
|
20
|
+
const texture = face.texture;
|
|
21
|
+
if (!texture)
|
|
22
|
+
throw new Error(`Missing resolved texture ${texture} for face ${faceName} of ${block.name}`);
|
|
23
|
+
const finalTexture = getTextureInfo(texture);
|
|
24
|
+
if (!finalTexture)
|
|
25
|
+
throw new Error(`Missing texture data ${texture} for ${block.name}`);
|
|
26
|
+
const _from = elem.from;
|
|
27
|
+
const _to = elem.to;
|
|
28
|
+
// taken from https://github.com/DragonDev1906/Minecraft-Overviewer/
|
|
29
|
+
const COORDINATE_MAX = 16;
|
|
30
|
+
const uv = (face.uv || {
|
|
31
|
+
// default UVs
|
|
32
|
+
// format: [u1, v1, u2, v2] (u = x, v = y)
|
|
33
|
+
north: [_to[0], COORDINATE_MAX - _to[1], _from[0], COORDINATE_MAX - _from[1]],
|
|
34
|
+
east: [_from[2], COORDINATE_MAX - _to[1], _to[2], COORDINATE_MAX - _from[1]],
|
|
35
|
+
south: [_from[0], COORDINATE_MAX - _to[1], _to[0], COORDINATE_MAX - _from[1]],
|
|
36
|
+
west: [_from[2], COORDINATE_MAX - _to[1], _to[2], COORDINATE_MAX - _from[1]],
|
|
37
|
+
up: [_from[0], _from[2], _to[0], _to[2]],
|
|
38
|
+
down: [_to[0], _from[2], _from[0], _to[2]]
|
|
39
|
+
}[faceName]);
|
|
40
|
+
const su = (uv[2] - uv[0]) / COORDINATE_MAX * finalTexture.su;
|
|
41
|
+
const sv = (uv[3] - uv[1]) / COORDINATE_MAX * finalTexture.sv;
|
|
42
|
+
return [faceName, {
|
|
43
|
+
...face,
|
|
44
|
+
texture: {
|
|
45
|
+
u: finalTexture.u + uv[0] / 16 * finalTexture.su,
|
|
46
|
+
v: finalTexture.v + uv[1] / 16 * finalTexture.sv,
|
|
47
|
+
su,
|
|
48
|
+
sv,
|
|
49
|
+
tileIndex: finalTexture.tileIndex,
|
|
50
|
+
debugName: texture,
|
|
51
|
+
},
|
|
52
|
+
}];
|
|
53
|
+
}))
|
|
54
|
+
};
|
|
55
|
+
}),
|
|
56
|
+
...rest
|
|
57
|
+
};
|
|
58
|
+
};
|
|
9
59
|
return {
|
|
10
60
|
getAllResolvedModels0_1(block, fallbackVariant = false) {
|
|
11
61
|
const modelsParts = assetsParser.getAllResolvedModels(block, fallbackVariant) ?? [];
|
|
12
62
|
const interestedFaces = ['north', 'east', 'south', 'west', 'up', 'down'];
|
|
13
63
|
return modelsParts.map(modelVariants => {
|
|
14
64
|
return modelVariants.map(model => {
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
// todo validate elements
|
|
18
|
-
elements: elements?.map((elem) => {
|
|
19
|
-
return {
|
|
20
|
-
...elem,
|
|
21
|
-
faces: Object.fromEntries(Object.entries(elem.faces).map(([faceName, face]) => {
|
|
22
|
-
const texture = face.texture;
|
|
23
|
-
if (!texture)
|
|
24
|
-
throw new Error(`Missing resolved texture ${texture} for face ${faceName} of ${block.name}`);
|
|
25
|
-
const finalTexture = this.getTextureInfo(texture);
|
|
26
|
-
if (!finalTexture)
|
|
27
|
-
throw new Error(`Missing texture data ${texture} for ${block.name}`);
|
|
28
|
-
const _from = elem.from;
|
|
29
|
-
const _to = elem.to;
|
|
30
|
-
// taken from https://github.com/DragonDev1906/Minecraft-Overviewer/
|
|
31
|
-
const COORDINATE_MAX = 16;
|
|
32
|
-
const uv = (face.uv || {
|
|
33
|
-
// default UVs
|
|
34
|
-
// format: [u1, v1, u2, v2] (u = x, v = y)
|
|
35
|
-
north: [_to[0], COORDINATE_MAX - _to[1], _from[0], COORDINATE_MAX - _from[1]],
|
|
36
|
-
east: [_from[2], COORDINATE_MAX - _to[1], _to[2], COORDINATE_MAX - _from[1]],
|
|
37
|
-
south: [_from[0], COORDINATE_MAX - _to[1], _to[0], COORDINATE_MAX - _from[1]],
|
|
38
|
-
west: [_from[2], COORDINATE_MAX - _to[1], _to[2], COORDINATE_MAX - _from[1]],
|
|
39
|
-
up: [_from[0], _from[2], _to[0], _to[2]],
|
|
40
|
-
down: [_to[0], _from[2], _from[0], _to[2]]
|
|
41
|
-
}[faceName]);
|
|
42
|
-
const su = (uv[2] - uv[0]) / COORDINATE_MAX * finalTexture.su;
|
|
43
|
-
const sv = (uv[3] - uv[1]) / COORDINATE_MAX * finalTexture.sv;
|
|
44
|
-
return [faceName, {
|
|
45
|
-
...face,
|
|
46
|
-
texture: {
|
|
47
|
-
u: finalTexture.u + uv[0] / 16 * finalTexture.su,
|
|
48
|
-
v: finalTexture.v + uv[1] / 16 * finalTexture.sv,
|
|
49
|
-
su,
|
|
50
|
-
sv,
|
|
51
|
-
tileIndex: finalTexture.tileIndex,
|
|
52
|
-
debugName: texture,
|
|
53
|
-
},
|
|
54
|
-
}];
|
|
55
|
-
}))
|
|
56
|
-
};
|
|
57
|
-
}),
|
|
58
|
-
...rest
|
|
59
|
-
};
|
|
65
|
+
return transformModel(model, block);
|
|
60
66
|
}).filter(a => a.elements?.length);
|
|
61
67
|
}).filter(a => a.length);
|
|
62
68
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
69
|
+
transformModel,
|
|
70
|
+
getTextureInfo
|
|
66
71
|
};
|
|
67
72
|
}
|