Fix editor regressions and add Blender scene and animated material import
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env node
|
||||
import { spawn } from 'node:child_process';
|
||||
import { access } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
if (!args.length || args.includes('--help')) {
|
||||
console.log(`Usage: npm run blender:export -- INPUT.blend --output OUTPUT.glb [options]
|
||||
--blender PATH Blender binary (or FORMA_BLENDER; default: blender)
|
||||
--scene NAME Scene to export
|
||||
--objects GLOB Export matching objects; repeat for several patterns
|
||||
--bake-materials Bake procedural/animated surface inputs to UV atlases
|
||||
--resolution 128 Pixels per baked frame, 16–1024
|
||||
--samples 8 Cycles samples per bake, 1–256
|
||||
--lighting compat Unitless lights for Forma; spec preserves physical units
|
||||
--start-frame N --end-frame N --frame-step N
|
||||
--allow-lossy Accept approximations listed in OUTPUT.report.json
|
||||
See docs/BLENDER.md for supported features and limitations.`);
|
||||
process.exit(args.length ? 0 : 1);
|
||||
}
|
||||
const input = path.resolve(args.shift());
|
||||
if (!/\.blend$/i.test(input)) throw Error('Input must be a .blend file');
|
||||
await access(input);
|
||||
const binaryFlag = args.indexOf('--blender');
|
||||
let binary = process.env.FORMA_BLENDER || 'blender';
|
||||
if (binaryFlag >= 0) {
|
||||
if (!args[binaryFlag + 1]) throw Error('--blender requires a path');
|
||||
binary = args[binaryFlag + 1]; args.splice(binaryFlag, 2);
|
||||
}
|
||||
const outputFlag = args.indexOf('--output');
|
||||
if (outputFlag < 0 || !args[outputFlag + 1] || !/\.glb$/i.test(args[outputFlag + 1])) throw Error('--output OUTPUT.glb is required');
|
||||
const output = path.resolve(args[outputFlag + 1]);
|
||||
if (output === input) throw Error('Output must differ from input');
|
||||
args[outputFlag + 1] = output;
|
||||
const script = fileURLToPath(new URL('../blender/export_forma.py', import.meta.url));
|
||||
const child = spawn(binary, ['--background', '--factory-startup', '--disable-autoexec', input, '--python-exit-code', '1', '--python', script, '--', ...args], { stdio: 'inherit', shell: false });
|
||||
child.on('error', error => { console.error(`Cannot start Blender: ${error.message}. Set FORMA_BLENDER or --blender.`); process.exitCode = 1; });
|
||||
child.on('exit', (code, signal) => { process.exitCode = code ?? (signal ? 1 : 0); });
|
||||
process.once('SIGINT', () => child.kill('SIGINT'));
|
||||
process.once('SIGTERM', () => child.kill('SIGTERM'));
|
||||
@@ -22,5 +22,5 @@ for (const [sourceDir, targetDir] of [['hosted-editor', 'studio'], ['engine', 'e
|
||||
}
|
||||
await cp(path.join(engine, 'public/favicon.svg'), path.join(out, 'favicon.svg'));
|
||||
const title = project.name.replace(/[<>&"']/g, '');
|
||||
await writeFile(path.join(out, 'index.html'), `<!doctype html><html lang="ru"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>Forma — ${title}</title><meta name="description" content="Редактор Forma с открытым проектом. Редактируй сцену, модели и скрипты; запускай игру и сохраняй проект."><link rel="icon" href="/favicon.svg"><link rel="stylesheet" href="/studio/editor.css"></head><body><div id="root"><p style="padding:32px;font:16px system-ui">Открываю проект Forma…</p></div><script type="module" src="/studio/editor.js"></script></body></html>`);
|
||||
await writeFile(path.join(out, 'index.html'), `<!doctype html><html lang="ru"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>Forma — ${title}</title><meta name="description" content="Редактор Forma с открытым проектом. Редактируй сцену, модели и скрипты; запускай игру и сохраняй проект."><link rel="icon" href="./favicon.svg"><link rel="stylesheet" href="./studio/editor.css"></head><body><div id="root"><p style="padding:32px;font:16px system-ui">Открываю проект Forma…</p></div><script type="module" src="./studio/editor.js"></script></body></html>`);
|
||||
console.log(`Browser editor exported to ${out}; project: ${project.name}, revision ${project.revision}.`);
|
||||
|
||||
Reference in New Issue
Block a user