fix: normalize exported texture filenames
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
import { extname } from 'path'
|
||||
import { compressTextureBuffer } from '@/lib/texture-compression'
|
||||
import { classifyAssetCategory } from '@/lib/asset-classification'
|
||||
import { normalizeTextureFilename } from '@/lib/asset-naming'
|
||||
import { TEXTURE_EXTENSIONS } from '@/lib/constants'
|
||||
import { getModelAssetPath } from '@/lib/model-paths'
|
||||
import type { ParsedFile, PreparedAssetSummary, PushFile } from '@/lib/types'
|
||||
|
||||
@@ -16,6 +19,65 @@ interface PrepareGitAssetsResult {
|
||||
compressionError?: string
|
||||
}
|
||||
|
||||
function getTextureFilenameMap(parsedFiles: ParsedFile[]) {
|
||||
const filenameMap = new Map<string, string>()
|
||||
const normalizedOwners = new Map<string, string>()
|
||||
|
||||
for (const file of parsedFiles) {
|
||||
const ext = extname(file.filename).toLowerCase()
|
||||
if (!TEXTURE_EXTENSIONS.has(ext)) continue
|
||||
|
||||
const normalizedFilename = normalizeTextureFilename(file.filename)
|
||||
if (!normalizedFilename) continue
|
||||
|
||||
const normalizedKey = normalizedFilename.toLowerCase()
|
||||
const existingOwner = normalizedOwners.get(normalizedKey)
|
||||
|
||||
if (existingOwner && existingOwner.toLowerCase() !== file.filename.toLowerCase()) {
|
||||
throw new Error(`Textures en conflit apres normalisation : ${existingOwner} et ${file.filename} deviennent ${normalizedFilename}`)
|
||||
}
|
||||
|
||||
filenameMap.set(file.filename.toLowerCase(), normalizedFilename)
|
||||
normalizedOwners.set(normalizedKey, file.filename)
|
||||
}
|
||||
|
||||
return filenameMap
|
||||
}
|
||||
|
||||
function getReferencedFilename(uri: string) {
|
||||
const cleanUri = decodeURIComponent(uri.split(/[?#]/)[0] || '')
|
||||
return cleanUri.split(/[\\/]/).pop()?.toLowerCase()
|
||||
}
|
||||
|
||||
function rewriteGltfUris(value: unknown, filenameMap: Map<string, string>): unknown {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((entry) => rewriteGltfUris(entry, filenameMap))
|
||||
}
|
||||
|
||||
if (!value || typeof value !== 'object') return value
|
||||
|
||||
const rewritten: Record<string, unknown> = {}
|
||||
|
||||
for (const [key, entry] of Object.entries(value)) {
|
||||
if (key === 'uri' && typeof entry === 'string') {
|
||||
const filename = getReferencedFilename(entry)
|
||||
rewritten[key] = filename ? filenameMap.get(filename) || entry : entry
|
||||
continue
|
||||
}
|
||||
|
||||
rewritten[key] = rewriteGltfUris(entry, filenameMap)
|
||||
}
|
||||
|
||||
return rewritten
|
||||
}
|
||||
|
||||
function prepareModelBuffer(buffer: Buffer, filenameMap: Map<string, string>) {
|
||||
if (filenameMap.size === 0) return buffer
|
||||
|
||||
const parsed: unknown = JSON.parse(buffer.toString('utf-8'))
|
||||
return Buffer.from(JSON.stringify(rewriteGltfUris(parsed, filenameMap), null, 2), 'utf-8')
|
||||
}
|
||||
|
||||
export async function prepareGitAssets({
|
||||
folderName,
|
||||
parsedFiles,
|
||||
@@ -25,22 +87,26 @@ export async function prepareGitAssets({
|
||||
let modelFilename = ''
|
||||
let compressed = false
|
||||
let compressionError: string | undefined
|
||||
const textureFilenameMap = getTextureFilenameMap(parsedFiles)
|
||||
|
||||
for (const pf of parsedFiles) {
|
||||
let content = pf.buffer
|
||||
let filename = pf.filename
|
||||
|
||||
if (pf.isModel) {
|
||||
content = prepareModelBuffer(pf.buffer, textureFilenameMap)
|
||||
modelFilename = pf.filename
|
||||
|
||||
assetSummaries.push({
|
||||
filename: pf.filename,
|
||||
filename,
|
||||
kind: 'model',
|
||||
compressed: false,
|
||||
})
|
||||
} else {
|
||||
const category = classifyAssetCategory(pf.filename)
|
||||
filename = textureFilenameMap.get(pf.filename.toLowerCase()) || pf.filename
|
||||
const category = classifyAssetCategory(filename)
|
||||
|
||||
const textureResult = await compressTextureBuffer(pf.filename, pf.buffer)
|
||||
const textureResult = await compressTextureBuffer(filename, pf.buffer)
|
||||
content = textureResult.buffer
|
||||
compressed ||= textureResult.compressed
|
||||
|
||||
@@ -49,7 +115,7 @@ export async function prepareGitAssets({
|
||||
}
|
||||
|
||||
assetSummaries.push({
|
||||
filename: pf.filename,
|
||||
filename,
|
||||
kind: category === 'assets' ? 'asset' : 'texture',
|
||||
category,
|
||||
compressed: textureResult.compressed,
|
||||
@@ -57,7 +123,7 @@ export async function prepareGitAssets({
|
||||
}
|
||||
|
||||
filesToPush.push({
|
||||
path: getModelAssetPath(folderName, pf.filename),
|
||||
path: getModelAssetPath(folderName, filename),
|
||||
contentBase64: content.toString('base64'),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user