Initial commit
This commit is contained in:
149
scripts/model-pipeline.js
Normal file
149
scripts/model-pipeline.js
Normal file
@ -0,0 +1,149 @@
|
||||
import { execSync } from 'node:child_process'
|
||||
import { readdirSync, copyFileSync, unlinkSync, mkdirSync, existsSync } from 'node:fs'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { exit } from 'node:process'
|
||||
|
||||
/**
|
||||
* This script is used to transform gltf and glb files into Threlte components.
|
||||
* It uses the `@threlte/gltf` package to do so.
|
||||
* It works in two steps:
|
||||
* 1. Transform the gltf/glb files located in the sourceDir directory
|
||||
* 2. Move the Threlte components to the targetDir directory
|
||||
*/
|
||||
const configuration = {
|
||||
sourceDir: resolve(join('static', 'models')),
|
||||
targetDir: resolve(join('src', 'lib', 'components', 'models')),
|
||||
overwrite: false,
|
||||
root: '/models/',
|
||||
types: true,
|
||||
keepnames: false,
|
||||
meta: false,
|
||||
shadows: false,
|
||||
printwidth: 120,
|
||||
precision: 2,
|
||||
draco: null,
|
||||
preload: false,
|
||||
suspense: false,
|
||||
isolated: false,
|
||||
transform: {
|
||||
enabled: false,
|
||||
resolution: 1024,
|
||||
simplify: {
|
||||
enabled: false,
|
||||
weld: 0.0001,
|
||||
ratio: 0.75,
|
||||
error: 0.001
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if the target directory doesn't exist, create it
|
||||
mkdirSync(configuration.targetDir, { recursive: true })
|
||||
|
||||
// throw error if source directory doesn't exist
|
||||
if (!existsSync(configuration.sourceDir)) {
|
||||
throw new Error(`Source directory ${configuration.sourceDir} doesn't exist.`)
|
||||
}
|
||||
|
||||
// read the directory, filter for .glb and .gltf files and files *not* ending
|
||||
// with -transformed.gltf or -transformed.glb as these should not be transformed
|
||||
// again.
|
||||
const gltfFiles = readdirSync(configuration.sourceDir).filter((file) => {
|
||||
return (
|
||||
(file.endsWith('.glb') || file.endsWith('.gltf')) &&
|
||||
!file.endsWith('-transformed.gltf') &&
|
||||
!file.endsWith('-transformed.glb')
|
||||
)
|
||||
})
|
||||
|
||||
if (gltfFiles.length === 0) {
|
||||
console.log('No gltf or glb files found.')
|
||||
exit()
|
||||
}
|
||||
|
||||
const filteredGltfFiles = gltfFiles.filter((file) => {
|
||||
if (!configuration.overwrite) {
|
||||
const componentFilename = file.split('.').slice(0, -1).join('.') + '.svelte'
|
||||
const componentPath = join(configuration.targetDir, componentFilename)
|
||||
if (existsSync(componentPath)) {
|
||||
console.error(`File ${componentPath} already exists, skipping.`)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if (filteredGltfFiles.length === 0) {
|
||||
console.log('No gltf or glb files to process.')
|
||||
exit()
|
||||
}
|
||||
|
||||
filteredGltfFiles.forEach((file) => {
|
||||
// run the gltf transform command on every file
|
||||
const path = join(configuration.sourceDir, file)
|
||||
|
||||
// parse the configuration
|
||||
const args = []
|
||||
if (configuration.root) args.push(`--root ${configuration.root}`)
|
||||
if (configuration.types) args.push('--types')
|
||||
if (configuration.keepnames) args.push('--keepnames')
|
||||
if (configuration.meta) args.push('--meta')
|
||||
if (configuration.shadows) args.push('--shadows')
|
||||
args.push(`--printwidth ${configuration.printwidth}`)
|
||||
args.push(`--precision ${configuration.precision}`)
|
||||
if (configuration.draco) args.push(`--draco ${configuration.draco}`)
|
||||
if (configuration.preload) args.push('--preload')
|
||||
if (configuration.suspense) args.push('--suspense')
|
||||
if (configuration.isolated) args.push('--isolated')
|
||||
if (configuration.transform.enabled) {
|
||||
args.push(`--transform`)
|
||||
args.push(`--resolution ${configuration.transform.resolution}`)
|
||||
if (configuration.transform.simplify.enabled) {
|
||||
args.push(`--simplify`)
|
||||
args.push(`--weld ${configuration.transform.simplify.weld}`)
|
||||
args.push(`--ratio ${configuration.transform.simplify.ratio}`)
|
||||
args.push(`--error ${configuration.transform.simplify.error}`)
|
||||
}
|
||||
}
|
||||
const formattedArgs = args.join(' ')
|
||||
|
||||
// run the command
|
||||
const cmd = `npx @threlte/gltf@latest ${path} ${formattedArgs}`
|
||||
try {
|
||||
execSync(cmd, {
|
||||
cwd: configuration.sourceDir
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(`Error transforming model: ${error}`)
|
||||
}
|
||||
})
|
||||
|
||||
// read dir again, but search for .svelte files only.
|
||||
const svelteFiles = readdirSync(configuration.sourceDir).filter((file) => file.endsWith('.svelte'))
|
||||
|
||||
svelteFiles.forEach((file) => {
|
||||
// now move every file to /src/components/models
|
||||
const path = join(configuration.sourceDir, file)
|
||||
const newPath = join(configuration.targetDir, file)
|
||||
copyFile: try {
|
||||
// Sanity check, we checked earlier if the file exists. Still, the CLI takes
|
||||
// a while, so who knows what happens in the meantime.
|
||||
if (!configuration.overwrite) {
|
||||
// check if file already exists
|
||||
if (existsSync(newPath)) {
|
||||
console.error(`File ${newPath} already exists, skipping.`)
|
||||
break copyFile
|
||||
}
|
||||
}
|
||||
copyFileSync(path, newPath)
|
||||
} catch (error) {
|
||||
console.error(`Error copying file: ${error}`)
|
||||
}
|
||||
|
||||
// remove the file from /static/models
|
||||
try {
|
||||
unlinkSync(path)
|
||||
} catch (error) {
|
||||
console.error(`Error removing file: ${error}`)
|
||||
}
|
||||
})
|
Reference in New Issue
Block a user