Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions packages/assetpack/src/texture-packer/packer/createJsons.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,24 @@
import { path } from '../../core/index.js';
import { createName } from './createTextures.js';
import { detectAnimations } from './detectAnimations.js';
import { fitTextureToPacker } from './fitTextureToPacker.js';

import type { PixiPacker } from './packTextures.js';
import type { PackTexturesOptions, PixiPacker } from './packTextures.js';

function convertName(pth: string, nameStyle: 'short' | 'relative', removeFileExtension = false) {
const name = nameStyle === 'short' ? path.basename(pth) : pth;

return removeFileExtension ? path.trimExt(name) : name;
}

export function createJsons(
packer: PixiPacker,
width: number,
height: number,
options: {
textureName: string;
resolution: number;
textureFormat: 'png' | 'jpg';
nameStyle: 'short' | 'relative';
removeFileExtension: boolean;
autodetectAnimations?: boolean;
},
) {
export function createJsons(packer: PixiPacker, options: Required<PackTexturesOptions>) {
const bins = packer.bins;

const jsons = [];

for (let i = 0; i < bins.length; i++) {
const bin = bins[i];
const { width, height } = fitTextureToPacker(bin, options);

const json: any = {
frames: {},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import sharp from 'sharp';
import { fitTextureToPacker } from './fitTextureToPacker.js';

import type { PackTexturesOptions, PixiPacker } from './packTextures.js';

export async function createTextures(
packer: PixiPacker,
width: number,
height: number,
options: Required<PackTexturesOptions>,
) {
export async function createTextures(packer: PixiPacker, options: Required<PackTexturesOptions>) {
const texturePromises: Promise<{ name: string; buffer: Buffer }>[] = [];

const bins = packer.bins;

for (let i = 0; i < bins.length; i++) {
const bin = bins[i];
const { width, height } = fitTextureToPacker(bin, options);

const compositeOptions = [];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { PackTexturesOptions, PixiPacker } from './packTextures.js';
import type { PackTexturesOptions, PixiRectData } from './packTextures.js';

export function fitTextureToPacker(
bin: PixiPacker,
bin: { rects: PixiRectData[] },
{ width, height, fixedSize, padding, powerOfTwo }: PackTexturesOptions,
) {
if (!fixedSize) {
Expand Down
7 changes: 2 additions & 5 deletions packages/assetpack/src/texture-packer/packer/packTextures.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createJsons } from './createJsons.js';
import { createTextureData } from './createTextureData.js';
import { createTextures } from './createTextures.js';
import { fitTextureToPacker } from './fitTextureToPacker.js';

import type { MaxRectsPacker, Rectangle } from 'maxrects-packer';
import type { SharpProcessingOptions } from '../../image/types.js';
Expand Down Expand Up @@ -80,12 +79,10 @@ export async function packTextures(_options: PackTexturesOptions): Promise<PackT
// which now contains all the info we need to create the textures and jsons
const packer = await createTextureData(options);

const { width, height } = fitTextureToPacker(packer, options);

return {
// combine the textures into one big one with all the info we have
textures: await createTextures(packer, width, height, options),
textures: await createTextures(packer, options),
// create the jsons for the textures
jsons: createJsons(packer, width, height, options),
jsons: createJsons(packer, options),
};
}
32 changes: 16 additions & 16 deletions packages/assetpack/test/manifest/Manifest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,12 +417,12 @@ describe('Manifest', () => {
{
alias: ['bundle/tps'],
src: [
{ src: 'bundle/tps-0@0.5x.webp.json', progressSize: 19.49 },
{ src: 'bundle/tps-0@0.5x.png.json', progressSize: 21.34 },
{ src: 'bundle/tps-0@0.5x.astc.json', progressSize: 26.57 },
{ src: 'bundle/tps-0.webp.json', progressSize: 45.18 },
{ src: 'bundle/tps-0.png.json', progressSize: 71.06 },
{ src: 'bundle/tps-0.astc.json', progressSize: 90.86 },
{ src: 'bundle/tps-0@0.5x.webp.json', progressSize: 19.47 },
{ src: 'bundle/tps-0@0.5x.png.json', progressSize: 21.69 },
{ src: 'bundle/tps-0@0.5x.astc.json', progressSize: 26.53 },
{ src: 'bundle/tps-0.webp.json', progressSize: 45.35 },
{ src: 'bundle/tps-0.png.json', progressSize: 69.82 },
{ src: 'bundle/tps-0.astc.json', progressSize: 90.8 },
],
data: {
tags: {
Expand Down Expand Up @@ -644,12 +644,12 @@ describe('Manifest', () => {
{
alias: ['bundle/tps'],
src: [
{ src: 'bundle/tps-RzSARA-0@0.5x.astc.json', progressSize: 26.52 },
{ src: 'bundle/tps-Ktro9A-0@0.5x.png.json', progressSize: 21.3 },
{ src: 'bundle/tps-iS-Jog-0@0.5x.webp.json', progressSize: 19.45 },
{ src: 'bundle/tps-G92JcQ-0.png.json', progressSize: 71.01 },
{ src: 'bundle/tps-g4NIDQ-0.astc.json', progressSize: 90.82 },
{ src: 'bundle/tps-bo4nog-0.webp.json', progressSize: 45.14 },
{ src: 'bundle/tps-ZOgqew-0@0.5x.webp.json', progressSize: 19.43 },
{ src: 'bundle/tps-w5hVsQ-0.astc.json', progressSize: 90.76 },
{ src: 'bundle/tps-TtXNnQ-0@0.5x.astc.json', progressSize: 26.49 },
{ src: 'bundle/tps-NBceYA-0.webp.json', progressSize: 45.31 },
{ src: 'bundle/tps-LHA0PQ-0.png.json', progressSize: 69.77 },
{ src: 'bundle/tps--FWNAg-0@0.5x.png.json', progressSize: 21.65 },
],
data: {
tags: {
Expand Down Expand Up @@ -1968,10 +1968,10 @@ describe('Manifest', () => {
{
alias: ['bundle/tps'],
src: [
{ src: 'bundle/tps-RzSARA-0@0.5x.astc.json', progressSize: 26.52 },
{ src: 'bundle/tps-iS-Jog-0@0.5x.webp.json', progressSize: 19.45 },
{ src: 'bundle/tps-g4NIDQ-0.astc.json', progressSize: 90.82 },
{ src: 'bundle/tps-bo4nog-0.webp.json', progressSize: 45.14 },
{ src: 'bundle/tps-ZOgqew-0@0.5x.webp.json', progressSize: 19.43 },
{ src: 'bundle/tps-w5hVsQ-0.astc.json', progressSize: 90.76 },
{ src: 'bundle/tps-TtXNnQ-0@0.5x.astc.json', progressSize: 26.49 },
{ src: 'bundle/tps-NBceYA-0.webp.json', progressSize: 45.31 },
],
data: {
tags: {
Expand Down
68 changes: 68 additions & 0 deletions packages/assetpack/test/texture-packer/texturePacker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -754,4 +754,72 @@ describe('Texture Packer', () => {
},
});
});

it('should compute per-bin dimensions in multi-pack mode', async () => {
const testName = 'tp-multipack-per-bin';
const inputDir = getInputDir(pkg, testName);
const outputDir = getOutputDir(pkg, testName);

// 10 untrimmed 256x256 sprites into a 1024 max: 9 fit in the first
// bin, 1 overflows into a second smaller bin.
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{tps}',
files: sprites,
folders: [],
},
],
});

const assetpack = new AssetPack({
entry: inputDir,
cacheLocation: getCacheDir(pkg, testName),
output: outputDir,
cache: false,
pipes: [
texturePacker({
resolutionOptions: {
resolutions: { default: 1 },
maximumTextureSize: 1024,
},
texturePacker: {
allowTrim: false,
},
}),
],
});

await assetpack.run();

expect(existsSync(`${outputDir}/sprites-0.json`)).toBe(true);
expect(existsSync(`${outputDir}/sprites-1.json`)).toBe(true);
expect(existsSync(`${outputDir}/sprites-2.json`)).toBe(false);

const sheet0 = fs.readJSONSync(`${outputDir}/sprites-0.json`);
const sheet1 = fs.readJSONSync(`${outputDir}/sprites-1.json`);

const meta0 = await sharp(`${outputDir}/sprites-0.png`).metadata();
const meta1 = await sharp(`${outputDir}/sprites-1.png`).metadata();

// Each sheet's actual texture dimensions must match its JSON metadata
expect(meta0.width).toEqual(sheet0.meta.size.w);
expect(meta0.height).toEqual(sheet0.meta.size.h);
expect(meta1.width).toEqual(sheet1.meta.size.w);
expect(meta1.height).toEqual(sheet1.meta.size.h);

// The last bin has fewer sprites so its texture should be smaller
expect(sheet1.meta.size.w * sheet1.meta.size.h).toBeLessThan(sheet0.meta.size.w * sheet0.meta.size.h);
});
});
Loading