Numerous improvements to Node API.
- Removed the shell scripts. We now invoke everything straight from Node. - Allow passing command line arguments to the tool via the Node API. - Require .glb or .gltf extension because the tool is automatically going to add that extension anyway, so we strip it off and add it back to shield the user from this weirdness. The tool may eventually stop adding an extension (and perhaps just validate it) and we can simplify our code. - Automatically add --binary option if the requested target file is a .glb. This also renames the bin/Windows directory to bin/Windows_NT, which is unfortunate but that matches os.type(). This ultimately comes from uname and that's what Windows chose to return. Let's just live with this historical accident rather than try to paper over it.
This commit is contained in:
parent
9085b8d284
commit
946f12361c
|
@ -11,7 +11,7 @@ This package contains three versions of `FBX2glTF`, compiled for three platforms
|
|||
and located in three eponymous directories:
|
||||
- bin/Darwin/FBX2glTF
|
||||
- bin/Linux/FBX2glTF
|
||||
- bin/Windows/FBX2glTF.exe
|
||||
- bin/Windows_NT/FBX2glTF.exe
|
||||
|
||||
# Usage
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
%~dp0\Windows\FBX2glTF --binary %1 %2
|
|
@ -1,43 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# fbx2glb.sh <input FBX> <output GLB>
|
||||
#
|
||||
# TODO: Pass command line switches through to binary.
|
||||
|
||||
set -e
|
||||
|
||||
BINDIR=`dirname $0`
|
||||
BINDIR=`cd ${BINDIR} ; pwd`
|
||||
|
||||
SYSTEM=`uname -s`
|
||||
FBX2GLTF="${BINDIR}/${SYSTEM}/FBX2glTF"
|
||||
|
||||
if [ ! -f "${FBX2GLTF}" ]; then
|
||||
echo "Unable to find 'FBX2glTF' binary: ${FBX2GLTF}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$#" != 2 ]; then
|
||||
echo "Usage: <fbx input> <glb output>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fullpath() {
|
||||
OLDPWD=$PWD
|
||||
cd "$(dirname "$1")"
|
||||
FULLPATH="$PWD/$(basename "$1")"
|
||||
cd "$OLDPWD"
|
||||
echo "$FULLPATH"
|
||||
}
|
||||
|
||||
INFILE=$(fullpath $1)
|
||||
OUTFILE=$(fullpath $(basename $2 ".glb"))
|
||||
|
||||
# construct a safe work dir
|
||||
SCRIPT_BASE=`basename $0`
|
||||
TEMP_DIR=`mktemp -d "/tmp/${SCRIPT_BASE}.XXXX"`
|
||||
trap "rm -rf ${TEMP_DIR}" EXIT
|
||||
cd ${TEMP_DIR}
|
||||
|
||||
# some hard-coded defaults for now
|
||||
"${FBX2GLTF}" --binary --flip-v --input "${INFILE}" --output "${OUTFILE}"
|
86
npm/index.js
86
npm/index.js
|
@ -1,6 +1,8 @@
|
|||
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`,
|
||||
|
@ -8,36 +10,70 @@ const binaries = {
|
|||
'win32': `bin\windows\Fbx2Gtlf.exe`,
|
||||
};
|
||||
|
||||
function fbx2glb(srcFile, destFile, cwd) {
|
||||
/**
|
||||
* 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.
|
||||
* 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) => {
|
||||
let script = os.type() === 'Windows_NT' ? 'fbx2glb.bat' : 'fbx2glb.sh';
|
||||
let child;
|
||||
try {
|
||||
let opts = {};
|
||||
cwd && (opts.cwd = cwd);
|
||||
child = childProcess.spawn(
|
||||
path.join(__dirname, 'bin', script),
|
||||
[ srcFile, destFile ],
|
||||
opts
|
||||
);
|
||||
let tool = path.join(__dirname, 'bin', os.type(), 'FBX2glTF');
|
||||
if (!fs.existsSync(tool)) {
|
||||
throw new Error(`Unsupported OS: ${os.type()}`);
|
||||
}
|
||||
|
||||
let destExt;
|
||||
if (destFile.endsWith('.glb')) {
|
||||
destExt = '.glb';
|
||||
opts.includes('--binary') || opts.push('--binary');
|
||||
} else if (destFile.endsWith('.gltf')) {
|
||||
destExt = '.gltf';
|
||||
} else {
|
||||
throw new Error(`Unsupported file extension: ${destFile}`);
|
||||
}
|
||||
|
||||
let srcPath = fs.realpathSync(srcFile);
|
||||
let destDir = fs.realpathSync(path.dirname(destFile));
|
||||
let destPath = path.join(destDir, path.basename(destFile, destExt));
|
||||
|
||||
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(`Script ${script} output:\n` +
|
||||
(output.length ? output : "<none>")));
|
||||
} else {
|
||||
resolve(destPath + destExt);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
let output = '';
|
||||
child.stdout.on('data', (data) => output += data);
|
||||
child.stderr.on('data', (data) => output += data);
|
||||
child.on('error', reject);
|
||||
child.on('close', code => {
|
||||
// non-zero exit code is failure
|
||||
if (code != 0) {
|
||||
reject(new Error(`Script ${script} output:\n` +
|
||||
(output.length ? output : "<none>")));
|
||||
} else {
|
||||
resolve(destFile);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = fbx2glb;
|
||||
module.exports = convert;
|
||||
|
|
|
@ -23,5 +23,8 @@
|
|||
"README.md",
|
||||
"bin",
|
||||
"index.js"
|
||||
]
|
||||
],
|
||||
"dependencies": {
|
||||
"rimraf": "^2.6.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
|
||||
fs.realpath@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
|
||||
glob@^7.0.5:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||
dependencies:
|
||||
fs.realpath "^1.0.0"
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "^3.0.4"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
|
||||
minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
|
||||
rimraf@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
dependencies:
|
||||
glob "^7.0.5"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
Loading…
Reference in New Issue