mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-11-12 20:32:58 +08:00
Compare commits
1 Commits
0b33809ff2
...
f8baf9cb25
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8baf9cb25 |
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@user/client-base",
|
|
||||||
"dependencies": {
|
|
||||||
"@motajs/render-asset": "workspace:*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { createMaterial } from './material';
|
|
||||||
|
|
||||||
export function create() {
|
|
||||||
createMaterial();
|
|
||||||
}
|
|
||||||
|
|
||||||
export * from './material';
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import {
|
|
||||||
ITextureStore,
|
|
||||||
ITexture,
|
|
||||||
ITextureComposedData,
|
|
||||||
ITextureStreamComposer,
|
|
||||||
TextureMaxRectsStreamComposer
|
|
||||||
} from '@motajs/render-assets';
|
|
||||||
import { IAssetBuilder } from './types';
|
|
||||||
import { logger } from '@motajs/common';
|
|
||||||
|
|
||||||
export class AssetBuilder implements IAssetBuilder {
|
|
||||||
readonly composer: ITextureStreamComposer<void> =
|
|
||||||
new TextureMaxRectsStreamComposer(4096, 4096, 0);
|
|
||||||
|
|
||||||
private output: ITextureStore | null = null;
|
|
||||||
private started: boolean = false;
|
|
||||||
|
|
||||||
pipe(store: ITextureStore): void {
|
|
||||||
if (this.started) {
|
|
||||||
logger.warn(76);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.output = store;
|
|
||||||
}
|
|
||||||
|
|
||||||
addTexture(texture: ITexture): ITextureComposedData {
|
|
||||||
this.started = true;
|
|
||||||
const res = [...this.composer.add([texture])];
|
|
||||||
const data = res[0];
|
|
||||||
if (this.output) {
|
|
||||||
if (!this.output.getTexture(data.index)) {
|
|
||||||
this.output.addTexture(data.index, data.texture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
addTextureList(
|
|
||||||
texture: Iterable<ITexture>
|
|
||||||
): Iterable<ITextureComposedData> {
|
|
||||||
this.started = true;
|
|
||||||
const res = [...this.composer.add(texture)];
|
|
||||||
if (this.output) {
|
|
||||||
res.forEach(v => {
|
|
||||||
if (!this.output!.getTexture(v.index)) {
|
|
||||||
this.output!.addTexture(v.index, v.texture);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(): void {
|
|
||||||
this.composer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
export function createMaterial() {}
|
|
||||||
|
|
||||||
export * from './manager';
|
|
||||||
@ -1,325 +0,0 @@
|
|||||||
import {
|
|
||||||
ITexture,
|
|
||||||
ITextureComposedData,
|
|
||||||
ITextureRenderable,
|
|
||||||
ITextureSplitter,
|
|
||||||
ITextureStore,
|
|
||||||
SizedCanvasImageSource,
|
|
||||||
Texture,
|
|
||||||
TextureColumnAnimater,
|
|
||||||
TextureGridSplitter,
|
|
||||||
TextureRowSplitter,
|
|
||||||
TextureStore
|
|
||||||
} from '@motajs/render-assets';
|
|
||||||
import {
|
|
||||||
IBlockIdentifier,
|
|
||||||
IMaterialData,
|
|
||||||
IMaterialManager,
|
|
||||||
IIndexedIdentifier,
|
|
||||||
IMaterialAssetData,
|
|
||||||
BlockCls,
|
|
||||||
IBigImageData,
|
|
||||||
IAssetBuilder
|
|
||||||
} from './types';
|
|
||||||
import { logger } from '@motajs/common';
|
|
||||||
import { getClsByString } from './utils';
|
|
||||||
import { isNil } from 'lodash-es';
|
|
||||||
import { AssetBuilder } from './builder';
|
|
||||||
|
|
||||||
export class MaterialManager implements IMaterialManager {
|
|
||||||
readonly tileStore: ITextureStore = new TextureStore();
|
|
||||||
readonly tilesetStore: ITextureStore = new TextureStore();
|
|
||||||
readonly imageStore: ITextureStore = new TextureStore();
|
|
||||||
readonly assetStore: ITextureStore = new TextureStore();
|
|
||||||
readonly bigImageStore: ITextureStore = new TextureStore();
|
|
||||||
|
|
||||||
/** 图集信息存储 */
|
|
||||||
readonly assetDataStore: Map<number, ITextureComposedData> = new Map();
|
|
||||||
/** 大怪物数据 */
|
|
||||||
readonly bigImageData: Map<number, ITexture> = new Map();
|
|
||||||
/** tileset 中 `Math.floor(id / 10000) + 1` 映射到 tileset 对应索引的映射,用于处理图块超出 10000 的 tileset */
|
|
||||||
readonly tilesetOffsetMap: Map<number, number> = new Map();
|
|
||||||
/** 图集打包器 */
|
|
||||||
readonly assetBuilder: IAssetBuilder = new AssetBuilder();
|
|
||||||
|
|
||||||
readonly idNumMap: Map<string, number> = new Map();
|
|
||||||
readonly numIdMap: Map<number, string> = new Map();
|
|
||||||
readonly clsMap: Map<number, BlockCls> = new Map();
|
|
||||||
|
|
||||||
/** 网格切分器 */
|
|
||||||
readonly gridSplitter: TextureGridSplitter = new TextureGridSplitter();
|
|
||||||
/** 行切分器 */
|
|
||||||
readonly rowSplitter: TextureRowSplitter = new TextureRowSplitter();
|
|
||||||
|
|
||||||
/** 大怪物贴图的标识符 */
|
|
||||||
private bigImageId: number = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加由分割器和图块映射组成的图像源贴图
|
|
||||||
* @param source 图像源
|
|
||||||
* @param map 图块 id 与图块数字映射
|
|
||||||
* @param store 要添加至的贴图存储对象
|
|
||||||
* @param splitter 使用的分割器
|
|
||||||
* @param splitterData 传递给分割器的数据
|
|
||||||
* @param processTexture 对每个纹理进行处理
|
|
||||||
*/
|
|
||||||
private addMappedSource<T>(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
map: ArrayLike<IBlockIdentifier>,
|
|
||||||
store: ITextureStore,
|
|
||||||
splitter: ITextureSplitter<T>,
|
|
||||||
splitterData: T,
|
|
||||||
processTexture?: (tex: ITexture) => void
|
|
||||||
): Iterable<IMaterialData> {
|
|
||||||
const tex = new Texture(source);
|
|
||||||
const textures = [...splitter.split(tex, splitterData)];
|
|
||||||
if (textures.length !== map.length) {
|
|
||||||
logger.warn(75, textures.length.toString(), map.length.toString());
|
|
||||||
}
|
|
||||||
const res: IMaterialData[] = textures.map((v, i) => {
|
|
||||||
const { id, num, cls } = map[i];
|
|
||||||
store.addTexture(num, v);
|
|
||||||
store.alias(num, id);
|
|
||||||
this.clsMap.set(num, getClsByString(cls));
|
|
||||||
processTexture?.(v);
|
|
||||||
const data: IMaterialData = {
|
|
||||||
store,
|
|
||||||
texture: v,
|
|
||||||
identifier: num,
|
|
||||||
alias: id
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
addGrid(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
map: ArrayLike<IBlockIdentifier>
|
|
||||||
): Iterable<IMaterialData> {
|
|
||||||
return this.addMappedSource(
|
|
||||||
source,
|
|
||||||
map,
|
|
||||||
this.tileStore,
|
|
||||||
this.gridSplitter,
|
|
||||||
[32, 32]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
addRowAnimate(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
map: ArrayLike<IBlockIdentifier>,
|
|
||||||
frames: number
|
|
||||||
): Iterable<IMaterialData> {
|
|
||||||
return this.addMappedSource(
|
|
||||||
source,
|
|
||||||
map,
|
|
||||||
this.tileStore,
|
|
||||||
this.rowSplitter,
|
|
||||||
32,
|
|
||||||
(tex: ITexture<number>) => {
|
|
||||||
tex.animated(new TextureColumnAnimater(), frames);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
addAutotile(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
identifier: IBlockIdentifier
|
|
||||||
): IMaterialData {
|
|
||||||
const texture = new Texture(source);
|
|
||||||
this.tileStore.addTexture(identifier.num, texture);
|
|
||||||
this.tileStore.alias(identifier.num, identifier.id);
|
|
||||||
this.clsMap.set(identifier.num, BlockCls.Autotile);
|
|
||||||
const data: IMaterialData = {
|
|
||||||
store: this.tileStore,
|
|
||||||
texture,
|
|
||||||
identifier: identifier.num,
|
|
||||||
alias: identifier.id
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
addTileset(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
identifier: IIndexedIdentifier
|
|
||||||
): IMaterialData {
|
|
||||||
const tex = new Texture(source);
|
|
||||||
this.tilesetStore.addTexture(identifier.index, tex);
|
|
||||||
this.tilesetStore.alias(identifier.index, identifier.alias);
|
|
||||||
const data: IMaterialData = {
|
|
||||||
store: this.tilesetStore,
|
|
||||||
texture: tex,
|
|
||||||
identifier: identifier.index,
|
|
||||||
alias: identifier.alias
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
addImage(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
identifier: IIndexedIdentifier
|
|
||||||
): IMaterialData {
|
|
||||||
const texture = new Texture(source);
|
|
||||||
this.imageStore.addTexture(identifier.index, texture);
|
|
||||||
this.imageStore.alias(identifier.index, identifier.alias);
|
|
||||||
const data: IMaterialData = {
|
|
||||||
store: this.imageStore,
|
|
||||||
texture,
|
|
||||||
identifier: identifier.index,
|
|
||||||
alias: identifier.alias
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTile(identifier: number): ITexture | null {
|
|
||||||
return this.tileStore.getTexture(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
getTileset(identifier: number): ITexture | null {
|
|
||||||
return this.tilesetStore.getTexture(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
getImage(identifier: number): ITexture | null {
|
|
||||||
return this.imageStore.getTexture(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
getTileByAlias(alias: string): ITexture | null {
|
|
||||||
return this.tileStore.fromAlias(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
getTilesetByAlias(alias: string): ITexture | null {
|
|
||||||
return this.tilesetStore.fromAlias(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
getImageByAlias(alias: string): ITexture | null {
|
|
||||||
return this.imageStore.fromAlias(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
buildAssets(): Iterable<IMaterialAssetData> {
|
|
||||||
this.assetBuilder.pipe(this.assetStore);
|
|
||||||
const data = this.assetBuilder.addTextureList(this.tileStore.values());
|
|
||||||
const arr = [...data];
|
|
||||||
const res: IMaterialAssetData[] = [];
|
|
||||||
arr.forEach((v, i) => {
|
|
||||||
const alias = `asset-${i}`;
|
|
||||||
this.assetStore.alias(i, alias);
|
|
||||||
const data: IMaterialAssetData = {
|
|
||||||
data: v,
|
|
||||||
identifier: i,
|
|
||||||
alias,
|
|
||||||
store: this.assetStore
|
|
||||||
};
|
|
||||||
for (const tex of v.assetMap.keys()) {
|
|
||||||
tex.toAsset(v);
|
|
||||||
}
|
|
||||||
res.push(data);
|
|
||||||
});
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAsset(identifier: number): ITextureComposedData | null {
|
|
||||||
return this.assetDataStore.get(identifier) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAssetByAlias(alias: string): ITextureComposedData | null {
|
|
||||||
const id = this.assetStore.identifierOf(alias);
|
|
||||||
if (isNil(id)) return null;
|
|
||||||
return this.assetDataStore.get(id) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private getTextureOf(identifier: number, cls: BlockCls): ITexture | null {
|
|
||||||
if (cls === BlockCls.Unknown) return null;
|
|
||||||
if (cls !== BlockCls.Tileset) {
|
|
||||||
return this.tileStore.getTexture(identifier);
|
|
||||||
}
|
|
||||||
if (identifier < 10000) return null;
|
|
||||||
const texture = this.tileStore.getTexture(identifier);
|
|
||||||
if (texture) return texture;
|
|
||||||
// 如果 tileset 不存在,那么执行缓存操作
|
|
||||||
const offset = Math.floor(identifier / 10000);
|
|
||||||
const index = this.tilesetOffsetMap.get(offset);
|
|
||||||
if (isNil(index)) return null;
|
|
||||||
// 获取对应的 tileset 贴图
|
|
||||||
const tileset = this.tilesetStore.getTexture(index);
|
|
||||||
if (!tileset) return null;
|
|
||||||
// 计算图块位置
|
|
||||||
const rest = identifier - offset * 10000;
|
|
||||||
const { width, height } = tileset;
|
|
||||||
const tileWidth = Math.floor(width / 32);
|
|
||||||
const tileHeight = Math.floor(height / 32);
|
|
||||||
// 如果图块位置超出了贴图范围
|
|
||||||
if (rest > tileWidth * tileHeight) return null;
|
|
||||||
// 裁剪 tileset,生成贴图
|
|
||||||
const x = rest % tileWidth;
|
|
||||||
const y = Math.floor(rest / tileWidth);
|
|
||||||
const newTexture = new Texture(tileset.source);
|
|
||||||
newTexture.clip(x * 32, y * 32, 32, 32);
|
|
||||||
// 缓存贴图
|
|
||||||
this.tileStore.addTexture(identifier, newTexture);
|
|
||||||
this.idNumMap.set(`X${identifier}`, identifier);
|
|
||||||
this.numIdMap.set(identifier, `X${identifier}`);
|
|
||||||
const data = this.assetBuilder.addTexture(newTexture);
|
|
||||||
newTexture.toAsset(data);
|
|
||||||
return newTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRenderable(identifier: number): ITextureRenderable | null {
|
|
||||||
const cls = this.clsMap.get(identifier);
|
|
||||||
if (isNil(cls)) return null;
|
|
||||||
const texture = this.getTextureOf(identifier, cls);
|
|
||||||
if (!texture) return null;
|
|
||||||
return texture.static();
|
|
||||||
}
|
|
||||||
|
|
||||||
getRenderableByAlias(alias: string): ITextureRenderable | null {
|
|
||||||
const identifier = this.idNumMap.get(alias);
|
|
||||||
if (isNil(identifier)) return null;
|
|
||||||
return this.getRenderable(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
getBlockCls(identifier: number): BlockCls {
|
|
||||||
return this.clsMap.get(identifier) ?? BlockCls.Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBlockClsByAlias(alias: string): BlockCls {
|
|
||||||
const id = this.idNumMap.get(alias);
|
|
||||||
if (isNil(id)) return BlockCls.Unknown;
|
|
||||||
return this.clsMap.get(id) ?? BlockCls.Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
getIdentifierByAlias(alias: string): number | undefined {
|
|
||||||
return this.idNumMap.get(alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
getAliasByIdentifier(identifier: number): string | undefined {
|
|
||||||
return this.numIdMap.get(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
setBigImage(identifier: number, image: ITexture): IBigImageData {
|
|
||||||
const bigImageId = this.bigImageId++;
|
|
||||||
this.bigImageStore.addTexture(bigImageId, image);
|
|
||||||
this.bigImageData.set(identifier, image);
|
|
||||||
const data: IBigImageData = {
|
|
||||||
identifier: bigImageId,
|
|
||||||
store: this.bigImageStore
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
isBigImage(identifier: number): boolean {
|
|
||||||
return this.bigImageData.has(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
getBigImage(identifier: number): ITexture | null {
|
|
||||||
return this.bigImageData.get(identifier) ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBigImageByAlias(alias: string): ITexture | null {
|
|
||||||
const identifier = this.idNumMap.get(alias);
|
|
||||||
if (isNil(identifier)) return null;
|
|
||||||
return this.bigImageData.get(identifier) ?? null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const materials = new MaterialManager();
|
|
||||||
@ -1,330 +0,0 @@
|
|||||||
import {
|
|
||||||
IRect,
|
|
||||||
ITexture,
|
|
||||||
ITextureComposedData,
|
|
||||||
ITextureRenderable,
|
|
||||||
ITextureStore,
|
|
||||||
SizedCanvasImageSource
|
|
||||||
} from '@motajs/render-assets';
|
|
||||||
|
|
||||||
export const enum BlockCls {
|
|
||||||
Unknown,
|
|
||||||
Terrains,
|
|
||||||
Animates,
|
|
||||||
Enemys,
|
|
||||||
Npcs,
|
|
||||||
Items,
|
|
||||||
Enemy48,
|
|
||||||
Npc48,
|
|
||||||
Tileset,
|
|
||||||
Autotile
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMaterialData {
|
|
||||||
/** 此素材的贴图对象存入了哪个贴图存储对象 */
|
|
||||||
readonly store: ITextureStore;
|
|
||||||
/** 贴图对象 */
|
|
||||||
readonly texture: ITexture;
|
|
||||||
/** 此素材的贴图对象的数字 id,一般对应到图块数字 */
|
|
||||||
readonly identifier: number;
|
|
||||||
/** 此素材的贴图对象的字符串别名,一般对应到图块 id */
|
|
||||||
readonly alias?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IBlockIdentifier {
|
|
||||||
/** 图块 id */
|
|
||||||
readonly id: string;
|
|
||||||
/** 图块数字 */
|
|
||||||
readonly num: number;
|
|
||||||
/** 图块类型 */
|
|
||||||
readonly cls: Cls;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IIndexedIdentifier {
|
|
||||||
/** 标识符索引 */
|
|
||||||
readonly index: number;
|
|
||||||
/** 标识符别名 */
|
|
||||||
readonly alias: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMaterialAssetData {
|
|
||||||
/** 图集数据 */
|
|
||||||
readonly data: ITextureComposedData;
|
|
||||||
/** 贴图的标识符 */
|
|
||||||
readonly identifier: number;
|
|
||||||
/** 贴图的别名 */
|
|
||||||
readonly alias: string;
|
|
||||||
/** 贴图所属的存储对象 */
|
|
||||||
readonly store: ITextureStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAutotileConnection {
|
|
||||||
/** 连接方式,上方连接是第一位,顺时针旋转位次依次升高 */
|
|
||||||
readonly connection: number;
|
|
||||||
/** 中心自动元件对应的图块数字 */
|
|
||||||
readonly center: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAutotileRenderable {
|
|
||||||
/** 自动元件的图像源 */
|
|
||||||
readonly source: SizedCanvasImageSource;
|
|
||||||
/** 渲染的矩形范围 */
|
|
||||||
readonly rects: Readonly<IRect>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IBigImageData {
|
|
||||||
/** 大怪物贴图在 store 中的标识符 */
|
|
||||||
readonly identifier: number;
|
|
||||||
/** 存储大怪物贴图的存储对象 */
|
|
||||||
readonly store: ITextureStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAutotileProcessor {
|
|
||||||
/** 该自动元件处理器使用的素材管理器 */
|
|
||||||
readonly manager: IMaterialManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置一个自动元件的父元件,一个自动元件可以有多个父元件
|
|
||||||
* @param autotile 自动元件
|
|
||||||
* @param parent 自动元件的父元件
|
|
||||||
*/
|
|
||||||
setParent(autotile: number, parent: number): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取自动元件的链接情况
|
|
||||||
* @param array 地图图块数组
|
|
||||||
* @param index 自动元件图块所在的索引
|
|
||||||
* @param edge 当前图块的边缘连接情况
|
|
||||||
*/
|
|
||||||
connect(
|
|
||||||
array: Float32Array,
|
|
||||||
index: number,
|
|
||||||
edge: number
|
|
||||||
): IAutotileConnection;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定自动元件的可渲染对象
|
|
||||||
* @param autotile 自动元件的图块数字
|
|
||||||
* @param connection 连接方式,上方连接是第一位,顺时针旋转位次依次升高
|
|
||||||
*/
|
|
||||||
render(autotile: number, connection: number): IAutotileRenderable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过可渲染对象输出自动元件经过连接的可渲染对象
|
|
||||||
* @param renderable 自动元件的原始可渲染对象
|
|
||||||
* @param connection 自动元件的链接方式
|
|
||||||
*/
|
|
||||||
fromRenderable(
|
|
||||||
renderable: ITextureRenderable,
|
|
||||||
connection: number
|
|
||||||
): IAutotileRenderable;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IMaterialManager {
|
|
||||||
/** 贴图存储,把 terrains 等内容单独分开存储 */
|
|
||||||
readonly tileStore: ITextureStore;
|
|
||||||
/** tilesets 贴图存储,每个 tileset 是一个贴图对象 */
|
|
||||||
readonly tilesetStore: ITextureStore;
|
|
||||||
/** 存储注册的图像的存储对象 */
|
|
||||||
readonly imageStore: ITextureStore;
|
|
||||||
/** 图集存储,将常用贴图存入其中 */
|
|
||||||
readonly assetStore: ITextureStore;
|
|
||||||
/** bigImage 存储,存储大怪物数据 */
|
|
||||||
readonly bigImageStore: ITextureStore;
|
|
||||||
|
|
||||||
/** 图块类型映射 */
|
|
||||||
readonly clsMap: Map<number, BlockCls>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加网格类型的贴图,包括 terrains 和 items 类型
|
|
||||||
* @param source 图像源
|
|
||||||
* @param map 贴图字符串 id 与图块数字映射,按照先从左到右,再从上到下的顺序映射
|
|
||||||
*/
|
|
||||||
addGrid(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
map: ArrayLike<IBlockIdentifier>
|
|
||||||
): Iterable<IMaterialData>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加行动画的贴图,包括 animates enemys npcs enemy48 npc48 类型
|
|
||||||
* @param source 图像源
|
|
||||||
* @param map 贴图字符串 id 与图块数字映射,按从上到下的顺序映射
|
|
||||||
* @param frames 每一行的帧数
|
|
||||||
*/
|
|
||||||
addRowAnimate(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
map: ArrayLike<IBlockIdentifier>,
|
|
||||||
frames: number
|
|
||||||
): Iterable<IMaterialData>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加自动元件
|
|
||||||
* @param source 图像源
|
|
||||||
* @param identifier 自动元件的字符串 id 及图块数字
|
|
||||||
*/
|
|
||||||
addAutotile(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
identifier: IBlockIdentifier
|
|
||||||
): IMaterialData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一个 tileset 类型的素材
|
|
||||||
* @param source 图像源
|
|
||||||
* @param alias tileset 的标识符,包含其在 tilesets 列表中的索引和图片名称
|
|
||||||
*/
|
|
||||||
addTileset(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
identifier: IIndexedIdentifier
|
|
||||||
): IMaterialData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一个图片
|
|
||||||
* @param source 图像源
|
|
||||||
* @param identifier 图片的标识符,包含其在 images 列表中的索引和图片名称
|
|
||||||
*/
|
|
||||||
addImage(
|
|
||||||
source: SizedCanvasImageSource,
|
|
||||||
identifier: IIndexedIdentifier
|
|
||||||
): IMaterialData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块数字获取图块,可以获取额外素材,会自动将未缓存的额外素材缓存
|
|
||||||
* @param identifier 图块的图块数字
|
|
||||||
*/
|
|
||||||
getTile(identifier: number): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据额外素材索引获取额外素材
|
|
||||||
* @param identifier 额外素材的索引
|
|
||||||
*/
|
|
||||||
getTileset(identifier: number): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图片的索引获取图片
|
|
||||||
* @param identifier 图片的索引
|
|
||||||
*/
|
|
||||||
getImage(identifier: number): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块 id 获取图块,可以获取额外素材,会自动将未缓存的额外素材缓存
|
|
||||||
* @param alias 图块 id
|
|
||||||
*/
|
|
||||||
getTileByAlias(alias: string): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据额外素材名称获取额外素材
|
|
||||||
* @param alias 额外素材名称
|
|
||||||
*/
|
|
||||||
getTilesetByAlias(alias: string): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图片名称获取图片
|
|
||||||
* @param alias 图片名称
|
|
||||||
*/
|
|
||||||
getImageByAlias(alias: string): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 把常用素材打包成为图集形式供后续使用
|
|
||||||
*/
|
|
||||||
buildAssets(): Iterable<IMaterialAssetData>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据标识符获取图集信息
|
|
||||||
* @param identifier 图集的标识符
|
|
||||||
*/
|
|
||||||
getAsset(identifier: number): ITextureComposedData | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据别名获取图集信息
|
|
||||||
* @param alias 图集的别名
|
|
||||||
*/
|
|
||||||
getAssetByAlias(alias: string): ITextureComposedData | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块标识符在图集中获取对应的可渲染对象
|
|
||||||
* @param identifier 图块标识符,即图块数字
|
|
||||||
*/
|
|
||||||
getRenderable(identifier: number): ITextureRenderable | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块别名在图集中获取对应的可渲染对象
|
|
||||||
* @param alias 图块的别名,即图块的 id
|
|
||||||
*/
|
|
||||||
getRenderableByAlias(alias: string): ITextureRenderable | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块标识符获取图块类型
|
|
||||||
* @param identifier 图块标识符,即图块数字
|
|
||||||
*/
|
|
||||||
getBlockCls(identifier: number): BlockCls;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块别名获取图块类型
|
|
||||||
* @param alias 图块别名,即图块的 id
|
|
||||||
*/
|
|
||||||
getBlockClsByAlias(alias: string): BlockCls;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块别名获取图块标识符,即图块数字
|
|
||||||
* @param alias 图块别名,即图块的 id
|
|
||||||
*/
|
|
||||||
getIdentifierByAlias(alias: string): number | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块标识符获取图块别名,即图块的 id
|
|
||||||
* @param identifier 图块标识符,即图块数字
|
|
||||||
*/
|
|
||||||
getAliasByIdentifier(identifier: number): string | undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置一个图块的 `bigImage` 贴图,即大怪物贴图,但不止怪物能用
|
|
||||||
* @param identifier 图块标识符,即图块数字
|
|
||||||
* @param image `bigImage` 对应的贴图对象
|
|
||||||
*/
|
|
||||||
setBigImage(identifier: number, image: ITexture): IBigImageData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断一个图块是否包含 `bigImage` 贴图,即是否是大怪物
|
|
||||||
* @param identifier 图块标识符,即图块数字
|
|
||||||
*/
|
|
||||||
isBigImage(identifier: number): boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块标识符获取一个图块的 `bigImage` 贴图
|
|
||||||
* @param identifier 图块标识符,即图块数字
|
|
||||||
*/
|
|
||||||
getBigImage(identifier: number): ITexture | null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据图块别名获取一个图块的 `bigImage` 贴图
|
|
||||||
* @param alias 图块别名,即图块的 id
|
|
||||||
*/
|
|
||||||
getBigImageByAlias(alias: string): ITexture | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAssetBuilder {
|
|
||||||
/**
|
|
||||||
* 将图集打包器输出至指定贴图存储对象,只能输出到一个存储对象中,设置多个仅最后一个有效
|
|
||||||
* @param store 贴图存储对象
|
|
||||||
*/
|
|
||||||
pipe(store: ITextureStore): void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加贴图对象至打包器
|
|
||||||
* @param texture 贴图对象
|
|
||||||
* @returns 当前打包的贴图对象对应的组合数据
|
|
||||||
*/
|
|
||||||
addTexture(texture: ITexture): ITextureComposedData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加一个贴图对象列表至打包器
|
|
||||||
* @param texture 贴图对象列表
|
|
||||||
* @returns 当前打包的贴图列表的组合数据,每一项代表一个图集,只包含使用到的图集,之前已经打包完成的将不会在列表内
|
|
||||||
*/
|
|
||||||
addTextureList(texture: Iterable<ITexture>): Iterable<ITextureComposedData>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结束此打包器
|
|
||||||
*/
|
|
||||||
close(): void;
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { BlockCls } from './types';
|
|
||||||
|
|
||||||
export function getClsByString(cls: Cls): BlockCls {
|
|
||||||
switch (cls) {
|
|
||||||
case 'terrains':
|
|
||||||
return BlockCls.Terrains;
|
|
||||||
case 'animates':
|
|
||||||
return BlockCls.Animates;
|
|
||||||
case 'autotile':
|
|
||||||
return BlockCls.Autotile;
|
|
||||||
case 'enemys':
|
|
||||||
return BlockCls.Enemys;
|
|
||||||
case 'items':
|
|
||||||
return BlockCls.Items;
|
|
||||||
case 'npcs':
|
|
||||||
return BlockCls.Npcs;
|
|
||||||
case 'npc48':
|
|
||||||
return BlockCls.Npc48;
|
|
||||||
case 'enemy48':
|
|
||||||
return BlockCls.Enemy48;
|
|
||||||
case 'tileset':
|
|
||||||
return BlockCls.Tileset;
|
|
||||||
default:
|
|
||||||
return BlockCls.Unknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,7 +5,6 @@
|
|||||||
"@motajs/client-base": "workspace:*",
|
"@motajs/client-base": "workspace:*",
|
||||||
"@motajs/common": "workspace:*",
|
"@motajs/common": "workspace:*",
|
||||||
"@motajs/render": "workspace:*",
|
"@motajs/render": "workspace:*",
|
||||||
"@motajs/render-assets": "workspace:*",
|
|
||||||
"@motajs/render-core": "workspace:*",
|
"@motajs/render-core": "workspace:*",
|
||||||
"@motajs/render-elements": "workspace:*",
|
"@motajs/render-elements": "workspace:*",
|
||||||
"@motajs/render-style": "workspace:*",
|
"@motajs/render-style": "workspace:*",
|
||||||
@ -18,8 +17,7 @@
|
|||||||
"@motajs/legacy-data": "workspace:*",
|
"@motajs/legacy-data": "workspace:*",
|
||||||
"@motajs/legacy-ui": "workspace:*",
|
"@motajs/legacy-ui": "workspace:*",
|
||||||
"@motajs/legacy-system": "workspace:*",
|
"@motajs/legacy-system": "workspace:*",
|
||||||
"@user/client-base": "workspace:*",
|
|
||||||
"@user/client-modules": "workspace:*",
|
"@user/client-modules": "workspace:*",
|
||||||
"@user/legacy-plugin-client": "workspace:*"
|
"@user/legacy-plugin-client": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,7 +5,6 @@ import * as LegacyClient from '@motajs/legacy-client';
|
|||||||
import * as LegacySystem from '@motajs/legacy-system';
|
import * as LegacySystem from '@motajs/legacy-system';
|
||||||
import * as LegacyUI from '@motajs/legacy-ui';
|
import * as LegacyUI from '@motajs/legacy-ui';
|
||||||
import * as Render from '@motajs/render';
|
import * as Render from '@motajs/render';
|
||||||
import * as RenderAssets from '@motajs/render-assets';
|
|
||||||
import * as RenderCore from '@motajs/render-core';
|
import * as RenderCore from '@motajs/render-core';
|
||||||
import * as RenderElements from '@motajs/render-elements';
|
import * as RenderElements from '@motajs/render-elements';
|
||||||
import * as RenderStyle from '@motajs/render-style';
|
import * as RenderStyle from '@motajs/render-style';
|
||||||
@ -13,7 +12,6 @@ import * as RenderVue from '@motajs/render-vue';
|
|||||||
import * as System from '@motajs/system';
|
import * as System from '@motajs/system';
|
||||||
import * as SystemAction from '@motajs/system-action';
|
import * as SystemAction from '@motajs/system-action';
|
||||||
import * as SystemUI from '@motajs/system-ui';
|
import * as SystemUI from '@motajs/system-ui';
|
||||||
import * as UserClientBase from '@user/client-base';
|
|
||||||
import * as ClientModules from '@user/client-modules';
|
import * as ClientModules from '@user/client-modules';
|
||||||
import * as LegacyPluginClient from '@user/legacy-plugin-client';
|
import * as LegacyPluginClient from '@user/legacy-plugin-client';
|
||||||
import * as MutateAnimate from 'mutate-animate';
|
import * as MutateAnimate from 'mutate-animate';
|
||||||
@ -30,7 +28,6 @@ export function create() {
|
|||||||
Mota.register('@motajs/legacy-system', LegacySystem);
|
Mota.register('@motajs/legacy-system', LegacySystem);
|
||||||
Mota.register('@motajs/legacy-ui', LegacyUI);
|
Mota.register('@motajs/legacy-ui', LegacyUI);
|
||||||
Mota.register('@motajs/render', Render);
|
Mota.register('@motajs/render', Render);
|
||||||
Mota.register('@motajs/render-assets', RenderAssets);
|
|
||||||
Mota.register('@motajs/render-core', RenderCore);
|
Mota.register('@motajs/render-core', RenderCore);
|
||||||
Mota.register('@motajs/render-elements', RenderElements);
|
Mota.register('@motajs/render-elements', RenderElements);
|
||||||
Mota.register('@motajs/render-style', RenderStyle);
|
Mota.register('@motajs/render-style', RenderStyle);
|
||||||
@ -38,7 +35,6 @@ export function create() {
|
|||||||
Mota.register('@motajs/system', System);
|
Mota.register('@motajs/system', System);
|
||||||
Mota.register('@motajs/system-action', SystemAction);
|
Mota.register('@motajs/system-action', SystemAction);
|
||||||
Mota.register('@motajs/system-ui', SystemUI);
|
Mota.register('@motajs/system-ui', SystemUI);
|
||||||
Mota.register('@user/client-base', UserClientBase);
|
|
||||||
Mota.register('@user/client-modules', ClientModules);
|
Mota.register('@user/client-modules', ClientModules);
|
||||||
Mota.register('@user/legacy-plugin-client', LegacyPluginClient);
|
Mota.register('@user/legacy-plugin-client', LegacyPluginClient);
|
||||||
Mota.register('MutateAnimate', MutateAnimate);
|
Mota.register('MutateAnimate', MutateAnimate);
|
||||||
@ -51,7 +47,6 @@ export function create() {
|
|||||||
async function createModule() {
|
async function createModule() {
|
||||||
LegacyUI.create();
|
LegacyUI.create();
|
||||||
ClientModules.create();
|
ClientModules.create();
|
||||||
UserClientBase.create();
|
|
||||||
|
|
||||||
await import('ant-design-vue/dist/antd.dark.css');
|
await import('ant-design-vue/dist/antd.dark.css');
|
||||||
main.renderLoaded = true;
|
main.renderLoaded = true;
|
||||||
|
|||||||
@ -106,9 +106,6 @@
|
|||||||
"72": "Frame count delivered to frame-based animater need to exactly divide texture's height.",
|
"72": "Frame count delivered to frame-based animater need to exactly divide texture's height.",
|
||||||
"73": "Consistent size is needed when using WebGL2 composer.",
|
"73": "Consistent size is needed when using WebGL2 composer.",
|
||||||
"74": "Frame size not match texture's size, incomplete data will be skipped.",
|
"74": "Frame size not match texture's size, incomplete data will be skipped.",
|
||||||
"75": "Material count splitted by grid does not match alias count, some material may have no alias or some alias may not map to a texture. Splitted: $1, alias: $2.",
|
|
||||||
"76": "Cannot pipe texture store when asset builder is started.",
|
|
||||||
"77": "Texture is clipped to an area of 0. Ensure that the texture contains your clip rect and clip rect's area is not zero.",
|
|
||||||
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
|
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
|
||||||
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
|
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,8 +51,7 @@ export class TextureGridComposer
|
|||||||
start: number,
|
start: number,
|
||||||
data: IGridComposerData,
|
data: IGridComposerData,
|
||||||
rows: number,
|
rows: number,
|
||||||
cols: number,
|
cols: number
|
||||||
index: number
|
|
||||||
): IndexMarkedComposedData {
|
): IndexMarkedComposedData {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
const ctx = canvas.getContext('2d')!;
|
const ctx = canvas.getContext('2d')!;
|
||||||
@ -81,7 +80,6 @@ export class TextureGridComposer
|
|||||||
|
|
||||||
const texture = new Texture(canvas);
|
const texture = new Texture(canvas);
|
||||||
const composed: ITextureComposedData = {
|
const composed: ITextureComposedData = {
|
||||||
index,
|
|
||||||
texture,
|
texture,
|
||||||
assetMap: map
|
assetMap: map
|
||||||
};
|
};
|
||||||
@ -98,14 +96,12 @@ export class TextureGridComposer
|
|||||||
const rows = Math.floor(this.maxWidth / data.width);
|
const rows = Math.floor(this.maxWidth / data.width);
|
||||||
const cols = Math.floor(this.maxHeight / data.height);
|
const cols = Math.floor(this.maxHeight / data.height);
|
||||||
|
|
||||||
let arrindex = 0;
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
while (arrindex < arr.length) {
|
while (i < arr.length) {
|
||||||
const res = this.nextAsset(arr, arrindex, data, rows, cols, i);
|
const { asset, index } = this.nextAsset(arr, i, data, rows, cols);
|
||||||
arrindex = res.index + 1;
|
i = index + 1;
|
||||||
i++;
|
yield asset;
|
||||||
yield res.asset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +149,6 @@ export class TextureMaxRectsComposer
|
|||||||
});
|
});
|
||||||
packer.addArray(rects);
|
packer.addArray(rects);
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
for (const bin of packer.bins) {
|
for (const bin of packer.bins) {
|
||||||
const map = new Map<ITexture, IRect>();
|
const map = new Map<ITexture, IRect>();
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement('canvas');
|
||||||
@ -171,7 +166,6 @@ export class TextureMaxRectsComposer
|
|||||||
});
|
});
|
||||||
const texture = new Texture(canvas);
|
const texture = new Texture(canvas);
|
||||||
const data: ITextureComposedData = {
|
const data: ITextureComposedData = {
|
||||||
index: index++,
|
|
||||||
texture,
|
texture,
|
||||||
assetMap: map
|
assetMap: map
|
||||||
};
|
};
|
||||||
@ -432,16 +426,15 @@ export class TextureMaxRectsWebGL2Composer
|
|||||||
const indexMap = this.mapTextures(arr);
|
const indexMap = this.mapTextures(arr);
|
||||||
this.setTexture(indexMap);
|
this.setTexture(indexMap);
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
for (const bin of packer.bins) {
|
for (const bin of packer.bins) {
|
||||||
const { texMap, attrib } = this.processRects(bin.rects, indexMap);
|
const { texMap, attrib } = this.processRects(bin.rects, indexMap);
|
||||||
this.renderAtlas(attrib);
|
this.renderAtlas(attrib);
|
||||||
const texture = new Texture(this.canvas);
|
const texture = new Texture(this.canvas);
|
||||||
const data: ITextureComposedData = {
|
const data: ITextureComposedData = {
|
||||||
index: index++,
|
|
||||||
texture,
|
texture,
|
||||||
assetMap: texMap
|
assetMap: texMap
|
||||||
};
|
};
|
||||||
|
|
||||||
yield data;
|
yield data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,9 +18,7 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
|
|||||||
readonly cols: number;
|
readonly cols: number;
|
||||||
|
|
||||||
private nowIndex: number = 0;
|
private nowIndex: number = 0;
|
||||||
private outputIndex: number = 0;
|
|
||||||
|
|
||||||
private nowTexture: ITexture;
|
|
||||||
private nowCanvas: HTMLCanvasElement;
|
private nowCanvas: HTMLCanvasElement;
|
||||||
private nowCtx: CanvasRenderingContext2D;
|
private nowCtx: CanvasRenderingContext2D;
|
||||||
private nowMap: Map<ITexture, Readonly<IRect>>;
|
private nowMap: Map<ITexture, Readonly<IRect>>;
|
||||||
@ -45,16 +43,12 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
|
|||||||
this.nowCanvas = document.createElement('canvas');
|
this.nowCanvas = document.createElement('canvas');
|
||||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
||||||
this.nowMap = new Map();
|
this.nowMap = new Map();
|
||||||
this.nowTexture = new Texture(this.nowCanvas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private nextCanvas() {
|
private nextCanvas() {
|
||||||
this.nowCanvas = document.createElement('canvas');
|
this.nowCanvas = document.createElement('canvas');
|
||||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
||||||
this.nowMap = new Map();
|
this.nowMap = new Map();
|
||||||
this.nowIndex = 0;
|
|
||||||
this.nowTexture = new Texture(this.nowCanvas);
|
|
||||||
this.outputIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> {
|
*add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> {
|
||||||
@ -72,14 +66,13 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
|
|||||||
this.nowCtx.drawImage(source, cx, cy, cw, ch, x, y, cw, ch);
|
this.nowCtx.drawImage(source, cx, cy, cw, ch, x, y, cw, ch);
|
||||||
this.nowMap.set(tex, { x, y, w: cw, h: ch });
|
this.nowMap.set(tex, { x, y, w: cw, h: ch });
|
||||||
|
|
||||||
const data: ITextureComposedData = {
|
index++;
|
||||||
index: this.outputIndex,
|
if (index === max) {
|
||||||
texture: this.nowTexture,
|
const data: ITextureComposedData = {
|
||||||
assetMap: this.nowMap
|
texture: new Texture(this.nowCanvas),
|
||||||
};
|
assetMap: this.nowMap
|
||||||
yield data;
|
};
|
||||||
|
yield data;
|
||||||
if (++index === max) {
|
|
||||||
this.nextCanvas();
|
this.nextCanvas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,13 +94,10 @@ export class TextureMaxRectsStreamComposer
|
|||||||
/** Max Rects 打包器 */
|
/** Max Rects 打包器 */
|
||||||
readonly packer: MaxRectsPacker<MaxRectsRectangle>;
|
readonly packer: MaxRectsPacker<MaxRectsRectangle>;
|
||||||
|
|
||||||
private outputIndex: number = 0;
|
|
||||||
private nowTexture: ITexture;
|
|
||||||
|
|
||||||
private nowCanvas: HTMLCanvasElement;
|
private nowCanvas: HTMLCanvasElement;
|
||||||
private nowCtx: CanvasRenderingContext2D;
|
private nowCtx: CanvasRenderingContext2D;
|
||||||
private nowMap: Map<ITexture, Readonly<IRect>>;
|
private nowMap: Map<ITexture, Readonly<IRect>>;
|
||||||
private nowBin: number;
|
private nowBins: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 Max Rects 算法执行贴图整合。输出的纹理的图像源将会是不同的画布。
|
* 使用 Max Rects 算法执行贴图整合。输出的纹理的图像源将会是不同的画布。
|
||||||
@ -132,16 +122,13 @@ export class TextureMaxRectsStreamComposer
|
|||||||
this.nowCanvas = document.createElement('canvas');
|
this.nowCanvas = document.createElement('canvas');
|
||||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
||||||
this.nowMap = new Map();
|
this.nowMap = new Map();
|
||||||
this.nowBin = 0;
|
this.nowBins = 0;
|
||||||
this.nowTexture = new Texture(this.nowCanvas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private nextCanvas() {
|
private nextCanvas() {
|
||||||
this.nowCanvas = document.createElement('canvas');
|
this.nowCanvas = document.createElement('canvas');
|
||||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
||||||
this.nowMap = new Map();
|
this.nowMap = new Map();
|
||||||
this.outputIndex++;
|
|
||||||
this.nowTexture = new Texture(this.nowCanvas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> {
|
*add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> {
|
||||||
@ -157,13 +144,12 @@ export class TextureMaxRectsStreamComposer
|
|||||||
const bins = this.packer.bins;
|
const bins = this.packer.bins;
|
||||||
if (bins.length === 0) return;
|
if (bins.length === 0) return;
|
||||||
const toYield: Bin<MaxRectsRectangle>[] = [bins[bins.length - 1]];
|
const toYield: Bin<MaxRectsRectangle>[] = [bins[bins.length - 1]];
|
||||||
if (bins.length > this.nowBin) {
|
if (bins.length > this.nowBins) {
|
||||||
toYield.push(...bins.slice(this.nowBin));
|
toYield.push(...bins.slice(this.nowBins));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = this.nowBin; i < bins.length; i++) {
|
for (const bin of toYield) {
|
||||||
const rects = bins[i].rects;
|
bin.rects.forEach(v => {
|
||||||
rects.forEach(v => {
|
|
||||||
if (this.nowMap.has(v.data)) return;
|
if (this.nowMap.has(v.data)) return;
|
||||||
const target: IRect = {
|
const target: IRect = {
|
||||||
x: v.x,
|
x: v.x,
|
||||||
@ -177,17 +163,14 @@ export class TextureMaxRectsStreamComposer
|
|||||||
this.nowCtx.drawImage(source, cx, cy, cw, ch, v.x, v.y, cw, ch);
|
this.nowCtx.drawImage(source, cx, cy, cw, ch, v.x, v.y, cw, ch);
|
||||||
});
|
});
|
||||||
const data: ITextureComposedData = {
|
const data: ITextureComposedData = {
|
||||||
index: this.outputIndex,
|
texture: new Texture(this.nowCanvas),
|
||||||
texture: this.nowTexture,
|
|
||||||
assetMap: this.nowMap
|
assetMap: this.nowMap
|
||||||
};
|
};
|
||||||
yield data;
|
yield data;
|
||||||
if (i < bins.length - 1) {
|
this.nextCanvas();
|
||||||
this.nextCanvas();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nowBin = bins.length;
|
this.nowBins = bins.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(): void {
|
close(): void {
|
||||||
|
|||||||
@ -53,12 +53,6 @@ export class Texture<T = unknown, A = unknown> implements ITexture<T, A> {
|
|||||||
const top = Math.max(0, y);
|
const top = Math.max(0, y);
|
||||||
const right = Math.min(this.width, r);
|
const right = Math.min(this.width, r);
|
||||||
const bottom = Math.min(this.height, b);
|
const bottom = Math.min(this.height, b);
|
||||||
const width = right - left;
|
|
||||||
const height = bottom - top;
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
logger.warn(77);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.cl = left;
|
this.cl = left;
|
||||||
this.ct = top;
|
this.ct = top;
|
||||||
this.width = right - left;
|
this.width = right - left;
|
||||||
|
|||||||
@ -22,8 +22,6 @@ export interface ITextureRenderable {
|
|||||||
export interface ITextureComposedData {
|
export interface ITextureComposedData {
|
||||||
/** 这个纹理图集的贴图对象 */
|
/** 这个纹理图集的贴图对象 */
|
||||||
readonly texture: ITexture;
|
readonly texture: ITexture;
|
||||||
/** 这个纹理图集的索引 */
|
|
||||||
readonly index: number;
|
|
||||||
/** 每个参与组合的贴图对应到图集对象的矩形范围 */
|
/** 每个参与组合的贴图对应到图集对象的矩形范围 */
|
||||||
readonly assetMap: Map<ITexture, Readonly<IRect>>;
|
readonly assetMap: Map<ITexture, Readonly<IRect>>;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user