diff --git a/packages/assetpack/src/image/mipmap.ts b/packages/assetpack/src/image/mipmap.ts index 2ef0cf52..83edd00f 100644 --- a/packages/assetpack/src/image/mipmap.ts +++ b/packages/assetpack/src/image/mipmap.ts @@ -22,7 +22,7 @@ const defaultMipmapOptions: Required = { fixedResolution: 'default', }; -export function mipmap(_options: MipmapOptions = {}): AssetPipe +export function mipmap(_options: MipmapOptions = {}): AssetPipe { const mipmap = resolveOptions(_options, defaultMipmapOptions); @@ -34,14 +34,15 @@ export function mipmap(_options: MipmapOptions = {}): AssetPipe +export function spineAtlasMipmap(_options?: SpineOptions): AssetPipe { return { folder: false, @@ -18,10 +18,11 @@ export function spineAtlasMipmap(_options?: SpineOptions): AssetPipe +export function texturePacker(_options: TexturePackerOptions = {}): AssetPipe { let shortcutClash: Record = {}; @@ -75,6 +75,7 @@ export function texturePacker(_options: TexturePackerOptions = {}): AssetPipe +): AssetPipe { return { folder: false, @@ -23,7 +23,7 @@ function signedFont( tags: { font: 'font', nc: 'nc', - fix: 'fix', + nomip: 'nomip', }, test(asset: Asset) { @@ -51,9 +51,9 @@ function signedFont( const newTextureAsset = createNewAssetAt(asset, newTextureName); - // don't compress! + // don't compress or mipmap the font texture, we can't resize or update image paths newTextureAsset.metaData[this.tags!.nc] = true; - newTextureAsset.metaData[this.tags!.fix] = true; + newTextureAsset.metaData[this.tags!.nomip] = true; newTextureAsset.metaData.mIgnore = true; assets.push(newTextureAsset); diff --git a/packages/assetpack/test/core/AssetWatcher.test.ts b/packages/assetpack/test/core/AssetWatcher.test.ts index 135e2fc3..19b1a49c 100644 --- a/packages/assetpack/test/core/AssetWatcher.test.ts +++ b/packages/assetpack/test/core/AssetWatcher.test.ts @@ -46,7 +46,7 @@ describe('AssetWatcher', () => it('should have correct file state with a cache', async () => { - const testName = 'asset-watcher'; + const testName = 'asset-watcher-file'; const inputDir = getInputDir(pkg, testName); createFolder( diff --git a/packages/assetpack/test/image/Mipmap.test.ts b/packages/assetpack/test/image/Mipmap.test.ts index 3b5de2e0..9f69cfb8 100644 --- a/packages/assetpack/test/image/Mipmap.test.ts +++ b/packages/assetpack/test/image/Mipmap.test.ts @@ -214,7 +214,45 @@ describe('Mipmap', () => entry: inputDir, cacheLocation: getCacheDir(pkg, testName), output: outputDir, cache: false, - pipes: [mipmap()] + pipes: [mipmap({ fixedResolution: 'low' })] + }); + + await assetpack.run(); + + expect(existsSync(`${outputDir}/assets/test.png`)).toBe(false); + expect(existsSync(`${outputDir}/assets/test@0.5x.png`)).toBe(true); + }); + + it('should prevent mipmaps', async () => + { + const testName = 'mip-nomip'; + const inputDir = getInputDir(pkg, testName); + const outputDir = getOutputDir(pkg, testName); + + createFolder( + pkg, + { + name: testName, + files: [], + folders: [ + { + name: 'assets{nomip}', + files: [ + { + name: 'test.png', + content: assetPath('image/png-1.png'), + }, + ], + folders: [], + }, + ], + }); + + const assetpack = new AssetPack({ + entry: inputDir, cacheLocation: getCacheDir(pkg, testName), + output: outputDir, + cache: false, + pipes: [mipmap({ fixedResolution: 'low' })] }); await assetpack.run(); diff --git a/packages/assetpack/test/spine/spineAtlasMipmap.test.ts b/packages/assetpack/test/spine/spineAtlasMipmap.test.ts index 548189bf..5f0967c8 100644 --- a/packages/assetpack/test/spine/spineAtlasMipmap.test.ts +++ b/packages/assetpack/test/spine/spineAtlasMipmap.test.ts @@ -171,9 +171,9 @@ describe('Atlas Mipmap', () => expect(existsSync(`${outputDir}/dragon2@0.5x.png`)).toBe(true); }); - it('should prevent mipmaps on file when tagged with fix', async () => + it('should resize atlas to fixed resolution when tagged with fix', async () => { - const testName = 'mip-fixed'; + const testName = 'mip-fixed-prevent'; const inputDir = getInputDir(pkg, testName); const outputDir = getOutputDir(pkg, testName); @@ -190,6 +190,14 @@ describe('Atlas Mipmap', () => name: 'dragon{spine}{fix}.atlas', content: assetPath('spine/dragon.atlas'), }, + { + name: 'dragon{fix}.png', + content: assetPath('spine/dragon.png'), + }, + { + name: 'dragon2{fix}.png', + content: assetPath('spine/dragon2.png'), + }, ], folders: [], }, @@ -210,5 +218,115 @@ describe('Atlas Mipmap', () => expect(existsSync(`${outputDir}/assets/dragon.atlas`)).toBe(true); expect(existsSync(`${outputDir}/assets/dragon@0.5x.atlas`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon@0.5x.png`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon2@0.5x.png`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon.png`)).toBe(true); + expect(existsSync(`${outputDir}/assets/dragon2.png`)).toBe(true); + }); + + it('should resize atlas to low fixed resolution when tagged with fix', async () => + { + const testName = 'mip-fixed-res'; + const inputDir = getInputDir(pkg, testName); + const outputDir = getOutputDir(pkg, testName); + + createFolder( + pkg, + { + name: testName, + files: [], + folders: [ + { + name: 'assets', + files: [ + { + name: 'dragon{spine}{fix}.atlas', + content: assetPath('spine/dragon.atlas'), + }, + { + name: 'dragon{fix}.png', + content: assetPath('spine/dragon.png'), + }, + { + name: 'dragon2{fix}.png', + content: assetPath('spine/dragon2.png'), + }, + ], + folders: [], + }, + ], + }); + + const assetpack = new AssetPack({ + entry: inputDir, cacheLocation: getCacheDir(pkg, testName), + output: outputDir, + cache: false, + pipes: [ + mipmap({ fixedResolution: 'low' }), + spineAtlasMipmap({ fixedResolution: 'low' }), + ] + }); + + await assetpack.run(); + + expect(existsSync(`${outputDir}/assets/dragon.atlas`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon@0.5x.atlas`)).toBe(true); + expect(existsSync(`${outputDir}/assets/dragon@0.5x.png`)).toBe(true); + expect(existsSync(`${outputDir}/assets/dragon2@0.5x.png`)).toBe(true); + expect(existsSync(`${outputDir}/assets/dragon.png`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon2.png`)).toBe(false); + }); + + it('should create no mipmaps', async () => + { + const testName = 'mip-nomip'; + const inputDir = getInputDir(pkg, testName); + const outputDir = getOutputDir(pkg, testName); + + createFolder( + pkg, + { + name: testName, + files: [], + folders: [ + { + name: 'assets', + files: [ + { + name: 'dragon{spine}{nomip}.atlas', + content: assetPath('spine/dragon.atlas'), + }, + { + name: 'dragon{nomip}.png', + content: assetPath('spine/dragon.png'), + }, + { + name: 'dragon2{nomip}.png', + content: assetPath('spine/dragon2.png'), + }, + ], + folders: [], + }, + ], + }); + + const assetpack = new AssetPack({ + entry: inputDir, cacheLocation: getCacheDir(pkg, testName), + output: outputDir, + cache: false, + pipes: [ + mipmap({ fixedResolution: 'low' }), + spineAtlasMipmap({ fixedResolution: 'low' }), + ] + }); + + await assetpack.run(); + + expect(existsSync(`${outputDir}/assets/dragon.atlas`)).toBe(true); + expect(existsSync(`${outputDir}/assets/dragon@0.5x.atlas`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon@0.5x.png`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon2@0.5x.png`)).toBe(false); + expect(existsSync(`${outputDir}/assets/dragon.png`)).toBe(true); + expect(existsSync(`${outputDir}/assets/dragon2.png`)).toBe(true); }); }); diff --git a/packages/assetpack/test/texture-packer/texturePacker.test.ts b/packages/assetpack/test/texture-packer/texturePacker.test.ts index cfabf738..b87c54cd 100644 --- a/packages/assetpack/test/texture-packer/texturePacker.test.ts +++ b/packages/assetpack/test/texture-packer/texturePacker.test.ts @@ -323,7 +323,7 @@ describe('Texture Packer', () => expect(sheetJson.meta.size).toEqual(expectedSize); }); - it('should not create mip spritesheets', async () => + it('should resize spritesheet to fixed resolution', async () => { const testName = 'tp-fix'; const inputDir = getInputDir(pkg, testName); @@ -364,7 +364,7 @@ describe('Texture Packer', () => output: outputDir, cache: false, pipes: [ - texturePacker() + texturePacker({ resolutionOptions: { fixedResolution: 'low' } }), ] }); @@ -373,10 +373,78 @@ describe('Texture Packer', () => const sheet1 = existsSync(`${outputDir}/sprites/sprites.json`); const sheet2 = existsSync(`${outputDir}/sprites/sprites@0.5x.json`); const sheet3 = existsSync(`${outputDir}/sprites/sprites@2x.json`); + const img = existsSync(`${outputDir}/sprites/sprites.png`); + const img2 = existsSync(`${outputDir}/sprites/sprites@0.5x.png`); + const img3 = existsSync(`${outputDir}/sprites/sprites@2x.png`); + + expect(sheet1).toBe(false); + expect(sheet2).toBe(true); + expect(sheet3).toBe(false); + expect(img).toBe(false); + expect(img2).toBe(true); + expect(img3).toBe(false); + }); + + it('should not create any mipmaps for the spritesheet', async () => + { + const testName = 'tp-nomip'; + const inputDir = getInputDir(pkg, testName); + const outputDir = getOutputDir(pkg, testName); + + const sprites: File[] = []; + + for (let i = 0; i < 10; i++) + { + sprites.push({ + name: `sprite${i}.png`, + content: assetPath(`image/sp-${i + 1}.png`), + }); + } + + createFolder( + pkg, + { + name: testName, + files: [], + folders: [ + { + name: 'sprites{nomip}', + files: [], + folders: [ + { + name: 'sprites{tps}', + files: sprites, + folders: [], + }, + ], + }, + ], + }); + + const assetpack = new AssetPack({ + entry: inputDir, cacheLocation: getCacheDir(pkg, testName), + output: outputDir, + cache: false, + pipes: [ + texturePacker({ resolutionOptions: { fixedResolution: 'low' } }), + ] + }); + + await assetpack.run(); + + const sheet1 = existsSync(`${outputDir}/sprites/sprites.json`); + const sheet2 = existsSync(`${outputDir}/sprites/sprites@0.5x.json`); + const sheet3 = existsSync(`${outputDir}/sprites/sprites@2x.json`); + const img = existsSync(`${outputDir}/sprites/sprites.png`); + const img2 = existsSync(`${outputDir}/sprites/sprites@0.5x.png`); + const img3 = existsSync(`${outputDir}/sprites/sprites@2x.png`); expect(sheet1).toBe(true); expect(sheet2).toBe(false); expect(sheet3).toBe(false); + expect(img).toBe(true); + expect(img2).toBe(false); + expect(img3).toBe(false); }); it('should create jpg spritesheets', async () => diff --git a/packages/assetpack/test/webfont/Webfont.test.ts b/packages/assetpack/test/webfont/Webfont.test.ts index 856654b8..1c28cd96 100644 --- a/packages/assetpack/test/webfont/Webfont.test.ts +++ b/packages/assetpack/test/webfont/Webfont.test.ts @@ -189,6 +189,46 @@ describe('Webfont', () => expect(existsSync(`${outputDir}/sdf.png`)).toBe(true); }); + it('should generate a sdf font from ttf file at 1 resolution', async () => + { + const testName = 'sdf-resolution'; + const inputDir = getInputDir(pkg, testName); + const outputDir = getOutputDir(pkg, testName); + + createFolder( + pkg, + { + name: testName, + files: [ + { + name: 'sdf{sdf}.ttf', + content: assetPath('font/Roboto-Regular.ttf'), + }, + ], + folders: [], + } + ); + + const assetpack = new AssetPack({ + entry: inputDir, cacheLocation: getCacheDir(pkg, testName), + output: outputDir, + cache: false, + pipes: [ + sdfFont(), + mipmap({ + fixedResolution: 'high', + resolutions: { high: 2, default: 1 }, + }) + ] + }); + + await assetpack.run(); + + // expect webfont file to be generated + expect(existsSync(`${outputDir}/sdf.fnt`)).toBe(true); + expect(existsSync(`${outputDir}/sdf.png`)).toBe(true); + }); + it('should generate a split sdf font from ttf file', async () => { const testName = 'sdf-split'; diff --git a/packages/docs/docs/guide/pipes/mipmap.mdx b/packages/docs/docs/guide/pipes/mipmap.mdx index e59dd074..8d084355 100644 --- a/packages/docs/docs/guide/pipes/mipmap.mdx +++ b/packages/docs/docs/guide/pipes/mipmap.mdx @@ -61,9 +61,10 @@ export default { ## Tags -| Tag | Folder/File | Description | -| ----- | ----------- | -------------------------------------------------------------------------------------- | -| `fix` | `both` | If present the `fixedResolution` will be used. No other resolutions will be generated. | +| Tag | Folder/File | Description | +| ------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `fix` | `both` | If present the `fixedResolution` will be used. No other resolutions will be generated. Note that the image will be resized to the resolution specified in `fixedResolution`. If you don't want the image to be resized please use the `nomip` tag. | +| `nomip` | `both` | If present mipmaps will not be generated. | ### Example: fixed resolution diff --git a/packages/docs/docs/guide/pipes/spine.mdx b/packages/docs/docs/guide/pipes/spine.mdx index c22f27e2..a3f13034 100644 --- a/packages/docs/docs/guide/pipes/spine.mdx +++ b/packages/docs/docs/guide/pipes/spine.mdx @@ -97,9 +97,10 @@ export default { ### Tags -| Tag | Folder/File | Description | -| ----- | ------ | -------------------------------------------------------------------------------------- | -| `fix` | `both` | If present the `fixedResolution` will be used. No other resolutions will be generated. | +| Tag | Folder/File | Description | +| ------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `fix` | `both` | If present the `fixedResolution` will be used. No other resolutions will be generated. Note that the image will be resized to the resolution specified in `fixedResolution`. If you don't want the image to be resized please use the `nomip` tag. | +| `nomip` | `both` | If present mipmaps will not be generated. | --- diff --git a/packages/docs/docs/guide/pipes/texture-packer.mdx b/packages/docs/docs/guide/pipes/texture-packer.mdx index 7913a5d1..91708105 100644 --- a/packages/docs/docs/guide/pipes/texture-packer.mdx +++ b/packages/docs/docs/guide/pipes/texture-packer.mdx @@ -68,15 +68,16 @@ export default { | resolutionOptions.fixedResolution | `string` | A resolution used if the fix tag is applied. Resolution must match one found in resolutions.
Defaults to `default`. | | resolutionOptions.maximumTextureSize | `number` | The maximum size a sprite sheet can be before its split out.
Defaults to `4096`. | | | | | -| addFrameNames | `boolean` | Whether to add frame names to the data in the manifest
Defaults to `false`. | +| addFrameNames | `boolean` | Whether to add frame names to the data in the manifest
Defaults to `false`. | ## Tags -| Tag | Folder/File | Description | -| ----- | ----------- | ------------------------------------------------------------------ | -| `tps` | `folder` | If present the folder will be processed by Texture Packer. | -| `jpg` | `folder` | If present the spritesheet will be saved as a jpg. | -| `fix` | `folder` | If present the spritesheet will be fixed to a specific resolution. | +| Tag | Folder/File | Description | +| ------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `tps` | `folder` | If present the folder will be processed by Texture Packer. | +| `jpg` | `folder` | If present the spritesheet will be saved as a jpg. | +| `fix` | `both` | If present the `fixedResolution` will be used. No other resolutions will be generated. Note that the image will be resized to the resolution specified in `fixedResolution`. If you don't want the image to be resized please use the `nomip` tag. | +| `nomip` | `both` | If present mipmaps will not be generated. | ---