-
-
Notifications
You must be signed in to change notification settings - Fork 409
Expand file tree
/
Copy pathSpriteAtlasLoader.ts
More file actions
111 lines (109 loc) · 4.22 KB
/
Copy pathSpriteAtlasLoader.ts
File metadata and controls
111 lines (109 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import {
AssetPromise,
AssetType,
Engine,
Loader,
LoadItem,
resourceLoader,
ResourceManager,
Sprite,
SpriteAtlas,
Texture2D,
Utils
} from "@galacean/engine-core";
import { AtlasConfig, AtlasSprite } from "@galacean/engine-core/types/2d/atlas/types";
import { Rect, Vector2, Vector4 } from "@galacean/engine-math";
@resourceLoader(AssetType.SpriteAtlas, ["atlas"])
class SpriteAtlasLoader extends Loader<SpriteAtlas> {
private _tempRect: Rect = new Rect();
private _tempVec2: Vector2 = new Vector2();
private _tempVec4: Vector4 = new Vector4();
load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<SpriteAtlas> {
return new AssetPromise<SpriteAtlas>((resolve, reject, _, __, onCancel) => {
const chainPromises = [];
onCancel(() => {
for (let i = 0; i < chainPromises.length; i++) {
chainPromises[i].cancel();
}
});
// @ts-ignore
const configPromise = resourceManager._request<AtlasConfig>(item.url, {
...item,
type: "json"
});
chainPromises.push(configPromise);
configPromise
.then((atlasData) => {
const { atlasItems, mipmap, anisoLevel, filterMode, wrapModeU, wrapModeV, format } = atlasData;
const atlasItemsLen = atlasItems ? atlasItems.length : 0;
const { engine } = resourceManager;
const spriteAtlas = new SpriteAtlas(engine);
if (atlasItemsLen <= 0) {
resolve(spriteAtlas);
return;
}
chainPromises.length = 0;
for (let i = 0; i < atlasItemsLen; i++) {
const atlasItem = atlasItems[i];
if (atlasItem.img) {
chainPromises.push(
resourceManager
.load<Texture2D>({
url: Utils.resolveAbsoluteUrl(item.url, atlasItem.img),
type: atlasItem.type ?? AssetType.Texture,
params: { format, mipmap }
})
.then((texture: Texture2D) => {
anisoLevel && (texture.anisoLevel = anisoLevel);
filterMode !== undefined && (texture.filterMode = filterMode);
wrapModeU !== undefined && (texture.wrapModeU = wrapModeU);
wrapModeV !== undefined && (texture.wrapModeV = wrapModeV);
for (let i = 0; i < atlasItem.sprites.length; i++) {
// @ts-ignore
spriteAtlas._addSprite(this._makeSprite(engine, atlasItem.sprites[i], texture));
}
})
.catch(reject)
);
} else {
for (let i = 0; i < atlasItem.sprites.length; i++) {
// @ts-ignore
spriteAtlas._addSprite(this._makeSprite(engine, atlasItem.sprites[i]));
}
}
}
AssetPromise.all(chainPromises)
.then(() => {
resolve(spriteAtlas);
})
.catch(reject);
})
.catch(reject);
});
}
private _makeSprite(engine: Engine, config: AtlasSprite, texture?: Texture2D): Sprite {
// Generate a SpriteAtlas object.
const { region, atlasRegionOffset, atlasRegion, pivot, border, width, height } = config;
const sprite = new Sprite(
engine,
texture,
region ? this._tempRect.set(region.x, region.y, region.w, region.h) : undefined,
pivot ? this._tempVec2.set(pivot.x, pivot.y) : undefined,
border ? this._tempVec4.set(border.x, border.y, border.z, border.w) : undefined,
config.name
);
if (texture) {
const invW = 1 / texture.width;
const invH = 1 / texture.height;
sprite.atlasRegion.set(atlasRegion.x * invW, atlasRegion.y * invH, atlasRegion.w * invW, atlasRegion.h * invH);
if (atlasRegionOffset) {
const { x: offsetLeft, y: offsetTop, z: offsetRight, w: offsetBottom } = atlasRegionOffset;
sprite.atlasRegionOffset.set(offsetLeft * invW, offsetTop * invH, offsetRight * invW, offsetBottom * invH);
}
sprite.atlasRotated = config.atlasRotated ?? false;
}
width === undefined || (sprite.width = width);
height === undefined || (sprite.height = height);
return sprite;
}
}