#!/usr/bin/env node /** * Creates deployment-ready Falukant GLBs in the asset repository. * Sources remain in models-src; only optimized *_opt.glb files are written * to public/models and are later fetched by update-frontend.sh. * * Example: * npm run build-runtime-models -- --assets-dir ../YourPart3Assets */ import fs from 'node:fs'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; import { fileURLToPath } from 'node:url'; const scriptDir = path.dirname(fileURLToPath(import.meta.url)); const frontendDir = path.resolve(scriptDir, '..'); const args = process.argv.slice(2); const optionIndex = args.indexOf('--assets-dir'); const categoryIndex = args.indexOf('--category'); const assetsDir = path.resolve(optionIndex >= 0 && args[optionIndex + 1] ? args[optionIndex + 1] : path.join(frontendDir, '..', '..', 'YourPart3Assets')); const sourceRoot = path.join(assetsDir, 'models-src', '3d', 'falukant'); const outputRoot = path.join(assetsDir, 'public', 'models', '3d', 'falukant'); const selectedCategory = categoryIndex >= 0 ? args[categoryIndex + 1] : null; const categories = selectedCategory ? [selectedCategory] : ['characters', 'houses']; if (categories.some((category) => !['characters', 'houses'].includes(category))) { throw new Error('Use --category characters or --category houses.'); } for (const category of categories) { const sourceDir = path.join(sourceRoot, category); const outputDir = path.join(outputRoot, category); if (!fs.existsSync(sourceDir)) { throw new Error(`Missing model source directory: ${sourceDir}`); } const result = spawnSync(process.execPath, [path.join(scriptDir, 'optimize-glb.mjs')], { cwd: frontendDir, stdio: 'inherit', env: { ...process.env, MODEL_SOURCE_DIR: sourceDir, MODEL_OUTPUT_DIR: outputDir, CLEAN_MODEL_OUTPUT: 'true', }, }); if (result.status !== 0) process.exit(result.status ?? 1); } console.log(`Runtime models ready in ${outputRoot}`);