Compare commits
13 Commits
Author | SHA1 | Date |
---|---|---|
|
739ee5db94 | |
|
37f992321e | |
|
be627fa228 | |
|
1d735698ba | |
|
5c3229d6cf | |
|
3c08169510 | |
|
b9c7d0a400 | |
|
44d2d5bf97 | |
|
24092a80bb | |
|
31e3665862 | |
|
7b39358f46 | |
|
648fdfb944 | |
|
6437d02e5f |
73
README.md
73
README.md
|
@ -1,4 +1,5 @@
|
||||||
# FBX2glTF
|
# FBX2glTF
|
||||||
|
|
||||||
[](https://opensource.org/licenses/BSD-3-Clause)
|
[](https://opensource.org/licenses/BSD-3-Clause)
|
||||||
|
|
||||||
This is a command line tool for converting 3D model assets on Autodesk's
|
This is a command line tool for converting 3D model assets on Autodesk's
|
||||||
|
@ -17,11 +18,13 @@ Bleeding-edge binaries for Windows may be found [here](https://ci.appveyor.com/p
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
The tool can be invoked like so:
|
The tool can be invoked like so:
|
||||||
|
|
||||||
```
|
```
|
||||||
> FBX2glTF ~/models/butterfly.fbx
|
> FBX2glTF ~/models/butterfly.fbx
|
||||||
```
|
```
|
||||||
|
|
||||||
Or perhaps, as part of a more complex pipeline:
|
Or perhaps, as part of a more complex pipeline:
|
||||||
|
|
||||||
```
|
```
|
||||||
> FBX2glTF --binary --draco --verbose \
|
> FBX2glTF --binary --draco --verbose \
|
||||||
--input ~/models/source/butterfly.fbx \
|
--input ~/models/source/butterfly.fbx \
|
||||||
|
@ -33,8 +36,9 @@ There are also some friendly & hands-on instructions available [over at Facebook
|
||||||
### CLI Switches
|
### CLI Switches
|
||||||
|
|
||||||
You can always run the binary with --help to see what options it takes:
|
You can always run the binary with --help to see what options it takes:
|
||||||
|
|
||||||
```
|
```
|
||||||
FBX2glTF 0.9.6: Generate a glTF 2.0 representation of an FBX model.
|
FBX2glTF 0.9.7: Generate a glTF 2.0 representation of an FBX model.
|
||||||
Usage: FBX2glTF [OPTIONS] [FBX Model]
|
Usage: FBX2glTF [OPTIONS] [FBX Model]
|
||||||
|
|
||||||
Positionals:
|
Positionals:
|
||||||
|
@ -64,6 +68,7 @@ Options:
|
||||||
--blend-shape-tangents Include blend shape tangents, if reported present by the FBX SDK.
|
--blend-shape-tangents Include blend shape tangents, if reported present by the FBX SDK.
|
||||||
-k,--keep-attribute (position|normal|tangent|binormial|color|uv0|uv1|auto) ...
|
-k,--keep-attribute (position|normal|tangent|binormial|color|uv0|uv1|auto) ...
|
||||||
Used repeatedly to build a limiting set of vertex attributes to keep.
|
Used repeatedly to build a limiting set of vertex attributes to keep.
|
||||||
|
--fbx-temp-dir DIR Temporary directory to be used by FBX SDK.
|
||||||
|
|
||||||
|
|
||||||
Materials:
|
Materials:
|
||||||
|
@ -115,7 +120,7 @@ Some of these switches are not obvious:
|
||||||
will be chosen by default if you supply none of the others. Material switches
|
will be chosen by default if you supply none of the others. Material switches
|
||||||
are documented further below.
|
are documented further below.
|
||||||
- If you supply any `-keep-attribute` option, you enable a mode wherein you must
|
- If you supply any `-keep-attribute` option, you enable a mode wherein you must
|
||||||
supply it repeatedly to list *all* the vertex attributes you wish to keep in
|
supply it repeatedly to list _all_ the vertex attributes you wish to keep in
|
||||||
the conversion process. This is a way to trim the size of the resulting glTF
|
the conversion process. This is a way to trim the size of the resulting glTF
|
||||||
if you know the FBX contains superfluous attributes. The supported arguments
|
if you know the FBX contains superfluous attributes. The supported arguments
|
||||||
are `position`, `normal`, `tangent`, `color`, `uv0`, and `uv1`.
|
are `position`, `normal`, `tangent`, `color`, `uv0`, and `uv1`.
|
||||||
|
@ -143,30 +148,34 @@ all of which are automatically downloaded and/or built.
|
||||||
build system will not successfully locate any other version.
|
build system will not successfully locate any other version.
|
||||||
|
|
||||||
### Linux and MacOS X
|
### Linux and MacOS X
|
||||||
|
|
||||||
Your development environment will need to have:
|
Your development environment will need to have:
|
||||||
|
|
||||||
- build essentials (gcc for Linux, clang for Mac)
|
- build essentials (gcc for Linux, clang for Mac)
|
||||||
- cmake
|
- cmake
|
||||||
- python 3.* and associated pip3/pip command
|
- python 3.\* and associated pip3/pip command
|
||||||
- zstd
|
- zstd
|
||||||
|
|
||||||
Then, compilation on Unix machines will look something like:
|
Then, compilation on Unix machines will look something like:
|
||||||
|
|
||||||
```
|
```
|
||||||
# Determine SDK location & build settings for Linux vs (Recent) Mac OS X
|
# Determine SDK location & build settings for Linux vs (Recent) Mac OS X
|
||||||
> if [[ "$OSTYPE" == "darwin" ]]; then
|
> if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
export CONAN_CONFIG="-s compiler=apple-clang -s compiler.version=10.0 -s compiler.libcxx=libc++"
|
export CONAN_CONFIG="-s compiler=apple-clang -s compiler.version=10.0 -s compiler.libcxx=libc++"
|
||||||
export FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Darwin/archive/2019.2.tar.gz"
|
export FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Darwin/archive/2019.2.tar.gz"
|
||||||
else
|
elif [[ "$OSTYPE" == "linux"* ]]; then
|
||||||
export CONAN_CONFIG="-s compiler.libcxx=libstdc++11"
|
export CONAN_CONFIG="-s compiler.libcxx=libstdc++11"
|
||||||
export FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Linux/archive/2019.2.tar.gz"
|
export FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Linux/archive/2019.2.tar.gz"
|
||||||
fi
|
else
|
||||||
|
echo "This snippet only handles Mac OS X and Linux."
|
||||||
|
fi
|
||||||
|
|
||||||
# Fetch Project
|
# Fetch Project
|
||||||
> GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/facebookincubator/FBX2glTF.git
|
> git clone https://github.com/facebookincubator/FBX2glTF.git
|
||||||
> cd FBX2glTF
|
> cd FBX2glTF
|
||||||
|
|
||||||
# Fetch and unpack FBX SDK
|
# Fetch and unpack FBX SDK
|
||||||
> curl -sL "${FBXSDK_TARBALL}" | tar xz --strip-components=1 --wildcards */sdk
|
> curl -sL "${FBXSDK_TARBALL}" | tar xz --strip-components=1 --include */sdk/
|
||||||
# Then decompress the contents
|
# Then decompress the contents
|
||||||
> zstd -d -r --rm sdk
|
> zstd -d -r --rm sdk
|
||||||
|
|
||||||
|
@ -195,10 +204,11 @@ versions of the IDE are unlikely to successfully build the tool.
|
||||||
|
|
||||||
Note that the `CMAKE_BUILD_TYPE` variable from the Unix Makefile system is
|
Note that the `CMAKE_BUILD_TYPE` variable from the Unix Makefile system is
|
||||||
entirely ignored here; it is when you open the generated solution that
|
entirely ignored here; it is when you open the generated solution that
|
||||||
you will be choose one of the canonical build types — *Debug*,
|
you will be choose one of the canonical build types — _Debug_,
|
||||||
*Release*, *MinSizeRel*, and so on.
|
_Release_, _MinSizeRel_, and so on.
|
||||||
|
|
||||||
## Conversion Process
|
## Conversion Process
|
||||||
|
|
||||||
The actual translation begins with the FBX SDK parsing the input file, and ends
|
The actual translation begins with the FBX SDK parsing the input file, and ends
|
||||||
with the generation of the descriptive `JSON` that forms the core of glTF, along
|
with the generation of the descriptive `JSON` that forms the core of glTF, along
|
||||||
with binary buffers that hold geometry and animations (and optionally also
|
with binary buffers that hold geometry and animations (and optionally also
|
||||||
|
@ -210,13 +220,14 @@ process happens in reverse when we construct meshes and materials that conform
|
||||||
to the expectations of the glTF format.
|
to the expectations of the glTF format.
|
||||||
|
|
||||||
### Animations
|
### Animations
|
||||||
|
|
||||||
Every animation in the FBX file becomes an animation in the glTF file. The
|
Every animation in the FBX file becomes an animation in the glTF file. The
|
||||||
method used is one of "baking": we step through the interval of time spanned by
|
method used is one of "baking": we step through the interval of time spanned by
|
||||||
the animation, keyframe by keyframe, calculate the local transform of each
|
the animation, keyframe by keyframe, calculate the local transform of each
|
||||||
node, and whenever we find any node that's rotated, translated or scaled, we
|
node, and whenever we find any node that's rotated, translated or scaled, we
|
||||||
record that fact in the output.
|
record that fact in the output.
|
||||||
|
|
||||||
Beyond skeleton-based animation, *Blend Shapes* are also supported; they are
|
Beyond skeleton-based animation, _Blend Shapes_ are also supported; they are
|
||||||
read from the FBX file on a per-mesh basis, and clips can use them by varying
|
read from the FBX file on a per-mesh basis, and clips can use them by varying
|
||||||
the weights associated with each one.
|
the weights associated with each one.
|
||||||
|
|
||||||
|
@ -225,6 +236,7 @@ drawback of creating potentially very large files. The more complex the
|
||||||
animation rig, the less avoidable this data explosion is.
|
animation rig, the less avoidable this data explosion is.
|
||||||
|
|
||||||
There are three future enhancements we hope to see for animations:
|
There are three future enhancements we hope to see for animations:
|
||||||
|
|
||||||
- Version 2.0 of glTF brought us support for expressing quadratic animation
|
- Version 2.0 of glTF brought us support for expressing quadratic animation
|
||||||
curves, where previously we had only had linear. Not coincidentally, quadratic
|
curves, where previously we had only had linear. Not coincidentally, quadratic
|
||||||
splines are one of the key ways animations are expressed inside the FBX. When
|
splines are one of the key ways animations are expressed inside the FBX. When
|
||||||
|
@ -254,33 +266,37 @@ old workflow often contain baked lighting of the type that would arise naturally
|
||||||
in a PBR environment.
|
in a PBR environment.
|
||||||
|
|
||||||
Some material settings remain well supported and transfer automatically:
|
Some material settings remain well supported and transfer automatically:
|
||||||
- Emissive constants and textures
|
|
||||||
- Occlusion maps
|
- Emissive constants and textures
|
||||||
- Normal maps
|
- Occlusion maps
|
||||||
|
- Normal maps
|
||||||
|
|
||||||
This leaves the other traditional settings, first of Lambert:
|
This leaves the other traditional settings, first of Lambert:
|
||||||
- Ambient — this is anathema in the PBR world, where such effects should
|
|
||||||
emerge naturally from the fundamental colour of the material and any ambient
|
- Ambient — this is anathema in the PBR world, where such effects should
|
||||||
lighting present.
|
emerge naturally from the fundamental colour of the material and any ambient
|
||||||
- Diffuse — the material's direction-agnostic, non-specular reflection,
|
lighting present.
|
||||||
and additionally, with Blinn/Phong:
|
- Diffuse — the material's direction-agnostic, non-specular reflection,
|
||||||
- Specular — a more polished material's direction-sensitive reflection,
|
and additionally, with Blinn/Phong:
|
||||||
- Shininess — just how polished the material is; a higher value here yields a
|
- Specular — a more polished material's direction-sensitive reflection,
|
||||||
more mirror-like surface.
|
- Shininess — just how polished the material is; a higher value here yields a
|
||||||
|
more mirror-like surface.
|
||||||
|
|
||||||
(All these can be either constants or textures.)
|
(All these can be either constants or textures.)
|
||||||
|
|
||||||
#### Exporting as Unlit
|
#### Exporting as Unlit
|
||||||
|
|
||||||
If you have a model was constructed using an unlit workflow, e.g. a photogrammetry
|
If you have a model was constructed using an unlit workflow, e.g. a photogrammetry
|
||||||
capture or a landscape with careful baked-in lighting, you may choose to export
|
capture or a landscape with careful baked-in lighting, you may choose to export
|
||||||
it using the --khr-materials-common switch. This incurs a dependency on the glTF
|
it using the --khr-materials-common switch. This incurs a dependency on the glTF
|
||||||
extension 'KHR_materials_unlit; a client that accepts that extension is making
|
extension 'KHR_materials_unlit; a client that accepts that extension is making
|
||||||
a promise it'll do its best to render pixel values without lighting calculations.
|
a promise it'll do its best to render pixel values without lighting calculations.
|
||||||
|
|
||||||
**Note that at the time of writing, this glTF extension is still undergoing the
|
**Note that at the time of writing, this glTF extension is still undergoing the
|
||||||
ratification process**
|
ratification process**
|
||||||
|
|
||||||
#### Exporting as Metallic-Roughness PBR
|
#### Exporting as Metallic-Roughness PBR
|
||||||
|
|
||||||
Given the command line flag --pbr-metallic-roughness, we throw ourselves into
|
Given the command line flag --pbr-metallic-roughness, we throw ourselves into
|
||||||
the warm embrace of glTF 2.0's PBR preference.
|
the warm embrace of glTF 2.0's PBR preference.
|
||||||
|
|
||||||
|
@ -293,6 +309,7 @@ that route should be digested propertly by FBX2glTF.
|
||||||
when hooked up to Maya.)
|
when hooked up to Maya.)
|
||||||
|
|
||||||
## Draco Compression
|
## Draco Compression
|
||||||
|
|
||||||
The tool will optionally apply [Draco](https://github.com/google/draco)
|
The tool will optionally apply [Draco](https://github.com/google/draco)
|
||||||
compression to the geometric data of each mesh (vertex indices, positions,
|
compression to the geometric data of each mesh (vertex indices, positions,
|
||||||
normals, per-vertex color, and so on). This can be dramatically effective
|
normals, per-vertex color, and so on). This can be dramatically effective
|
||||||
|
@ -306,16 +323,18 @@ viewer that is willing and able to decompress the data.
|
||||||
ratification process.**
|
ratification process.**
|
||||||
|
|
||||||
## Future Improvements
|
## Future Improvements
|
||||||
|
|
||||||
This tool is under continuous development. We do not have a development roadmap
|
This tool is under continuous development. We do not have a development roadmap
|
||||||
per se, but some aspirations have been noted above. The canonical list of active
|
per se, but some aspirations have been noted above. The canonical list of active
|
||||||
TODO items can be found
|
TODO items can be found
|
||||||
[on GitHub](https://github.com/facebookincubator/FBX2glTF/labels/enhancement).
|
[on GitHub](https://github.com/facebookincubator/FBX2glTF/labels/enhancement).
|
||||||
|
|
||||||
|
|
||||||
## Authors
|
## Authors
|
||||||
- Pär Winzell
|
|
||||||
- J.M.P. van Waveren
|
- Pär Winzell
|
||||||
- Amanda Watson
|
- J.M.P. van Waveren
|
||||||
|
- Amanda Watson
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
FBX2glTF is licensed under the [3-clause BSD license](LICENSE).
|
FBX2glTF is licensed under the [3-clause BSD license](LICENSE).
|
||||||
|
|
58
appveyor.yml
58
appveyor.yml
|
@ -1,58 +0,0 @@
|
||||||
# version format
|
|
||||||
version: 1.0.{build}
|
|
||||||
|
|
||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
|
||||||
PYTHON: "C:\\Python36-x64"
|
|
||||||
FBXSDK_SDKS: sdk
|
|
||||||
|
|
||||||
stack: python %PYTHON%
|
|
||||||
|
|
||||||
#temporarily disabled
|
|
||||||
#cache:
|
|
||||||
# - C:\Users\appveyor\.conan\data -> appveyor.yml, conanfile.py
|
|
||||||
|
|
||||||
init:
|
|
||||||
- git config --global filter.lfs.required false
|
|
||||||
- git config --global filter.lfs.smudge "git-lfs smudge --skip %f"
|
|
||||||
- git config --global filter.lfs.process "git-lfs filter-process --skip"
|
|
||||||
|
|
||||||
install:
|
|
||||||
- cinst zstandard
|
|
||||||
- ps: Start-FileDownload 'https://github.com/zellski/FBXSDK-Windows/archive/2019.2.tar.gz'
|
|
||||||
- 7z e 2019.2.tar.gz
|
|
||||||
- 7z x 2019.2.tar
|
|
||||||
- ps: move -v .\FBXSDK-Windows-2019.2\sdk\ .
|
|
||||||
- ps: zstd -d -r --rm sdk
|
|
||||||
- cmd: echo "Downloading conan..."
|
|
||||||
- cmd: set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH%
|
|
||||||
- cmd: python --version
|
|
||||||
- cmd: python -m pip install --upgrade pip
|
|
||||||
- cmd: pip install conan
|
|
||||||
- cmd: conan user # Create the conan data directory
|
|
||||||
- cmd: conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
|
||||||
- cmd: conan --version
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- cmd: conan install . -i build -s build_type=Release -s compiler="Visual Studio" -s compiler.version=15
|
|
||||||
- cmd: conan build -bf build .
|
|
||||||
- cmd: move build\Release\FBX2glTF.exe build\Release\FBX2glTF-windows-x64.exe
|
|
||||||
|
|
||||||
test: off
|
|
||||||
|
|
||||||
artifacts:
|
|
||||||
- path: build/Release/FBX2glTF-windows-x64.exe
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
tag: $(APPVEYOR_REPO_TAG_NAME)
|
|
||||||
description: ''
|
|
||||||
provider: GitHub
|
|
||||||
auth_token:
|
|
||||||
secure: OSvhQP0O9uaH+OFOJpbGiiBMRTOJ+H/VJHqVBhq39RNDnOfUEr/yjJNKh3JSdNqj
|
|
||||||
artifact: build/Release/FBX2glTF-windows-x64.exe
|
|
||||||
draft: true
|
|
||||||
prerelease: true
|
|
||||||
on:
|
|
||||||
branch: master
|
|
||||||
APPVEYOR_REPO_TAG: true
|
|
|
@ -18,7 +18,7 @@ const binaries = {
|
||||||
/**
|
/**
|
||||||
* Converts an FBX to a GTLF or GLB file.
|
* Converts an FBX to a GTLF or GLB file.
|
||||||
* @param string srcFile path to the source file.
|
* @param string srcFile path to the source file.
|
||||||
* @param string destFile path to the destination file.
|
* @param string destFile path to the destination file or destination path.
|
||||||
* This must end in `.glb` or `.gltf` (case matters).
|
* This must end in `.glb` or `.gltf` (case matters).
|
||||||
* @param string[] [opts] options to pass to the converter tool.
|
* @param string[] [opts] options to pass to the converter tool.
|
||||||
* @return Promise<string> a promise that yields the full path to the converted
|
* @return Promise<string> a promise that yields the full path to the converted
|
||||||
|
@ -33,19 +33,31 @@ function convert(srcFile, destFile, opts = []) {
|
||||||
throw new Error(`Unsupported OS: ${os.type()}`);
|
throw new Error(`Unsupported OS: ${os.type()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let destExt;
|
let destExt = path.extname(destFile).toLowerCase();
|
||||||
if (destFile.endsWith('.glb')) {
|
|
||||||
destExt = '.glb';
|
if (!destExt) {
|
||||||
opts.includes('--binary') || opts.push('--binary');
|
destExt = '.gltf'
|
||||||
} else if (destFile.endsWith('.gltf')) {
|
|
||||||
destExt = '.gltf';
|
const srcFilename = path.basename(srcFile, path.extname(srcFile))
|
||||||
} else {
|
destFile = path.join(destFile, srcFilename + destExt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (destExt !== '.glb' && destExt !== '.gltf') {
|
||||||
throw new Error(`Unsupported file extension: ${destFile}`);
|
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 srcPath = fs.realpathSync(srcFile);
|
||||||
let destDir = fs.realpathSync(path.dirname(destFile));
|
let destDir = fs.realpathSync(path.dirname(destFile));
|
||||||
let destPath = path.join(destDir, path.basename(destFile, destExt));
|
let destFilename = path.basename(destFile, path.extname(destFile)) + destExt;
|
||||||
|
let destPath = path.join(destDir, destFilename);
|
||||||
|
|
||||||
let args = opts.slice(0);
|
let args = opts.slice(0);
|
||||||
args.push('--input', srcPath, '--output', destPath);
|
args.push('--input', srcPath, '--output', destPath);
|
||||||
|
@ -72,7 +84,7 @@ function convert(srcFile, destFile, opts = []) {
|
||||||
reject(new Error(`Converter output:\n` +
|
reject(new Error(`Converter output:\n` +
|
||||||
(output.length ? output : "<none>")));
|
(output.length ? output : "<none>")));
|
||||||
} else {
|
} else {
|
||||||
resolve(destPath + destExt);
|
resolve(destPath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
{
|
||||||
|
"name": "fbx2gltf",
|
||||||
|
"version": "0.9.7-p1",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||||
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "^1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||||
|
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||||
|
"requires": {
|
||||||
|
"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": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||||
|
"requires": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^1.1.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||||
|
"requires": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||||
|
},
|
||||||
|
"rimraf": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
|
||||||
|
"requires": {
|
||||||
|
"glob": "^7.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "fbx2gltf",
|
"name": "fbx2gltf",
|
||||||
"version": "0.9.6",
|
"version": "0.9.7-p1",
|
||||||
"description": "Node wrapper around FBX2glTF tools.",
|
"description": "Node wrapper around FBX2glTF tools.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -4,26 +4,31 @@
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||||
|
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||||
|
|
||||||
brace-expansion@^1.1.7:
|
brace-expansion@^1.1.7:
|
||||||
version "1.1.11"
|
version "1.1.11"
|
||||||
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
|
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||||
dependencies:
|
dependencies:
|
||||||
balanced-match "^1.0.0"
|
balanced-match "^1.0.0"
|
||||||
concat-map "0.0.1"
|
concat-map "0.0.1"
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
fs.realpath@^1.0.0:
|
fs.realpath@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||||
|
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||||
|
|
||||||
glob@^7.0.5:
|
glob@^7.1.3:
|
||||||
version "7.1.3"
|
version "7.1.4"
|
||||||
resolved "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
|
||||||
|
integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
|
||||||
dependencies:
|
dependencies:
|
||||||
fs.realpath "^1.0.0"
|
fs.realpath "^1.0.0"
|
||||||
inflight "^1.0.4"
|
inflight "^1.0.4"
|
||||||
|
@ -34,37 +39,44 @@ glob@^7.0.5:
|
||||||
|
|
||||||
inflight@^1.0.4:
|
inflight@^1.0.4:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||||
|
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||||
dependencies:
|
dependencies:
|
||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
inherits@2:
|
inherits@2:
|
||||||
version "2.0.3"
|
version "2.0.4"
|
||||||
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
minimatch@^3.0.4:
|
minimatch@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
dependencies:
|
dependencies:
|
||||||
brace-expansion "^1.1.7"
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
once@^1.3.0:
|
once@^1.3.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||||
|
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||||
dependencies:
|
dependencies:
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
path-is-absolute@^1.0.0:
|
path-is-absolute@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
rimraf@^2.6.2:
|
rimraf@^2.6.2:
|
||||||
version "2.6.2"
|
version "2.6.3"
|
||||||
resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
|
||||||
|
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.0.5"
|
glob "^7.1.3"
|
||||||
|
|
||||||
wrappy@1:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
|
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||||
|
|
|
@ -237,6 +237,8 @@ int main(int argc, char* argv[]) {
|
||||||
->check(CLI::Range(1, 32))
|
->check(CLI::Range(1, 32))
|
||||||
->group("Draco");
|
->group("Draco");
|
||||||
|
|
||||||
|
app.add_option("--fbx-temp-dir", gltfOptions.fbxTempDir, "Temporary directory to be used by FBX SDK.")->check(CLI::ExistingDirectory);
|
||||||
|
|
||||||
CLI11_PARSE(app, argc, argv);
|
CLI11_PARSE(app, argc, argv);
|
||||||
|
|
||||||
bool do_flip_u = false;
|
bool do_flip_u = false;
|
||||||
|
@ -290,14 +292,24 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
// the path of the actual .glb or .gltf file
|
// the path of the actual .glb or .gltf file
|
||||||
std::string modelPath;
|
std::string modelPath;
|
||||||
|
const auto& suffix = FileUtils::GetFileSuffix(outputPath);
|
||||||
|
|
||||||
|
// Assume binary output if extension is glb
|
||||||
|
if (suffix.has_value() && suffix.value() == "glb") {
|
||||||
|
gltfOptions.outputBinary = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (gltfOptions.outputBinary) {
|
if (gltfOptions.outputBinary) {
|
||||||
const auto& suffix = FileUtils::GetFileSuffix(outputPath);
|
|
||||||
// add .glb to output path, unless it already ends in exactly that
|
// add .glb to output path, unless it already ends in exactly that
|
||||||
if (suffix.has_value() && suffix.value() == "glb") {
|
if (suffix.has_value() && suffix.value() == "glb") {
|
||||||
modelPath = outputPath;
|
modelPath = outputPath;
|
||||||
} else {
|
} else {
|
||||||
modelPath = outputPath + ".glb";
|
modelPath = outputPath + ".glb";
|
||||||
}
|
}
|
||||||
|
// if the extension is gltf set the output folder to the parent directory
|
||||||
|
} else if (suffix.has_value() && suffix.value() == "gltf") {
|
||||||
|
outputFolder = FileUtils::getFolder(outputPath) + "/";
|
||||||
|
modelPath = outputPath;
|
||||||
} else {
|
} else {
|
||||||
// in gltf mode, we create a folder and write into that
|
// in gltf mode, we create a folder and write into that
|
||||||
outputFolder = fmt::format("{}_out/", outputPath.c_str());
|
outputFolder = fmt::format("{}_out/", outputPath.c_str());
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FBX2GLTF_VERSION std::string("0.9.6")
|
#define FBX2GLTF_VERSION std::string("0.9.7")
|
||||||
|
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
|
@ -122,4 +122,7 @@ struct GltfOptions {
|
||||||
UseLongIndicesOptions useLongIndices = UseLongIndicesOptions::AUTO;
|
UseLongIndicesOptions useLongIndices = UseLongIndicesOptions::AUTO;
|
||||||
/** Select baked animation framerate. */
|
/** Select baked animation framerate. */
|
||||||
AnimationFramerateOptions animationFramerate = AnimationFramerateOptions::BAKE24;
|
AnimationFramerateOptions animationFramerate = AnimationFramerateOptions::BAKE24;
|
||||||
|
|
||||||
|
/** Temporary directory used by FBX SDK. */
|
||||||
|
std::string fbxTempDir;
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,26 @@
|
||||||
|
|
||||||
float scaleFactor;
|
float scaleFactor;
|
||||||
|
|
||||||
|
static std::string NativeToUTF8(const std::string& str) {
|
||||||
|
#if _WIN32
|
||||||
|
char* u8cstr = nullptr;
|
||||||
|
#if (_UNICODE || UNICODE)
|
||||||
|
FbxWCToUTF8(reinterpret_cast<const char*>(str.c_str()), u8cstr);
|
||||||
|
#else
|
||||||
|
FbxAnsiToUTF8(str.c_str(), u8cstr);
|
||||||
|
#endif
|
||||||
|
if (!u8cstr) {
|
||||||
|
return str;
|
||||||
|
} else {
|
||||||
|
std::string u8str = u8cstr;
|
||||||
|
delete[] u8cstr;
|
||||||
|
return u8str;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return str;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static bool TriangleTexturePolarity(const Vec2f& uv0, const Vec2f& uv1, const Vec2f& uv2) {
|
static bool TriangleTexturePolarity(const Vec2f& uv0, const Vec2f& uv1, const Vec2f& uv2) {
|
||||||
const Vec2f d0 = uv1 - uv0;
|
const Vec2f d0 = uv1 - uv0;
|
||||||
const Vec2f d1 = uv2 - uv0;
|
const Vec2f d1 = uv2 - uv0;
|
||||||
|
@ -516,12 +536,12 @@ static void ReadCamera(RawModel& raw, FbxScene* pScene, FbxNode* pNode) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FbxCamera::EApertureMode::eHorizontal: {
|
case FbxCamera::EApertureMode::eHorizontal: {
|
||||||
fovx = pCamera->FieldOfViewX;
|
fovx = pCamera->FieldOfView;
|
||||||
fovy = HFOV2VFOV(fovx, apertureRatio);
|
fovy = HFOV2VFOV(fovx, apertureRatio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FbxCamera::EApertureMode::eVertical: {
|
case FbxCamera::EApertureMode::eVertical: {
|
||||||
fovy = pCamera->FieldOfViewY;
|
fovy = pCamera->FieldOfView;
|
||||||
fovx = VFOV2HFOV(fovy, 1.0 / apertureRatio);
|
fovx = VFOV2HFOV(fovy, 1.0 / apertureRatio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1073,13 +1093,26 @@ bool LoadFBXFile(
|
||||||
const std::string fbxFileName,
|
const std::string fbxFileName,
|
||||||
const std::set<std::string>& textureExtensions,
|
const std::set<std::string>& textureExtensions,
|
||||||
const GltfOptions& options) {
|
const GltfOptions& options) {
|
||||||
|
std::string fbxFileNameU8 = NativeToUTF8(fbxFileName);
|
||||||
FbxManager* pManager = FbxManager::Create();
|
FbxManager* pManager = FbxManager::Create();
|
||||||
|
|
||||||
|
if (!options.fbxTempDir.empty()) {
|
||||||
|
pManager->GetXRefManager().AddXRefProject("embeddedFileProject", options.fbxTempDir.c_str());
|
||||||
|
FbxXRefManager::sEmbeddedFileProject = "embeddedFileProject";
|
||||||
|
pManager->GetXRefManager().AddXRefProject("configurationProject", options.fbxTempDir.c_str());
|
||||||
|
FbxXRefManager::sConfigurationProject = "configurationProject";
|
||||||
|
pManager->GetXRefManager().AddXRefProject("localizationProject", options.fbxTempDir.c_str());
|
||||||
|
FbxXRefManager::sLocalizationProject = "localizationProject";
|
||||||
|
pManager->GetXRefManager().AddXRefProject("temporaryFileProject", options.fbxTempDir.c_str());
|
||||||
|
FbxXRefManager::sTemporaryFileProject = "temporaryFileProject";
|
||||||
|
}
|
||||||
|
|
||||||
FbxIOSettings* pIoSettings = FbxIOSettings::Create(pManager, IOSROOT);
|
FbxIOSettings* pIoSettings = FbxIOSettings::Create(pManager, IOSROOT);
|
||||||
pManager->SetIOSettings(pIoSettings);
|
pManager->SetIOSettings(pIoSettings);
|
||||||
|
|
||||||
FbxImporter* pImporter = FbxImporter::Create(pManager, "");
|
FbxImporter* pImporter = FbxImporter::Create(pManager, "");
|
||||||
|
|
||||||
if (!pImporter->Initialize(fbxFileName.c_str(), -1, pManager->GetIOSettings())) {
|
if (!pImporter->Initialize(fbxFileNameU8.c_str(), -1, pManager->GetIOSettings())) {
|
||||||
if (verboseOutput) {
|
if (verboseOutput) {
|
||||||
fmt::printf("%s\n", pImporter->GetStatus().GetErrorString());
|
fmt::printf("%s\n", pImporter->GetStatus().GetErrorString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,21 @@ MeshData::MeshData(const std::string& name, const std::vector<float>& weights)
|
||||||
|
|
||||||
json MeshData::serialize() const {
|
json MeshData::serialize() const {
|
||||||
json jsonPrimitivesArray = json::array();
|
json jsonPrimitivesArray = json::array();
|
||||||
|
json jsonTargetNamesArray = json::array();
|
||||||
for (const auto& primitive : primitives) {
|
for (const auto& primitive : primitives) {
|
||||||
jsonPrimitivesArray.push_back(*primitive);
|
jsonPrimitivesArray.push_back(*primitive);
|
||||||
|
if (!primitive->targetNames.empty()) {
|
||||||
|
for (auto targetName : primitive->targetNames) {
|
||||||
|
jsonTargetNamesArray.push_back(targetName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
json result = {{"name", name}, {"primitives", jsonPrimitivesArray}};
|
json result = {{"name", name}, {"primitives", jsonPrimitivesArray}};
|
||||||
if (!weights.empty()) {
|
if (!weights.empty()) {
|
||||||
result["weights"] = weights;
|
result["weights"] = weights;
|
||||||
}
|
}
|
||||||
|
if (!jsonTargetNamesArray.empty()) {
|
||||||
|
result["extras"]["targetNames"] = jsonTargetNamesArray;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ void PrimitiveData::AddTarget(
|
||||||
positions->ix,
|
positions->ix,
|
||||||
normals != nullptr ? normals->ix : -1,
|
normals != nullptr ? normals->ix : -1,
|
||||||
tangents != nullptr ? tangents->ix : -1));
|
tangents != nullptr ? tangents->ix : -1));
|
||||||
|
targetNames.push_back(positions->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void to_json(json& j, const PrimitiveData& d) {
|
void to_json(json& j, const PrimitiveData& d) {
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct PrimitiveData {
|
||||||
const MeshMode mode;
|
const MeshMode mode;
|
||||||
|
|
||||||
std::vector<std::tuple<int, int, int>> targetAccessors{};
|
std::vector<std::tuple<int, int, int>> targetAccessors{};
|
||||||
|
std::vector<std::string> targetNames{};
|
||||||
|
|
||||||
std::map<std::string, int> attributes;
|
std::map<std::string, int> attributes;
|
||||||
std::map<std::string, int> dracoAttributes;
|
std::map<std::string, int> dracoAttributes;
|
||||||
|
|
|
@ -22,6 +22,15 @@
|
||||||
#include "utils/Image_Utils.hpp"
|
#include "utils/Image_Utils.hpp"
|
||||||
#include "utils/String_Utils.hpp"
|
#include "utils/String_Utils.hpp"
|
||||||
|
|
||||||
|
size_t VertexHasher::operator()(const RawVertex& v) const {
|
||||||
|
size_t seed = 5381;
|
||||||
|
const auto hasher = std::hash<float>{};
|
||||||
|
seed ^= hasher(v.position[0]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
seed ^= hasher(v.position[1]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
seed ^= hasher(v.position[2]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
|
||||||
bool RawVertex::operator==(const RawVertex& other) const {
|
bool RawVertex::operator==(const RawVertex& other) const {
|
||||||
return (position == other.position) && (normal == other.normal) && (tangent == other.tangent) &&
|
return (position == other.position) && (normal == other.normal) && (tangent == other.tangent) &&
|
||||||
(binormal == other.binormal) && (color == other.color) && (uv0 == other.uv0) &&
|
(binormal == other.binormal) && (color == other.color) && (uv0 == other.uv0) &&
|
||||||
|
|
|
@ -29,9 +29,9 @@ enum RawVertexAttribute {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawBlendVertex {
|
struct RawBlendVertex {
|
||||||
Vec3f position{};
|
Vec3f position{0.0f};
|
||||||
Vec3f normal{};
|
Vec3f normal{0.0f};
|
||||||
Vec4f tangent{};
|
Vec4f tangent{0.0f};
|
||||||
|
|
||||||
bool operator==(const RawBlendVertex& other) const {
|
bool operator==(const RawBlendVertex& other) const {
|
||||||
return position == other.position && normal == other.normal && tangent == other.tangent;
|
return position == other.position && normal == other.normal && tangent == other.tangent;
|
||||||
|
@ -39,8 +39,6 @@ struct RawBlendVertex {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawVertex {
|
struct RawVertex {
|
||||||
RawVertex() : polarityUv0(false), pad1(false), pad2(false), pad3(false) {}
|
|
||||||
|
|
||||||
Vec3f position{0.0f};
|
Vec3f position{0.0f};
|
||||||
Vec3f normal{0.0f};
|
Vec3f normal{0.0f};
|
||||||
Vec3f binormal{0.0f};
|
Vec3f binormal{0.0f};
|
||||||
|
@ -57,12 +55,12 @@ struct RawVertex {
|
||||||
int blendSurfaceIx = -1;
|
int blendSurfaceIx = -1;
|
||||||
// the size of this vector is always identical to the size of the corresponding
|
// the size of this vector is always identical to the size of the corresponding
|
||||||
// RawSurface.blendChannels
|
// RawSurface.blendChannels
|
||||||
std::vector<RawBlendVertex> blends{};
|
std::vector<RawBlendVertex> blends;
|
||||||
|
|
||||||
bool polarityUv0;
|
bool polarityUv0 = false;
|
||||||
bool pad1;
|
bool pad1 = false;
|
||||||
bool pad2;
|
bool pad2 = false;
|
||||||
bool pad3;
|
bool pad3 = false;
|
||||||
|
|
||||||
bool operator==(const RawVertex& other) const;
|
bool operator==(const RawVertex& other) const;
|
||||||
size_t Difference(const RawVertex& other) const;
|
size_t Difference(const RawVertex& other) const;
|
||||||
|
@ -70,14 +68,7 @@ struct RawVertex {
|
||||||
|
|
||||||
class VertexHasher {
|
class VertexHasher {
|
||||||
public:
|
public:
|
||||||
size_t operator()(const RawVertex& v) const {
|
size_t operator()(const RawVertex& v) const;
|
||||||
size_t seed = 5381;
|
|
||||||
const auto hasher = std::hash<float>{};
|
|
||||||
seed ^= hasher(v.position[0]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
||||||
seed ^= hasher(v.position[1]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
||||||
seed ^= hasher(v.position[2]) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
|
||||||
return seed;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawTriangle {
|
struct RawTriangle {
|
||||||
|
|
Loading…
Reference in New Issue