npm/fbx2gltf/index.js (66 lines of code) (raw):
/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*/
const childProcess = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
const rimraf = require('rimraf');
const binaries = {
'darwin': `bin/darwin/Fbx2Gtlf`,
'linux': `bin/linux/Fbx2Gtlf`,
'win32': `bin\windows\Fbx2Gtlf.exe`,
};
/**
* Converts an FBX to a GTLF or GLB file.
* @param string srcFile path to the source file.
* @param string destFile path to the destination file or destination path.
* This must end in `.glb` or `.gltf` (case matters).
* @param string[] [opts] options to pass to the converter tool.
* @return Promise<string> a promise that yields the full path to the converted
* file, an error on conversion failure.
*/
function convert(srcFile, destFile, opts = []) {
return new Promise((resolve, reject) => {
try {
let binExt = os.type() === 'Windows_NT' ? '.exe' : '';
let tool = path.join(__dirname, 'bin', os.type(), 'FBX2glTF' + binExt);
if (!fs.existsSync(tool)) {
throw new Error(`Unsupported OS: ${os.type()}`);
}
let destExt = path.extname(destFile).toLowerCase();
if (!destExt) {
destExt = '.gltf'
const srcFilename = path.basename(srcFile, path.extname(srcFile))
destFile = path.join(destFile, srcFilename + destExt)
}
if (destExt !== '.glb' && destExt !== '.gltf') {
throw new Error(`Unsupported file extension: ${destFile}`);
}
const binary = opts.includes('--binary') || opts.includes('-b');
if (binary && destExt !== '.glb') {
destExt = '.glb';
} else if (!binary && destExt === 'glb') {
opts.push('--binary');
}
let srcPath = fs.realpathSync(srcFile);
let destDir = fs.realpathSync(path.dirname(destFile));
let destFilename = path.basename(destFile, path.extname(destFile)) + destExt;
let destPath = path.join(destDir, destFilename);
let args = opts.slice(0);
args.push('--input', srcPath, '--output', destPath);
let child = childProcess.spawn(tool, args);
let output = '';
child.stdout.on('data', (data) => output += data);
child.stderr.on('data', (data) => output += data);
child.on('error', reject);
child.on('close', code => {
// the FBX SDK may create an .fbm dir during conversion; delete!
let fbmCruft = srcPath.replace(/.fbx$/i, '.fbm');
// don't stick a fork in things if this fails, just log a warning
const onError = error =>
error && console.warn(`Failed to delete ${fbmCruft}: ${error}`);
try {
fs.existsSync(fbmCruft) && rimraf(fbmCruft, {}, onError);
} catch (error) {
onError(error);
}
// non-zero exit code is failure
if (code != 0) {
reject(new Error(`Converter output:\n` +
(output.length ? output : "<none>")));
} else {
resolve(destPath);
}
});
} catch (error) {
reject(error);
}
});
}
module.exports = convert;