fix: normalize exported texture filenames

This commit is contained in:
Tom Boullay
2026-04-28 15:51:15 +02:00
parent 497b0853c5
commit 41e04002b8
9 changed files with 188 additions and 16 deletions
+77 -1
View File
@@ -6,6 +6,8 @@ export const ASSET_FAMILIES = [
'metalness',
'height',
'opacity',
'orm',
'ao',
] as const
export type AssetFamily = typeof ASSET_FAMILIES[number]
@@ -21,6 +23,23 @@ const FORBIDDEN_ASSET_FAMILY_ALIASES: ReadonlyMap<string, AssetFamily> = new Map
['occlusion_roughness_metallic', 'roughness'],
])
const EXPORTED_SUFFIX_ALIASES: Array<{ suffix: string; family: AssetFamily }> = [
{ suffix: 'occlusionroughnessmetallic', family: 'orm' },
{ suffix: 'occlusion_roughness_metallic', family: 'orm' },
{ suffix: 'normal_opengl', family: 'normal' },
{ suffix: 'normalopengl', family: 'normal' },
{ suffix: 'base_color', family: 'color' },
{ suffix: 'basecolor', family: 'color' },
{ suffix: 'mixed_ao', family: 'ao' },
{ suffix: 'metallic', family: 'metalness' },
{ suffix: 'roughness', family: 'roughness' },
{ suffix: 'normal', family: 'normal' },
{ suffix: 'height', family: 'height' },
{ suffix: 'opacity', family: 'opacity' },
{ suffix: 'diffuse', family: 'diffuse' },
{ suffix: 'color', family: 'color' },
]
export function getAssetFamily(value: string): AssetFamily | undefined {
return ASSET_FAMILY_BY_KEY.get(value.toLowerCase())
}
@@ -33,11 +52,68 @@ function getFileStem(filename: string) {
return filename.replace(/\.[^.]+$/, '')
}
function getFileExtension(filename: string) {
return filename.split('.').pop()?.toLowerCase() || ''
}
function normalizeTargetName(target: string) {
return target
.trim()
.replace(/[\s-]+/g, '_')
.replace(/_+/g, '_')
.replace(/^_+|_+$/g, '')
}
function buildTextureFilename(family: AssetFamily, target: string, extension: string) {
const normalizedTarget = normalizeTargetName(target)
return `${family}${normalizedTarget ? `_${normalizedTarget}` : ''}.${extension}`
}
function getExportedTextureAlias(stem: string) {
const lowerStem = stem.toLowerCase()
for (const alias of EXPORTED_SUFFIX_ALIASES) {
const lowerSuffix = alias.suffix.toLowerCase()
if (lowerStem === lowerSuffix) {
return { family: alias.family, target: '' }
}
if (lowerStem.endsWith(`_${lowerSuffix}`)) {
return {
family: alias.family,
target: stem.slice(0, -lowerSuffix.length - 1),
}
}
}
return null
}
export function normalizeTextureFilename(filename: string) {
const stem = getFileStem(filename)
const extension = getFileExtension(filename)
const [prefix, ...targetParts] = stem.split('_')
const family = getAssetFamily(prefix)
if (family) {
return buildTextureFilename(family, targetParts.join('_'), extension)
}
const exportedAlias = getExportedTextureAlias(stem)
if (exportedAlias) {
return buildTextureFilename(exportedAlias.family, exportedAlias.target, extension)
}
return null
}
export function getTextureNamingError(filename: string) {
const stem = getFileStem(filename)
const [prefix, ...targetParts] = stem.split('_')
const family = getAssetFamily(prefix)
const extension = filename.split('.').pop()
const extension = getFileExtension(filename)
if (normalizeTextureFilename(filename)) return null
if (family && targetParts.every(Boolean)) return null