refactor: removed fallback image processing and updated portrait image processing

This commit is contained in:
Haoyu Xu
2025-11-16 17:05:28 +08:00
parent ea0bd20211
commit 2a99186867
13 changed files with 138 additions and 346 deletions

View File

@@ -162,7 +162,6 @@ const generateMapping = () => {
type === 'skin'
? skinEntry.skinId.replace(/@/, '_')
: `${skinEntry.charId}_2`
operator.fallback_name = `${operator.portrait_filename}${operator.isSP ? '_sp' : ''}`
const regions = Object.keys(
operator.codename

View File

@@ -1,12 +1,11 @@
import path from 'node:path'
import config from '@aklive2d/config'
import { alphaComposite, file } from '@aklive2d/libs'
import { file } from '@aklive2d/libs'
import operators, {
DIST_DIR,
generateAssetsJson,
OPERATOR_SOURCE_FOLDER,
} from '../index.ts'
import type { PortraitHub, PortraitJson } from '../types.ts'
import { getDistFolder, getExtractedFolder } from './utils.ts'
export const build = async (namesToBuild: string[]) => {
@@ -39,75 +38,10 @@ const generateAssets = async (name: string) => {
file.rmdir(outDir)
file.mkdir(outDir)
const fallback_name = operators[name].fallback_name
const fallbackFilename = `${fallback_name}.png`
const alphaCompositeFilename = `${path.parse(fallbackFilename).name}[alpha].png`
if (file.exists(path.join(extractedDir, alphaCompositeFilename))) {
const fallbackBuffer = await alphaComposite.process(
fallbackFilename,
alphaCompositeFilename,
extractedDir
)
file.writeSync(
fallbackBuffer,
path.join(getDistFolder(name), fallbackFilename)
)
} else {
await file.copy(
path.join(extractedDir, fallbackFilename),
path.join(getDistFolder(name), fallbackFilename)
)
}
// generate portrait
const portraitDir = path.join(
OPERATOR_SOURCE_FOLDER,
config.module.operator.portraits
)
const portraitHubContent = file.readSync(
path.join(
portraitDir,
config.module.operator.MonoBehaviour,
'portrait_hub.json'
)
) as string
if (!portraitHubContent) throw new Error('portrait_hub.json not found')
const portraitHub: PortraitHub = JSON.parse(portraitHubContent)
const portrait_filename_lowerCase =
operators[name].portrait_filename.toLowerCase()
const portraitItem = portraitHub._sprites.find(
(item) => item.name.toLowerCase() === portrait_filename_lowerCase
)
if (!portraitItem) throw new Error(`portrait ${fallback_name} not found`)
const portraitAtlas = portraitItem.atlas
const portraitJsonText = file.readSync(
path.join(
portraitDir,
config.module.operator.MonoBehaviour,
`portraits#${portraitAtlas}.json`
)
) as string
if (!portraitJsonText)
throw new Error(`portrait ${fallback_name} json not found`)
const portraitJson: PortraitJson = JSON.parse(portraitJsonText)
const item = portraitJson._sprites.find(
(item) => item.name.toLowerCase() === portrait_filename_lowerCase
)
if (!item) throw new Error(`portrait ${fallback_name} not found`)
const rect = {
...item.rect,
rotate: item.rotate,
}
const protraitFilename = `portraits#${portraitAtlas}.png`
const portraitBuffer = await alphaComposite.process(
protraitFilename,
`${path.parse(protraitFilename).name}a.png`,
path.join(portraitDir, config.module.operator.Texture2D)
)
const croppedBuffer = await alphaComposite.crop(portraitBuffer, rect)
file.writeSync(
croppedBuffer,
path.join(getDistFolder(name), `${fallback_name}_portrait.png`)
const portraitFilename = `${operators[name].portrait_filename}.png`
await file.copy(
path.join(extractedDir, portraitFilename),
path.join(getDistFolder(name), portraitFilename)
)
await generateAssetsJson(

View File

@@ -5,7 +5,6 @@ export type OperatorEntryType = 'operator' | 'skin'
export interface OperatorConfig {
filename: string
logo: string
fallback_name: string
portrait_filename: string
viewport_left: number // should be default to 0 in the future
viewport_right: number
@@ -29,69 +28,6 @@ export type Config = {
[name: string]: OperatorConfig
}
type FileIDPathID = {
m_FileID: number
m_PathID: number
}
export type PortraitHub = {
m_GameObject: FileIDPathID
m_Enabled: number
m_Script: FileIDPathID
m_Name: string
_sprites: {
name: string
atlas: number
}[]
_atlases: string[]
_inputSpriteDir: string
_outputAtlasDir: string
_rootAtlasName: string
_spriteSize: {
width: number
height: number
}
_cntPerAtlas: number
_maxAtlasSize: number
}
type SignedItem = {
name: string
guid: string
md5: string
}
export type PortraitJson = {
m_GameObject: FileIDPathID
m_Enabled: number
m_Script: FileIDPathID
m_Name: string
_sprites: {
name: string
guid: string
atlas: number
rect: {
x: number
y: number
w: number
h: number
}
rotate: number
}[]
_atlas: {
index: number
texture: FileIDPathID
alpha: FileIDPathID
size: number
}
_index: number
_sign: {
m_sprites: SignedItem[]
m_atlases: SignedItem[]
m_alphas: SignedItem[]
}
}
export type AssetsJson = {
filename: string
path?: string