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:
Michael Bayne 2017-10-19 10:14:13 -07:00 committed by Pär Winzell
parent 9085b8d284
commit 946f12361c
7 changed files with 136 additions and 71 deletions

View File

@ -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

View File

@ -1 +0,0 @@
%~dp0\Windows\FBX2glTF --binary %1 %2

View File

@ -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}"

View File

@ -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;

View File

@ -23,5 +23,8 @@
"README.md",
"bin",
"index.js"
]
],
"dependencies": {
"rimraf": "^2.6.2"
}
}

70
npm/yarn.lock Normal file
View File

@ -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"