Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
8aebb1eb2a
|
@ -0,0 +1,3 @@
|
||||||
|
.dockerignore
|
||||||
|
Dockerfile
|
||||||
|
sdk
|
|
@ -1,5 +1,14 @@
|
||||||
|
# FBX SDK
|
||||||
|
*.a filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dylib filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.so filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dll filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lib filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|
||||||
|
# TEST FILES
|
||||||
*.glb filter=lfs diff=lfs merge=lfs -text
|
*.glb filter=lfs diff=lfs merge=lfs -text
|
||||||
*.fbx filter=lfs diff=lfs merge=lfs -text
|
*.fbx filter=lfs diff=lfs merge=lfs -text
|
||||||
*.tga filter=lfs diff=lfs merge=lfs -text
|
*.tga filter=lfs diff=lfs merge=lfs -text
|
||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
git:
|
||||||
|
lfs_skip_smudge: true
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: linux
|
||||||
|
dist: xenial
|
||||||
|
env:
|
||||||
|
- APP_NAME="FBX2glTF-linux-x64"
|
||||||
|
- CONAN_CONFIG="-s compiler.libcxx=libstdc++11"
|
||||||
|
- FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Linux/archive/2019.2.tar.gz"
|
||||||
|
- TAR_WILDCARDS="--wildcards"
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode10.2
|
||||||
|
env:
|
||||||
|
- APP_NAME="FBX2glTF-darwin-x64"
|
||||||
|
- CONAN_CONFIG="-s compiler=apple-clang -s compiler.version=10.0 -s compiler.libcxx=libc++"
|
||||||
|
- FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Darwin/archive/2019.2.tar.gz"
|
||||||
|
- TAR_WILDCARDS=""
|
||||||
|
compiler: gcc
|
||||||
|
language: generic
|
||||||
|
|
||||||
|
#disabled for now
|
||||||
|
#cache:
|
||||||
|
# directories:
|
||||||
|
# - ${HOME}/.conan
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages: zstd
|
||||||
|
homebrew:
|
||||||
|
packages: zstd
|
||||||
|
|
||||||
|
install:
|
||||||
|
- curl -sL "${FBXSDK_TARBALL}" | tar xz --strip-components=1 ${TAR_WILDCARDS} */sdk
|
||||||
|
- zstd -d -r --rm sdk
|
||||||
|
- git clone --depth 1 git://github.com/astropy/ci-helpers.git
|
||||||
|
- source ci-helpers/travis/setup_conda.sh
|
||||||
|
- conda config --set always_yes yes
|
||||||
|
- conda info -a
|
||||||
|
- conda create -n travis_env python=3.7 pip
|
||||||
|
- conda activate travis_env
|
||||||
|
- pip install conan
|
||||||
|
- conan user
|
||||||
|
- conan remote add --force bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||||
|
|
||||||
|
script:
|
||||||
|
- conan install . -i build -s build_type=Release ${CONAN_CONFIG}
|
||||||
|
- conan build . -bf build
|
||||||
|
- mv build/FBX2glTF build/${APP_NAME}
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
webhooks:
|
||||||
|
- "https://code.facebook.com/travis/webhook/"
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key:
|
||||||
|
secure: V9CTmZKM7yvsT/WCesJ/tLTuapSf0oIp73zyZrwID7zQtXaq1QJSna4tWM2T0qeZIYhniH1/mqEr2jZVW1txmYn9ZxUMH1Nmp9zzOGl/q+JlRrJUi6HRUWWhCMz003L90whngyOcGI+T7rHtcVcby4owVsze15SrQqqV74NXI8DYNIbNgQR1Nwmqsrg0QirFPEBaIKDAiKonnRDWKPy2P8vqnN9fLhj00uHLwuvahlKAnWFEbNnFbiRScKifB+Mlo6Pf6r64iikrxS2jBxAgSsvPLkuemWLmaHTeGbJMM82aqh5vGSvgYcExvZi+0RdXeIcBdv/jaivM/xge4aZ+4P+IJoX32ZNCcYFMsqES+a6TztkywMs2k1r5gV6LrTjeXJsINSW+BDFdmrwmkudETc4gelQgkMmEkdCwFHENtZGl65z8HJDQKcu9F8NQlhNU7Z5rwQNLmYccvktSDhwbFSG5eq2kFFfcbVx3ovvn1voRTNnyhhVD2ZnLepSQInAVkZbaLkE90bQ+t9icf8uDdHDn17zOQaAZuecPlSW1y4XUCJnZCi0JPLhdSmQYiF60LHYI6xDneC8pmIz8kCUbk921zu8bJBy7zKHmfHy2vqNlPKuRULRIs5QzY31jf2PVZHzB5zX3KSqx9Dd+3DtgbLX2HLaZnANbkQc0rr1X2kk=
|
||||||
|
file: build/${APP_NAME}
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
repo: facebookincubator/FBX2glTF
|
||||||
|
tags: true
|
102
CMakeLists.txt
102
CMakeLists.txt
|
@ -1,10 +1,15 @@
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
project(FBX2glTF)
|
project(FBX2glTF)
|
||||||
|
|
||||||
|
set(typical_usage_str
|
||||||
|
"Example usage:\n\
|
||||||
|
> mkdir -p build_debug\n\
|
||||||
|
> conan install . -i build_debug -s build_type=Debug -e FBXSDK_SDKS=/home/zell/FBXSDK\n\
|
||||||
|
> conan build . -bf build_debug")
|
||||||
|
|
||||||
if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
"Building from within the source tree is not supported.\n"
|
"Building from within the source tree is not supported! ${typical_usage_str}")
|
||||||
"Hint: mkdir -p build; cmake -H. -Bbuild; make -Cbuild\n")
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
@ -28,35 +33,27 @@ if (NOT FBXSDK_FOUND)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan_paths.cmake")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"The Conan package manager must run ('install') first. ${typical_usage_str}")
|
||||||
|
endif()
|
||||||
|
include("${CMAKE_BINARY_DIR}/conan_paths.cmake")
|
||||||
|
|
||||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
find_package(Iconv QUIET)
|
|
||||||
|
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_BINARY_DIR}")
|
||||||
|
|
||||||
|
# stuff we get from Conan
|
||||||
|
find_package(boost_filesystem MODULE REQUIRED)
|
||||||
|
find_package(boost_optional MODULE REQUIRED)
|
||||||
|
find_package(libxml2 MODULE REQUIRED)
|
||||||
|
find_package(zlib MODULE REQUIRED)
|
||||||
|
find_package(fmt MODULE REQUIRED)
|
||||||
|
|
||||||
# create a compilation database for e.g. clang-tidy
|
# create a compilation database for e.g. clang-tidy
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
# this will suffice for now; don't really care about 32-bit
|
|
||||||
set(LIBXML2_INCLUDE_DIRS ${FBXSDK_INCLUDE_DIR})
|
|
||||||
set(LIBXML2_LIBRARIES ${FBXSDK_ROOT}/lib/vs2017/x64/release/libxml2-mt.lib)
|
|
||||||
set(LIBXML2_LIBRARIES_DEBUG ${FBXSDK_ROOT}/lib/vs2017/x64/debug/libxml2-mt.lib)
|
|
||||||
if (NOT LIBXML2_INCLUDE_DIRS OR NOT LIBXML2_LIBRARIES)
|
|
||||||
message(FATAL_ERROR "Cannot find libxml2.lib in the expected location.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(ZLIB_INCLUDE_DIRS ${FBXSDK_INCLUDE_DIR})
|
|
||||||
set(ZLIB_LIBRARIES ${FBXSDK_ROOT}/lib/vs2017/x64/release/zlib-mt.lib)
|
|
||||||
set(ZLIB_LIBRARIES_DEBUG ${FBXSDK_ROOT}/lib/vs2017/x64/debug/zlib-mt.lib)
|
|
||||||
if (NOT ZLIB_LIBRARIES)
|
|
||||||
message(FATAL_ERROR "Cannot find zlib.lib in the expected location.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
else()
|
|
||||||
find_package(LibXml2 REQUIRED)
|
|
||||||
find_package(ZLIB REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# DRACO
|
# DRACO
|
||||||
ExternalProject_Add(Draco
|
ExternalProject_Add(Draco
|
||||||
GIT_REPOSITORY https://github.com/google/draco
|
GIT_REPOSITORY https://github.com/google/draco
|
||||||
|
@ -110,22 +107,6 @@ ExternalProject_Add(CPPCodec
|
||||||
)
|
)
|
||||||
set(CPPCODEC_INCLUDE_DIR "${CMAKE_BINARY_DIR}/cppcodec/src/CPPCodec")
|
set(CPPCODEC_INCLUDE_DIR "${CMAKE_BINARY_DIR}/cppcodec/src/CPPCodec")
|
||||||
|
|
||||||
# FMT
|
|
||||||
ExternalProject_Add(Fmt
|
|
||||||
PREFIX fmt
|
|
||||||
GIT_REPOSITORY https://github.com/fmtlib/fmt
|
|
||||||
GIT_TAG 4.0.0
|
|
||||||
CMAKE_CACHE_ARGS "-DFMT_DOC:BOOL=OFF" "-DFMT_INSTALL:BOOL=ON" "-DFMT_TEST:BOOL=OFF"
|
|
||||||
CMAKE_ARGS
|
|
||||||
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
|
|
||||||
)
|
|
||||||
set(FMT_INCLUDE_DIR "${CMAKE_BINARY_DIR}/fmt/include")
|
|
||||||
if (WIN32)
|
|
||||||
set(FMT_LIB "${CMAKE_BINARY_DIR}/fmt/lib/fmt.lib")
|
|
||||||
else()
|
|
||||||
set(FMT_LIB "${CMAKE_BINARY_DIR}/fmt/lib/libfmt.a")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
find_library(CF_FRAMEWORK CoreFoundation)
|
find_library(CF_FRAMEWORK CoreFoundation)
|
||||||
message("CoreFoundation Framework: ${CF_FRAMEWORK}")
|
message("CoreFoundation Framework: ${CF_FRAMEWORK}")
|
||||||
|
@ -190,7 +171,6 @@ set(LIB_SOURCE_FILES
|
||||||
src/utils/File_Utils.hpp
|
src/utils/File_Utils.hpp
|
||||||
src/utils/Image_Utils.cpp
|
src/utils/Image_Utils.cpp
|
||||||
src/utils/Image_Utils.hpp
|
src/utils/Image_Utils.hpp
|
||||||
src/utils/String_Utils.cpp
|
|
||||||
src/utils/String_Utils.hpp
|
src/utils/String_Utils.hpp
|
||||||
third_party/CLI11/CLI11.hpp
|
third_party/CLI11/CLI11.hpp
|
||||||
)
|
)
|
||||||
|
@ -205,7 +185,6 @@ add_dependencies(libFBX2glTF
|
||||||
MathFu
|
MathFu
|
||||||
FiFoMap
|
FiFoMap
|
||||||
CPPCodec
|
CPPCodec
|
||||||
Fmt
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT MSVC)
|
if (NOT MSVC)
|
||||||
|
@ -222,51 +201,40 @@ endif()
|
||||||
|
|
||||||
target_link_libraries(libFBX2glTF
|
target_link_libraries(libFBX2glTF
|
||||||
${FRAMEWORKS}
|
${FRAMEWORKS}
|
||||||
|
boost_filesystem::boost_filesystem
|
||||||
|
boost_optional::boost_optional
|
||||||
${DRACO_LIB}
|
${DRACO_LIB}
|
||||||
${FMT_LIB}
|
|
||||||
optimized ${FBXSDK_LIBRARY}
|
optimized ${FBXSDK_LIBRARY}
|
||||||
debug ${FBXSDK_LIBRARY_DEBUG}
|
debug ${FBXSDK_LIBRARY_DEBUG}
|
||||||
|
fmt::fmt
|
||||||
|
libxml2::libxml2
|
||||||
|
zlib::zlib
|
||||||
${CMAKE_DL_LIBS}
|
${CMAKE_DL_LIBS}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WIN32)
|
if (APPLE)
|
||||||
target_link_libraries(libFBX2glTF
|
find_package(Iconv MODULE REQUIRED)
|
||||||
optimized ${LIBXML2_LIBRARIES}
|
target_link_libraries(libFBX2glTF Iconv)
|
||||||
debug ${LIBXML2_LIBRARIES_DEBUG}
|
|
||||||
optimized ${ZLIB_LIBRARIES}
|
|
||||||
debug ${ZLIB_LIBRARIES_DEBUG}
|
|
||||||
)
|
|
||||||
else()
|
else()
|
||||||
target_link_libraries(libFBX2glTF
|
find_package(libiconv MODULE REQUIRED)
|
||||||
${LIBXML2_LIBRARIES}
|
target_link_libraries(libFBX2glTF libiconv::libiconv)
|
||||||
${ZLIB_LIBRARIES}
|
|
||||||
)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(libFBX2glTF SYSTEM PUBLIC
|
target_include_directories(libFBX2glTF PUBLIC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
"third_party/stb"
|
|
||||||
"third_party/json"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(libFBX2glTF SYSTEM PUBLIC
|
target_include_directories(libFBX2glTF SYSTEM PUBLIC
|
||||||
Iconv::Iconv
|
"third_party/stb"
|
||||||
|
"third_party/json"
|
||||||
${FBXSDK_INCLUDE_DIR}
|
${FBXSDK_INCLUDE_DIR}
|
||||||
${DRACO_INCLUDE_DIR}
|
${DRACO_INCLUDE_DIR}
|
||||||
${MATHFU_INCLUDE_DIRS}
|
${MATHFU_INCLUDE_DIRS}
|
||||||
${FIFO_MAP_INCLUDE_DIR}
|
${FIFO_MAP_INCLUDE_DIR}
|
||||||
${CPPCODEC_INCLUDE_DIR}
|
${CPPCODEC_INCLUDE_DIR}
|
||||||
${FMT_INCLUDE_DIR}
|
|
||||||
${LIBXML2_INCLUDE_DIR}
|
|
||||||
${ZLIB_INCLUDE_DIRS}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (Iconv_FOUND)
|
|
||||||
target_link_libraries(libFBX2glTF Iconv::Iconv)
|
|
||||||
target_include_directories(libFBX2glTF SYSTEM PUBLIC Iconv::Iconv)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(appFBX2glTF PUBLIC
|
target_include_directories(appFBX2glTF PUBLIC
|
||||||
"third_party/CLI11"
|
"third_party/CLI11"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y software-properties-common && \
|
||||||
|
add-apt-repository ppa:jonathonf/python-3.6 && \
|
||||||
|
add-apt-repository ppa:git-core/ppa && \
|
||||||
|
apt-get update && \
|
||||||
|
apt-get install -y python3.6 curl build-essential cmake libxml2-dev zlib1g-dev git && \
|
||||||
|
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3 get-pip.py && \
|
||||||
|
pip install conan && \
|
||||||
|
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||||
|
|
||||||
|
# Install FBX SDK
|
||||||
|
RUN mkdir -p /fbx2gltf/sdk/Linux/2019.2 && \
|
||||||
|
curl -L https://www.autodesk.com/content/dam/autodesk/www/adn/fbx/20192/fbx20192_fbxsdk_linux.tar.gz -o fbx20192_fbxsdk_linux.tar.gz && \
|
||||||
|
tar -xvf fbx20192_fbxsdk_linux.tar.gz && \
|
||||||
|
echo "yes\nn" | ./fbx20192_fbxsdk_linux /fbx2gltf/sdk/Linux/2019.2 && \
|
||||||
|
rm -rf /fbxsdktemp
|
||||||
|
|
||||||
|
COPY . /fbx2gltf
|
||||||
|
|
||||||
|
WORKDIR /fbx2gltf
|
||||||
|
|
||||||
|
# Build and install
|
||||||
|
RUN conan install . -i docker-build -s build_type=Release -s compiler=gcc -s compiler.version=5 -s compiler.libcxx=libstdc++11 && \
|
||||||
|
conan build -bf docker-build . && \
|
||||||
|
cp docker-build/FBX2glTF /usr/bin && \
|
||||||
|
cd / && \
|
||||||
|
rm -rf /fbx2gltf /root/.conan
|
|
@ -24,28 +24,23 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT DEFINED FBXSDK_VERSION)
|
if (NOT DEFINED FBXSDK_VERSION)
|
||||||
set(FBXSDK_VERSION "2018.1.1")
|
set(FBXSDK_VERSION "2019.2")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(_fbxsdk_vstudio_version "vs2017")
|
set(_fbxsdk_vstudio_version "vs2017")
|
||||||
|
|
||||||
message("Looking for FBX SDK version: ${FBXSDK_VERSION}")
|
message("Looking for FBX SDK version: ${FBXSDK_VERSION}")
|
||||||
|
|
||||||
if (DEFINED FBXSDK_SDKS)
|
if (NOT DEFINED FBXSDK_SDKS)
|
||||||
get_filename_component(FBXSDK_SDKS_ABS ${FBXSDK_SDKS} ABSOLUTE)
|
set(FBXSDK_SDKS "${CMAKE_CURRENT_SOURCE_DIR}/sdk")
|
||||||
|
|
||||||
set(FBXSDK_APPLE_ROOT "${FBXSDK_SDKS_ABS}/Darwin/${FBXSDK_VERSION}")
|
|
||||||
set(FBXSDK_LINUX_ROOT "${FBXSDK_SDKS_ABS}/Linux/${FBXSDK_VERSION}")
|
|
||||||
set(FBXSDK_WINDOWS_ROOT "${FBXSDK_SDKS_ABS}/Windows/${FBXSDK_VERSION}")
|
|
||||||
else()
|
|
||||||
set(FBXSDK_APPLE_ROOT
|
|
||||||
"/Applications/Autodesk/FBX SDK/${FBXSDK_VERSION}")
|
|
||||||
set(FBXSDK_LINUX_ROOT
|
|
||||||
"/usr")
|
|
||||||
set(FBXSDK_WINDOWS_ROOT
|
|
||||||
"C:/Program Files/Autodesk/FBX/FBX SDK/${FBXSDK_VERSION}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
get_filename_component(FBXSDK_SDKS_ABS ${FBXSDK_SDKS} ABSOLUTE)
|
||||||
|
|
||||||
|
set(FBXSDK_APPLE_ROOT "${FBXSDK_SDKS_ABS}/Darwin/${FBXSDK_VERSION}")
|
||||||
|
set(FBXSDK_LINUX_ROOT "${FBXSDK_SDKS_ABS}/Linux/${FBXSDK_VERSION}")
|
||||||
|
set(FBXSDK_WINDOWS_ROOT "${FBXSDK_SDKS_ABS}/Windows/${FBXSDK_VERSION}")
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set(_fbxsdk_root "${FBXSDK_APPLE_ROOT}")
|
set(_fbxsdk_root "${FBXSDK_APPLE_ROOT}")
|
||||||
set(_fbxsdk_libdir_debug "lib/clang/debug")
|
set(_fbxsdk_libdir_debug "lib/clang/debug")
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -2,7 +2,7 @@ BSD License
|
||||||
|
|
||||||
For FBX2glTF software
|
For FBX2glTF software
|
||||||
|
|
||||||
Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
33
PATENTS
33
PATENTS
|
@ -1,33 +0,0 @@
|
||||||
Additional Grant of Patent Rights Version 2
|
|
||||||
|
|
||||||
"Software" means the FBX2glTF software contributed by Facebook, Inc.
|
|
||||||
|
|
||||||
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
|
|
||||||
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
|
|
||||||
(subject to the termination provision below) license under any Necessary
|
|
||||||
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
|
|
||||||
transfer the Software. For avoidance of doubt, no license is granted under
|
|
||||||
Facebook’s rights in any patent claims that are infringed by (i) modifications
|
|
||||||
to the Software made by you or any third party or (ii) the Software in
|
|
||||||
combination with any software or other technology.
|
|
||||||
|
|
||||||
The license granted hereunder will terminate, automatically and without notice,
|
|
||||||
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
|
|
||||||
directly or indirectly, or take a direct financial interest in, any Patent
|
|
||||||
Assertion: (i) against Facebook or any of its subsidiaries or corporate
|
|
||||||
affiliates, (ii) against any party if such Patent Assertion arises in whole or
|
|
||||||
in part from any software, technology, product or service of Facebook or any of
|
|
||||||
its subsidiaries or corporate affiliates, or (iii) against any party relating
|
|
||||||
to the Software. Notwithstanding the foregoing, if Facebook or any of its
|
|
||||||
subsidiaries or corporate affiliates files a lawsuit alleging patent
|
|
||||||
infringement against you in the first instance, and you respond by filing a
|
|
||||||
patent infringement counterclaim in that lawsuit against that party that is
|
|
||||||
unrelated to the Software, the license granted hereunder will not terminate
|
|
||||||
under section (i) of this paragraph due to such counterclaim.
|
|
||||||
|
|
||||||
A "Necessary Claim" is a claim of a patent owned by Facebook that is
|
|
||||||
necessarily infringed by the Software standing alone.
|
|
||||||
|
|
||||||
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
|
|
||||||
or contributory infringement or inducement to infringe any patent, including a
|
|
||||||
cross-claim or counterclaim.
|
|
156
README.md
156
README.md
|
@ -1,4 +1,5 @@
|
||||||
# FBX2glTF
|
# FBX2glTF
|
||||||
|
[](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
|
||||||
venerable [FBX](https://www.autodesk.com/products/fbx/overview) format to
|
venerable [FBX](https://www.autodesk.com/products/fbx/overview) format to
|
||||||
|
@ -8,7 +9,10 @@ a modern runtime asset delivery format.
|
||||||
Precompiled binaries releases for Windows, Mac OS X and Linux may be
|
Precompiled binaries releases for Windows, Mac OS X and Linux may be
|
||||||
found [here](https://github.com/facebookincubator/FBX2glTF/releases).
|
found [here](https://github.com/facebookincubator/FBX2glTF/releases).
|
||||||
|
|
||||||
Bleeding-edge binaries are periodically built and publicly available [here](https://dev.azure.com/parwinzell/FBX2glTF/): click a build (usually the most recent), then the 'Artefacts' dropdown in the upper right.
|
Bleeding-edge binaries for Windows may be found [here](https://ci.appveyor.com/project/Facebook/fbx2gltf/build/artifacts). Linux and Mac OS X to come; meanwhile, you can [build your own](#building-it-on-your-own).
|
||||||
|
|
||||||
|
[](https://travis-ci.com/facebookincubator/FBX2glTF)
|
||||||
|
[](https://ci.appveyor.com/project/Facebook/fbx2gltf)
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
|
@ -28,47 +32,66 @@ Or perhaps, as part of a more complex pipeline:
|
||||||
|
|
||||||
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 2.0: Generate a glTF 2.0 representation of an FBX model.
|
FBX2glTF 0.9.6: Generate a glTF 2.0 representation of an FBX model.
|
||||||
Usage:
|
Usage: FBX2glTF [OPTIONS] [FBX Model]
|
||||||
FBX2glTF [OPTION...] [<FBX File>]
|
|
||||||
|
|
||||||
-i, --input arg The FBX model to convert.
|
Positionals:
|
||||||
-o, --output arg Where to generate the output, without suffix.
|
FBX Model FILE The FBX model to convert.
|
||||||
-e, --embed Inline buffers as data:// URIs within
|
|
||||||
generated non-binary glTF.
|
Options:
|
||||||
-b, --binary Output a single binary format .glb file.
|
-h,--help Print this help message and exit
|
||||||
-d, --draco Apply Draco mesh compression to geometries.
|
-v,--verbose Include blend shape tangents, if reported present by the FBX SDK.
|
||||||
--flip-u Flip all U texture coordinates.
|
-V,--version
|
||||||
--flip-v Flip all V texture coordinates (default
|
-i,--input FILE The FBX model to convert.
|
||||||
behaviour!)
|
-o,--output TEXT Where to generate the output, without suffix.
|
||||||
--no-flip-v Suppress the default flipping of V texture
|
-e,--embed Inline buffers as data:// URIs within generated non-binary glTF.
|
||||||
coordinates
|
-b,--binary Output a single binary format .glb file.
|
||||||
--pbr-metallic-roughness Try to glean glTF 2.0 native PBR attributes
|
--long-indices (never|auto|always)
|
||||||
from the FBX.
|
Whether to use 32-bit indices.
|
||||||
--khr-materials-unlit Use KHR_materials_unlit extension to specify
|
--compute-normals (never|broken|missing|always)
|
||||||
Unlit shader.
|
When to compute vertex normals from mesh geometry.
|
||||||
--blend-shape-normals Include blend shape normals, if reported
|
--anim-framerate (bake24|bake30|bake60)
|
||||||
present by the FBX SDK.
|
Select baked animation framerate.
|
||||||
--blend-shape-tangents Include blend shape tangents, if reported
|
--flip-u Flip all U texture coordinates.
|
||||||
present by the FBX SDK.
|
--no-flip-u Don't flip U texture coordinates.
|
||||||
--long-indices arg Whether to use 32-bit indices
|
--flip-v Flip all V texture coordinates.
|
||||||
(never|auto|always).
|
--no-flip-v Don't flip V texture coordinates.
|
||||||
--compute-normals arg When to compute normals for vertices
|
--no-khr-lights-punctual Don't use KHR_lights_punctual extension to export FBX lights.
|
||||||
(never|broken|missing|always).
|
--user-properties Transcribe FBX User Properties into glTF node and material 'extras'.
|
||||||
-k, --keep-attribute arg Used repeatedly to build a limiting set of
|
--blend-shape-normals Include blend shape normals, if reported present by the FBX SDK.
|
||||||
vertex attributes to keep.
|
--blend-shape-tangents Include blend shape tangents, if reported present by the FBX SDK.
|
||||||
-v, --verbose Enable verbose output.
|
-k,--keep-attribute (position|normal|tangent|binormial|color|uv0|uv1|auto) ...
|
||||||
-h, --help Show this help.
|
Used repeatedly to build a limiting set of vertex attributes to keep.
|
||||||
-V, --version Display the current program version.
|
|
||||||
|
|
||||||
|
Materials:
|
||||||
|
--pbr-metallic-roughness Try to glean glTF 2.0 native PBR attributes from the FBX.
|
||||||
|
--khr-materials-unlit Use KHR_materials_unlit extension to request an unlit shader.
|
||||||
|
|
||||||
|
|
||||||
|
Draco:
|
||||||
|
-d,--draco Apply Draco mesh compression to geometries.
|
||||||
|
--draco-compression-level INT in [0 - 10]=7
|
||||||
|
The compression level to tune Draco to.
|
||||||
|
--draco-bits-for-position INT in [1 - 32]=14
|
||||||
|
How many bits to quantize position to.
|
||||||
|
--draco-bits-for-uv INT in [1 - 32]=10
|
||||||
|
How many bits to quantize UV coordinates to.
|
||||||
|
--draco-bits-for-normals INT in [1 - 32]=10
|
||||||
|
How many bits to quantize nornals to.
|
||||||
|
--draco-bits-for-colors INT in [1 - 32]=8
|
||||||
|
How many bits to quantize colors to.
|
||||||
|
--draco-bits-for-other INT in [1 - 32]=8
|
||||||
|
How many bits to quantize all other vertex attributes to.
|
||||||
```
|
```
|
||||||
|
|
||||||
Some of these switches are not obvious:
|
Some of these switches are not obvious:
|
||||||
|
|
||||||
- `--embed` is the way to get a single distributable file without using the
|
- `--embed` is the way to get a single distributable file without using the
|
||||||
binary format. It encodes the binary buffer(s) as a single enormous
|
binary format. It encodes the binary buffer(s) as a single base64-encoded
|
||||||
base64-encoded `data://` URI. This is a very slow and space-consuming way to
|
`data://` URI. This is a very slow and space-consuming way to accomplish what
|
||||||
accomplish what the binary format was invented to do simply and efficiently,
|
the binary format was invented to do simply and efficiently, but it can be
|
||||||
but it can be useful e.g. for loaders that don't understand the .glb format.
|
useful e.g. for loaders that don't understand the .glb format.
|
||||||
- `--flip-u` and `--flip-v`, when enabled, will apply a `x -> (1.0 - x)`
|
- `--flip-u` and `--flip-v`, when enabled, will apply a `x -> (1.0 - x)`
|
||||||
function to all `u` or `v` texture coordinates respectively. The `u` version
|
function to all `u` or `v` texture coordinates respectively. The `u` version
|
||||||
is perhaps not commonly used, but flipping `v` is **the default behaviour**.
|
is perhaps not commonly used, but flipping `v` is **the default behaviour**.
|
||||||
|
@ -104,49 +127,70 @@ Some of these switches are not obvious:
|
||||||
|
|
||||||
## Building it on your own
|
## Building it on your own
|
||||||
|
|
||||||
This build process has been tested on Linux, Mac OS X and Windows. It requires
|
|
||||||
CMake 3.5+ and a reasonably C++11 compliant toolchain.
|
|
||||||
|
|
||||||
We currently depend on the open source projects
|
We currently depend on the open source projects
|
||||||
[Draco](https://github.com/google/draco),
|
[Draco](https://github.com/google/draco),
|
||||||
[MathFu](https://github.com/google/mathfu),
|
[MathFu](https://github.com/google/mathfu),
|
||||||
[Json](https://github.com/nlohmann/json),
|
[Json](https://github.com/nlohmann/json),
|
||||||
[cppcodec](https://github.com/tplgy/cppcodec),
|
[cppcodec](https://github.com/tplgy/cppcodec),
|
||||||
[cxxopts](https://github.com/jarro2783/cxxopts),
|
[CLI11](https://github.com/CLIUtils/CLI11),
|
||||||
|
[stb](https://github.com/nothings/stb),
|
||||||
and [fmt](https://github.com/fmtlib/fmt);
|
and [fmt](https://github.com/fmtlib/fmt);
|
||||||
all of which are automatically downloaded, configured and built.
|
all of which are automatically downloaded and/or built.
|
||||||
|
|
||||||
You must manually download and install the
|
**At present, only version 2019.2 of the FBX SDK is supported**. The
|
||||||
[Autodesk FBX SDK](https://www.autodesk.com/products/fbx/overview) and
|
|
||||||
accept its license agreement.
|
|
||||||
|
|
||||||
**At present, only version 2018.1.1 of the FBX SDK is supported**. The
|
|
||||||
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
|
||||||
Compilation on Unix machines should be as simple as:
|
Your development environment will need to have:
|
||||||
|
- build essentials (gcc for Linux, clang for Mac)
|
||||||
|
- cmake
|
||||||
|
- python 3.* and associated pip3/pip command
|
||||||
|
- zstd
|
||||||
|
|
||||||
|
Then, compilation on Unix machines will look something like:
|
||||||
|
|
||||||
```
|
```
|
||||||
> cd <FBX2glTF directory>
|
# Determine SDK location & build settings for Linux vs (Recent) Mac OS X
|
||||||
> cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Release
|
> if [[ "$OSTYPE" == "darwin" ]]; then
|
||||||
> make -Cbuild -j4 install
|
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"
|
||||||
|
else
|
||||||
|
export CONAN_CONFIG="-s compiler.libcxx=libstdc++11"
|
||||||
|
export FBXSDK_TARBALL="https://github.com/zellski/FBXSDK-Linux/archive/2019.2.tar.gz"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fetch Project
|
||||||
|
> GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/facebookincubator/FBX2glTF.git
|
||||||
|
> cd FBX2glTF
|
||||||
|
|
||||||
|
# Fetch and unpack FBX SDK
|
||||||
|
> curl -sL "${FBXSDK_TARBALL}" | tar xz --strip-components=1 --wildcards */sdk
|
||||||
|
# Then decompress the contents
|
||||||
|
> zstd -d -r --rm sdk
|
||||||
|
|
||||||
|
# Install and configure Conan, if needed
|
||||||
|
> pip3 install conan # or sometimes just "pip"; you may need to install Python/PIP
|
||||||
|
> conan remote add --force bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||||
|
|
||||||
|
# Initialize & run build
|
||||||
|
> conan install . -i build -s build_type=Release ${CONAN_CONFIG}
|
||||||
|
> conan build . -bf build
|
||||||
```
|
```
|
||||||
|
|
||||||
If all goes well, you will end up with a statically linked executable.
|
If all goes well, you will end up with a statically linked executable in `./build/FBX2glTF`.
|
||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
|
<TODO> the below is out of date
|
||||||
|
|
||||||
Windows users may [download](https://cmake.org/download) CMake for Windows,
|
Windows users may [download](https://cmake.org/download) CMake for Windows,
|
||||||
install it and [run it](https://cmake.org/runningcmake/) on the FBX2glTF
|
install it and [run it](https://cmake.org/runningcmake/) on the FBX2glTF
|
||||||
checkout (choose a build directory distinct from the source).
|
checkout (choose a build directory distinct from the source).
|
||||||
|
|
||||||
As part of this process, you will be asked to choose which generator
|
As part of this process, you will be asked to choose which generator
|
||||||
to use. **At present, only Visual Studio 2017 is supported.** Older
|
to use. **At present, only Visual Studio 2017 or 2019 is supported.** Older
|
||||||
versions of the IDE are unlikely to successfully build the tool.
|
versions of the IDE are unlikely to successfully build the tool.
|
||||||
|
|
||||||
*(MinGW support is plausible. The difficulty is linking statically against the
|
|
||||||
FBX SDK .lib file. Contributions welcome.)*
|
|
||||||
|
|
||||||
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*,
|
||||||
|
@ -272,4 +316,4 @@ TODO items can be found
|
||||||
- Amanda Watson
|
- Amanda Watson
|
||||||
|
|
||||||
## License
|
## License
|
||||||
FBX2glTF is BSD-licensed. We also provide an additional patent grant.
|
FBX2glTF is licensed under the [3-clause BSD license](LICENSE).
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
# 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
|
|
@ -0,0 +1,101 @@
|
||||||
|
# C/C++ with GCC
|
||||||
|
# Build your C/C++ project with GCC using make.
|
||||||
|
# Add steps that publish test results, save build artifacts, deploy, and more:
|
||||||
|
# https://docs.microsoft.com/azure/devops/pipelines/apps/c-cpp/gcc
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
- job: Linux
|
||||||
|
pool:
|
||||||
|
vmImage: 'Ubuntu 16.04'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: '3.6'
|
||||||
|
architecture: 'x64'
|
||||||
|
|
||||||
|
- script: python -m pip install --upgrade pip setuptools wheel
|
||||||
|
displayName: 'Install Python tools'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
pip install conan
|
||||||
|
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||||
|
displayName: 'Install & configure Conan'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
conan install . -i build -s build_type=Release -e FBXSDK_SDKS=sdk
|
||||||
|
displayName: 'Resolve binary dependencies and build CMake files.'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
conan build -bf build .
|
||||||
|
mv build/FBX2glTF build/FBX2glTF-linux-x64
|
||||||
|
displayName: 'Build FBX2glTF'
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
inputs:
|
||||||
|
pathtoPublish: 'build/FBX2glTF-linux-x64'
|
||||||
|
artifactName: 'binaries'
|
||||||
|
|
||||||
|
- job: Mac
|
||||||
|
pool:
|
||||||
|
vmImage: 'macOS-10.14'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: '3.6'
|
||||||
|
architecture: 'x64'
|
||||||
|
|
||||||
|
- script: python -m pip install --upgrade pip setuptools wheel
|
||||||
|
displayName: 'Install Python tools'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
pip install conan
|
||||||
|
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||||
|
displayName: 'Install Conan'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
conan install . -i build -s compiler=apple-clang -s compiler=apple-clang -s compiler.version=10.0 -s compiler.libcxx=libc++ -s build_type=Release -e FBXSDK_SDKS=sdk
|
||||||
|
displayName: 'Resolve binary dependencies and build CMake files.'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
conan build -bf build .
|
||||||
|
mv build/FBX2glTF build/FBX2glTF-darwin-x64
|
||||||
|
displayName: 'Build FBX2glTF'
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
inputs:
|
||||||
|
pathtoPublish: 'build/FBX2glTF-darwin-x64'
|
||||||
|
artifactName: 'binaries'
|
||||||
|
|
||||||
|
- job: Windows
|
||||||
|
pool:
|
||||||
|
vmImage: 'vs2017-win2016'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: '3.6'
|
||||||
|
architecture: 'x64'
|
||||||
|
|
||||||
|
- script: python -m pip install --upgrade pip setuptools wheel
|
||||||
|
displayName: 'Install Python tools'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
pip install conan
|
||||||
|
conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan
|
||||||
|
displayName: 'Install Conan'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
conan install . -i build -s build_type=Release -e FBXSDK_SDKS=sdk
|
||||||
|
displayName: 'Resolve binary dependencies and build CMake files.'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
conan build -bf build .
|
||||||
|
move build\Release\FBX2glTF.exe build\Release\FBX2glTF-windows-x64.exe
|
||||||
|
displayName: 'Build FBX2glTF'
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
inputs:
|
||||||
|
pathtoPublish: 'build/Release/FBX2glTF-windows-x64.exe'
|
||||||
|
artifactName: 'binaries'
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from conans import ConanFile, CMake
|
||||||
|
|
||||||
|
|
||||||
|
class FBX2glTFConan(ConanFile):
|
||||||
|
settings = "os", "compiler", "build_type", "arch"
|
||||||
|
requires = (
|
||||||
|
("boost_filesystem/1.69.0@bincrafters/stable"),
|
||||||
|
("libiconv/1.15@bincrafters/stable"),
|
||||||
|
("zlib/1.2.11@conan/stable"),
|
||||||
|
("libxml2/2.9.9@bincrafters/stable"),
|
||||||
|
("fmt/5.3.0@bincrafters/stable"),
|
||||||
|
)
|
||||||
|
generators = "cmake_find_package", "cmake_paths"
|
||||||
|
|
||||||
|
def configure(self):
|
||||||
|
if (
|
||||||
|
self.settings.compiler == "gcc"
|
||||||
|
and self.settings.compiler.libcxx == "libstdc++"
|
||||||
|
):
|
||||||
|
raise Exception(
|
||||||
|
"Rerun 'conan install' with argument: '-s compiler.libcxx=libstdc++11'"
|
||||||
|
)
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.definitions["FBXSDK_SDKS"] = os.getenv("FBXSDK_SDKS", "sdk")
|
||||||
|
cmake.configure()
|
||||||
|
cmake.build()
|
|
@ -0,0 +1,5 @@
|
||||||
|
version: '3.7'
|
||||||
|
services:
|
||||||
|
fbx2gltf:
|
||||||
|
build:
|
||||||
|
context: .
|
|
@ -2,7 +2,7 @@ BSD License
|
||||||
|
|
||||||
For FBX2glTF software
|
For FBX2glTF software
|
||||||
|
|
||||||
Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
|
Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification,
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
are permitted provided that the following conditions are met:
|
are permitted provided that the following conditions are met:
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
Additional Grant of Patent Rights Version 2
|
|
||||||
|
|
||||||
"Software" means the FBX2glTF software contributed by Facebook, Inc.
|
|
||||||
|
|
||||||
Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
|
|
||||||
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
|
|
||||||
(subject to the termination provision below) license under any Necessary
|
|
||||||
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
|
|
||||||
transfer the Software. For avoidance of doubt, no license is granted under
|
|
||||||
Facebook’s rights in any patent claims that are infringed by (i) modifications
|
|
||||||
to the Software made by you or any third party or (ii) the Software in
|
|
||||||
combination with any software or other technology.
|
|
||||||
|
|
||||||
The license granted hereunder will terminate, automatically and without notice,
|
|
||||||
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
|
|
||||||
directly or indirectly, or take a direct financial interest in, any Patent
|
|
||||||
Assertion: (i) against Facebook or any of its subsidiaries or corporate
|
|
||||||
affiliates, (ii) against any party if such Patent Assertion arises in whole or
|
|
||||||
in part from any software, technology, product or service of Facebook or any of
|
|
||||||
its subsidiaries or corporate affiliates, or (iii) against any party relating
|
|
||||||
to the Software. Notwithstanding the foregoing, if Facebook or any of its
|
|
||||||
subsidiaries or corporate affiliates files a lawsuit alleging patent
|
|
||||||
infringement against you in the first instance, and you respond by filing a
|
|
||||||
patent infringement counterclaim in that lawsuit against that party that is
|
|
||||||
unrelated to the Software, the license granted hereunder will not terminate
|
|
||||||
under section (i) of this paragraph due to such counterclaim.
|
|
||||||
|
|
||||||
A "Necessary Claim" is a claim of a patent owned by Facebook that is
|
|
||||||
necessarily infringed by the Software standing alone.
|
|
||||||
|
|
||||||
A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
|
|
||||||
or contributory infringement or inducement to infringe any patent, including a
|
|
||||||
cross-claim or counterclaim.
|
|
|
@ -1,5 +1,8 @@
|
||||||
# FBX2glTF
|
# FBX2glTF
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/BSD-3-Clause)
|
||||||
|
|
||||||
|
|
||||||
This is a command line tool for converting 3D model assets on the
|
This is a command line tool for converting 3D model assets on the
|
||||||
well-established [FBX](https://www.autodesk.com/products/fbx/overview) format to
|
well-established [FBX](https://www.autodesk.com/products/fbx/overview) format to
|
||||||
[glTF 2.0](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0),
|
[glTF 2.0](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0),
|
||||||
|
@ -53,6 +56,9 @@ The home of this tool is [here](https://github.com/facebookincubator/FBX2glTF).
|
||||||
|
|
||||||
# Legal
|
# Legal
|
||||||
|
|
||||||
|
FBX2glTF is licensed under the [3-clause BSD license](LICENSE).
|
||||||
|
|
||||||
|
```
|
||||||
This software contains Autodesk® FBX® code developed by Autodesk, Inc. Copyright
|
This software contains Autodesk® FBX® code developed by Autodesk, Inc. Copyright
|
||||||
2017 Autodesk, Inc. All rights, reserved. Such code is provided “as is” and
|
2017 Autodesk, Inc. All rights, reserved. Such code is provided “as is” and
|
||||||
Autodesk, Inc. disclaims any and all warranties, whether express or implied,
|
Autodesk, Inc. disclaims any and all warranties, whether express or implied,
|
||||||
|
@ -64,4 +70,4 @@ of substitute goods or services; loss of use, data, or profits; or business
|
||||||
interruption) however caused and on any theory of liability, whether in
|
interruption) however caused and on any theory of liability, whether in
|
||||||
contract, strict liability, or tort (including negligence or otherwise) arising
|
contract, strict liability, or tort (including negligence or otherwise) arising
|
||||||
in any way out of such code.
|
in any way out of such code.
|
||||||
|
```
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
"homepage": "https://github.com/facebookincubator/FBX2glTF",
|
"homepage": "https://github.com/facebookincubator/FBX2glTF",
|
||||||
"files": [
|
"files": [
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
"PATENTS",
|
|
||||||
"README.md",
|
"README.md",
|
||||||
"bin",
|
"bin",
|
||||||
"index.js"
|
"index.js"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -13,13 +12,6 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#define _stricmp strcasecmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <CLI11.hpp>
|
#include <CLI11.hpp>
|
||||||
|
|
||||||
#include "FBX2glTF.h"
|
#include "FBX2glTF.h"
|
||||||
|
@ -103,6 +95,26 @@ int main(int argc, char* argv[]) {
|
||||||
"When to compute vertex normals from mesh geometry.")
|
"When to compute vertex normals from mesh geometry.")
|
||||||
->type_name("(never|broken|missing|always)");
|
->type_name("(never|broken|missing|always)");
|
||||||
|
|
||||||
|
app.add_option(
|
||||||
|
"--anim-framerate",
|
||||||
|
[&](std::vector<std::string> choices) -> bool {
|
||||||
|
for (const std::string choice : choices) {
|
||||||
|
if (choice == "bake24") {
|
||||||
|
gltfOptions.animationFramerate = AnimationFramerateOptions::BAKE24;
|
||||||
|
} else if (choice == "bake30") {
|
||||||
|
gltfOptions.animationFramerate = AnimationFramerateOptions::BAKE30;
|
||||||
|
} else if (choice == "bake60") {
|
||||||
|
gltfOptions.animationFramerate = AnimationFramerateOptions::BAKE60;
|
||||||
|
} else {
|
||||||
|
fmt::printf("Unknown --anim-framerate: %s\n", choice);
|
||||||
|
throw CLI::RuntimeError(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"Select baked animation framerate.")
|
||||||
|
->type_name("(bake24|bake30|bake60)");
|
||||||
|
|
||||||
const auto opt_flip_u = app.add_flag("--flip-u", "Flip all U texture coordinates.");
|
const auto opt_flip_u = app.add_flag("--flip-u", "Flip all U texture coordinates.");
|
||||||
const auto opt_no_flip_u = app.add_flag("--no-flip-u", "Don't flip U texture coordinates.");
|
const auto opt_no_flip_u = app.add_flag("--no-flip-u", "Don't flip U texture coordinates.");
|
||||||
const auto opt_flip_v = app.add_flag("--flip-v", "Flip all V texture coordinates.");
|
const auto opt_flip_v = app.add_flag("--flip-v", "Flip all V texture coordinates.");
|
||||||
|
@ -284,10 +296,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
if (outputPath.empty()) {
|
if (outputPath.empty()) {
|
||||||
// if -o is not given, default to the basename of the .fbx
|
// if -o is not given, default to the basename of the .fbx
|
||||||
outputPath = fmt::format(
|
outputPath = "./" + FileUtils::GetFileBase(inputPath);
|
||||||
".{}{}",
|
|
||||||
(const char)StringUtils::GetPathSeparator(),
|
|
||||||
StringUtils::GetFileBaseString(inputPath));
|
|
||||||
}
|
}
|
||||||
// the output folder in .gltf mode, not used for .glb
|
// the output folder in .gltf mode, not used for .glb
|
||||||
std::string outputFolder;
|
std::string outputFolder;
|
||||||
|
@ -295,14 +304,17 @@ 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;
|
||||||
if (gltfOptions.outputBinary) {
|
if (gltfOptions.outputBinary) {
|
||||||
// in binary mode, we write precisely where we're asked
|
const auto& suffix = FileUtils::GetFileSuffix(outputPath);
|
||||||
modelPath = outputPath + ".glb";
|
// add .glb to output path, unless it already ends in exactly that
|
||||||
|
if (suffix.has_value() && suffix.value() == "glb") {
|
||||||
|
modelPath = outputPath;
|
||||||
|
} else {
|
||||||
|
modelPath = outputPath + ".glb";
|
||||||
|
}
|
||||||
} 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 =
|
outputFolder = fmt::format("{}_out/", outputPath.c_str());
|
||||||
fmt::format("{}_out{}", outputPath.c_str(), (const char)StringUtils::GetPathSeparator());
|
modelPath = outputFolder + FileUtils::GetFileName(outputPath) + ".gltf";
|
||||||
modelPath = outputFolder + StringUtils::GetFileNameString(outputPath) + ".gltf";
|
|
||||||
}
|
}
|
||||||
if (!FileUtils::CreatePath(modelPath.c_str())) {
|
if (!FileUtils::CreatePath(modelPath.c_str())) {
|
||||||
fmt::fprintf(stderr, "ERROR: Failed to create folder: %s'\n", outputFolder.c_str());
|
fmt::fprintf(stderr, "ERROR: Failed to create folder: %s'\n", outputFolder.c_str());
|
||||||
|
@ -315,7 +327,7 @@ int main(int argc, char* argv[]) {
|
||||||
if (verboseOutput) {
|
if (verboseOutput) {
|
||||||
fmt::printf("Loading FBX File: %s\n", inputPath);
|
fmt::printf("Loading FBX File: %s\n", inputPath);
|
||||||
}
|
}
|
||||||
if (!LoadFBXFile(raw, inputPath.c_str(), "png;jpg;jpeg")) {
|
if (!LoadFBXFile(raw, inputPath, {"png", "jpg", "jpeg"}, gltfOptions)) {
|
||||||
fmt::fprintf(stderr, "ERROR:: Failed to parse FBX: %s\n", inputPath);
|
fmt::fprintf(stderr, "ERROR:: Failed to parse FBX: %s\n", inputPath);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
141
src/FBX2glTF.h
141
src/FBX2glTF.h
|
@ -1,17 +1,17 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#if defined ( _WIN32 )
|
#if defined(_WIN32)
|
||||||
// Tell Windows not to define min() and max() macros
|
// Tell Windows not to define min() and max() macros
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
@ -20,20 +20,22 @@
|
||||||
#define FBX2GLTF_VERSION std::string("0.9.6")
|
#define FBX2GLTF_VERSION std::string("0.9.6")
|
||||||
|
|
||||||
#include <fmt/printf.h>
|
#include <fmt/printf.h>
|
||||||
|
|
||||||
#include <fbxsdk.h>
|
#include <fbxsdk.h>
|
||||||
|
|
||||||
#if defined ( _WIN32 )
|
#if defined(_WIN32)
|
||||||
// this is defined in fbxmath.h
|
// this is defined in fbxmath.h
|
||||||
#undef isnan
|
#undef isnan
|
||||||
|
#undef snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mathfu.hpp"
|
#include "mathfu.hpp"
|
||||||
|
|
||||||
// give all modules access to our tweaked JSON
|
// give all modules access to our tweaked JSON
|
||||||
#include <json.hpp>
|
|
||||||
#include <fifo_map.hpp>
|
#include <fifo_map.hpp>
|
||||||
|
#include <json.hpp>
|
||||||
|
|
||||||
template<class K, class V, class ignore, class A>
|
template <class K, class V, class ignore, class A>
|
||||||
using workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
|
using workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
|
||||||
|
|
||||||
using json = nlohmann::basic_json<workaround_fifo_map>;
|
using json = nlohmann::basic_json<workaround_fifo_map>;
|
||||||
|
@ -41,70 +43,87 @@ using json = nlohmann::basic_json<workaround_fifo_map>;
|
||||||
extern bool verboseOutput;
|
extern bool verboseOutput;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The variuos situations in which the user may wish for us to (re-)compute normals for our vertices.
|
* Centralises all the laborious downcasting from your OS' 64-bit
|
||||||
*/
|
* index variables down to the uint32s that glTF is built out of.
|
||||||
|
*/
|
||||||
|
inline uint32_t to_uint32(size_t n) {
|
||||||
|
assert(n < UINT_MAX);
|
||||||
|
return static_cast<uint32_t>(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The variuos situations in which the user may wish for us to (re-)compute normals for our
|
||||||
|
* vertices.
|
||||||
|
*/
|
||||||
enum class ComputeNormalsOption {
|
enum class ComputeNormalsOption {
|
||||||
NEVER, // do not ever compute any normals (results in broken glTF for some sources)
|
NEVER, // do not ever compute any normals (results in broken glTF for some sources)
|
||||||
BROKEN, // replace zero-length normals in any mesh that has a normal layer
|
BROKEN, // replace zero-length normals in any mesh that has a normal layer
|
||||||
MISSING, // if a mesh lacks normals, compute them all
|
MISSING, // if a mesh lacks normals, compute them all
|
||||||
ALWAYS // compute a new normal for every vertex, obliterating whatever may have been there before
|
ALWAYS // compute a new normal for every vertex, obliterating whatever may have been there before
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class UseLongIndicesOptions {
|
enum class UseLongIndicesOptions {
|
||||||
NEVER, // only ever use 16-bit indices
|
NEVER, // only ever use 16-bit indices
|
||||||
AUTO, // use shorts or longs depending on vertex count
|
AUTO, // use shorts or longs depending on vertex count
|
||||||
ALWAYS, // only ever use 32-bit indices
|
ALWAYS, // only ever use 32-bit indices
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AnimationFramerateOptions {
|
||||||
|
BAKE24, // bake animations at 24 fps
|
||||||
|
BAKE30, // bake animations at 30 fps
|
||||||
|
BAKE60, // bake animations at 60 fps
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-supplied options that dictate the nature of the glTF being generated.
|
* User-supplied options that dictate the nature of the glTF being generated.
|
||||||
*/
|
*/
|
||||||
struct GltfOptions
|
struct GltfOptions {
|
||||||
{
|
/**
|
||||||
/**
|
* If negative, disabled. Otherwise, a bitfield of RawVertexAttributes that
|
||||||
* If negative, disabled. Otherwise, a bitfield of RawVertexAttributes that
|
* specify the largest set of attributes that'll ever be kept for a vertex.
|
||||||
* specify the largest set of attributes that'll ever be kept for a vertex.
|
* The special bit RAW_VERTEX_ATTRIBUTE_AUTO triggers smart mode, where the
|
||||||
* The special bit RAW_VERTEX_ATTRIBUTE_AUTO triggers smart mode, where the
|
* attributes to keep are inferred from which textures are supplied.
|
||||||
* attributes to keep are inferred from which textures are supplied.
|
*/
|
||||||
*/
|
int keepAttribs{-1};
|
||||||
int keepAttribs { -1 };
|
/** Whether to output a .glb file, the binary format of glTF. */
|
||||||
/** Whether to output a .glb file, the binary format of glTF. */
|
bool outputBinary{false};
|
||||||
bool outputBinary { false };
|
/** If non-binary, whether to inline all resources, for a single (large) .glTF file. */
|
||||||
/** If non-binary, whether to inline all resources, for a single (large) .glTF file. */
|
bool embedResources{false};
|
||||||
bool embedResources { false };
|
|
||||||
|
|
||||||
/** Whether and how to use KHR_draco_mesh_compression to minimize static geometry size. */
|
/** Whether and how to use KHR_draco_mesh_compression to minimize static geometry size. */
|
||||||
struct {
|
struct {
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
int compressionLevel = 7;
|
int compressionLevel = 7;
|
||||||
int quantBitsPosition = 14;
|
int quantBitsPosition = 14;
|
||||||
int quantBitsTexCoord = 10;
|
int quantBitsTexCoord = 10;
|
||||||
int quantBitsNormal = 10;
|
int quantBitsNormal = 10;
|
||||||
int quantBitsColor = 8;
|
int quantBitsColor = 8;
|
||||||
int quantBitsGeneric = 8;
|
int quantBitsGeneric = 8;
|
||||||
} draco;
|
} draco;
|
||||||
|
|
||||||
/** Whether to include FBX User Properties as 'extras' metadata in glTF nodes. */
|
/** Whether to include FBX User Properties as 'extras' metadata in glTF nodes. */
|
||||||
bool enableUserProperties { false };
|
bool enableUserProperties{false};
|
||||||
|
|
||||||
/** Whether to use KHR_materials_unlit to extend materials definitions. */
|
/** Whether to use KHR_materials_unlit to extend materials definitions. */
|
||||||
bool useKHRMatUnlit { false };
|
bool useKHRMatUnlit{false};
|
||||||
/** Whether to populate the pbrMetallicRoughness substruct in materials. */
|
/** Whether to populate the pbrMetallicRoughness substruct in materials. */
|
||||||
bool usePBRMetRough { false };
|
bool usePBRMetRough{false};
|
||||||
|
|
||||||
/** Whether to include lights through the KHR_punctual_lights extension. */
|
/** Whether to include lights through the KHR_punctual_lights extension. */
|
||||||
bool useKHRLightsPunctual { true };
|
bool useKHRLightsPunctual{true};
|
||||||
|
|
||||||
/** Whether to include blend shape normals, if present according to the SDK. */
|
/** Whether to include blend shape normals, if present according to the SDK. */
|
||||||
bool useBlendShapeNormals { false };
|
bool useBlendShapeNormals{false};
|
||||||
/** Whether to include blend shape tangents, if present according to the SDK. */
|
/** Whether to include blend shape tangents, if present according to the SDK. */
|
||||||
bool useBlendShapeTangents { false };
|
bool useBlendShapeTangents{false};
|
||||||
/** Whether to normalized skinning weights. */
|
/** Whether to normalized skinning weights. */
|
||||||
bool normalizeSkinningWeights { true };
|
bool normalizeSkinningWeights { true };
|
||||||
/** Maximum number of bone influences per vertex. */
|
/** Maximum number of bone influences per vertex. */
|
||||||
int maxSkinningWeights { 4 };
|
int maxSkinningWeights { 4 };
|
||||||
/** When to compute vertex normals from geometry. */
|
/** When to compute vertex normals from geometry. */
|
||||||
ComputeNormalsOption computeNormals = ComputeNormalsOption::BROKEN;
|
ComputeNormalsOption computeNormals = ComputeNormalsOption::BROKEN;
|
||||||
/** When to use 32-bit indices. */
|
/** When to use 32-bit indices. */
|
||||||
UseLongIndicesOptions useLongIndices = UseLongIndicesOptions::AUTO;
|
UseLongIndicesOptions useLongIndices = UseLongIndicesOptions::AUTO;
|
||||||
|
/** Select baked animation framerate. */
|
||||||
|
AnimationFramerateOptions animationFramerate = AnimationFramerateOptions::BAKE24;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Fbx2Raw.hpp"
|
#include "Fbx2Raw.hpp"
|
||||||
|
@ -715,8 +714,19 @@ static void ReadNodeHierarchy(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ReadAnimations(RawModel& raw, FbxScene* pScene) {
|
static void ReadAnimations(RawModel& raw, FbxScene* pScene, const GltfOptions& options) {
|
||||||
FbxTime::EMode eMode = FbxTime::eFrames24;
|
FbxTime::EMode eMode = FbxTime::eFrames24;
|
||||||
|
switch (options.animationFramerate) {
|
||||||
|
case AnimationFramerateOptions::BAKE24:
|
||||||
|
eMode = FbxTime::eFrames24;
|
||||||
|
break;
|
||||||
|
case AnimationFramerateOptions::BAKE30:
|
||||||
|
eMode = FbxTime::eFrames30;
|
||||||
|
break;
|
||||||
|
case AnimationFramerateOptions::BAKE60:
|
||||||
|
eMode = FbxTime::eFrames60;
|
||||||
|
break;
|
||||||
|
}
|
||||||
const double epsilon = 1e-5f;
|
const double epsilon = 1e-5f;
|
||||||
|
|
||||||
const int animationCount = pScene->GetSrcObjectCount<FbxAnimStack>();
|
const int animationCount = pScene->GetSrcObjectCount<FbxAnimStack>();
|
||||||
|
@ -726,24 +736,58 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene) {
|
||||||
|
|
||||||
pScene->SetCurrentAnimationStack(pAnimStack);
|
pScene->SetCurrentAnimationStack(pAnimStack);
|
||||||
|
|
||||||
FbxTakeInfo* takeInfo = pScene->GetTakeInfo(animStackName);
|
/**
|
||||||
if (takeInfo == nullptr) {
|
* Individual animations are often concatenated on the timeline, and the
|
||||||
fmt::printf("Warning:: animation '%s' has no Take information. Skipping.\n", animStackName);
|
* only certain way to identify precisely what interval they occupy is to
|
||||||
// not all animstacks have a take
|
* depth-traverse the entire animation stack, and examine the actual keys.
|
||||||
continue;
|
*
|
||||||
|
* There is a deprecated concept of an "animation take" which is meant to
|
||||||
|
* provide precisely this time interval information, but the data is not
|
||||||
|
* actually derived by the SDK from source-of-truth data structures, but
|
||||||
|
* rather provided directly by the FBX exporter, and not sanity checked.
|
||||||
|
*
|
||||||
|
* Some exporters calculate it correctly. Others do not. In any case, we
|
||||||
|
* now ignore it completely.
|
||||||
|
*/
|
||||||
|
FbxLongLong firstFrameIndex = -1;
|
||||||
|
FbxLongLong lastFrameIndex = -1;
|
||||||
|
for (int layerIx = 0; layerIx < pAnimStack->GetMemberCount(); layerIx++) {
|
||||||
|
FbxAnimLayer* layer = pAnimStack->GetMember<FbxAnimLayer>(layerIx);
|
||||||
|
for (int nodeIx = 0; nodeIx < layer->GetMemberCount(); nodeIx++) {
|
||||||
|
auto* node = layer->GetMember<FbxAnimCurveNode>(nodeIx);
|
||||||
|
FbxTimeSpan nodeTimeSpan;
|
||||||
|
// Multiple curves per curve node is not even supported by the SDK.
|
||||||
|
for (int curveIx = 0; curveIx < node->GetCurveCount(0); curveIx++) {
|
||||||
|
FbxAnimCurve* curve = node->GetCurve(0U, curveIx);
|
||||||
|
if (curve == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// simply take the interval as first key to last key
|
||||||
|
int firstKeyIndex = 0;
|
||||||
|
int lastKeyIndex = std::max(firstKeyIndex, curve->KeyGetCount() - 1);
|
||||||
|
FbxLongLong firstCurveFrame = curve->KeyGetTime(firstKeyIndex).GetFrameCount(eMode);
|
||||||
|
FbxLongLong lastCurveFrame = curve->KeyGetTime(lastKeyIndex).GetFrameCount(eMode);
|
||||||
|
|
||||||
|
// the final interval is the union of all node curve intervals
|
||||||
|
if (firstFrameIndex == -1 || firstCurveFrame < firstFrameIndex) {
|
||||||
|
firstFrameIndex = firstCurveFrame;
|
||||||
|
}
|
||||||
|
if (lastFrameIndex == -1 || lastCurveFrame > lastFrameIndex) {
|
||||||
|
lastFrameIndex = lastCurveFrame;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
RawAnimation animation;
|
||||||
|
animation.name = animStackName;
|
||||||
|
|
||||||
|
fmt::printf(
|
||||||
|
"Animation %s: [%lu - %lu]\n", std::string(animStackName), firstFrameIndex, lastFrameIndex);
|
||||||
|
|
||||||
if (verboseOutput) {
|
if (verboseOutput) {
|
||||||
fmt::printf("animation %zu: %s (%d%%)", animIx, (const char*)animStackName, 0);
|
fmt::printf("animation %zu: %s (%d%%)", animIx, (const char*)animStackName, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxTime start = takeInfo->mLocalTimeSpan.GetStart();
|
|
||||||
FbxTime end = takeInfo->mLocalTimeSpan.GetStop();
|
|
||||||
|
|
||||||
RawAnimation animation;
|
|
||||||
animation.name = animStackName;
|
|
||||||
|
|
||||||
FbxLongLong firstFrameIndex = start.GetFrameCount(eMode);
|
|
||||||
FbxLongLong lastFrameIndex = end.GetFrameCount(eMode);
|
|
||||||
for (FbxLongLong frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; frameIndex++) {
|
for (FbxLongLong frameIndex = firstFrameIndex; frameIndex <= lastFrameIndex; frameIndex++) {
|
||||||
FbxTime pTime;
|
FbxTime pTime;
|
||||||
// first frame is always at t = 0.0
|
// first frame is always at t = 0.0
|
||||||
|
@ -910,39 +954,61 @@ static void ReadAnimations(RawModel& raw, FbxScene* pScene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetInferredFileName(
|
static std::string FindFileLoosely(
|
||||||
const std::string& fbxFileName,
|
const std::string& fbxFileName,
|
||||||
const std::string& directory,
|
const std::string& directory,
|
||||||
const std::vector<std::string>& directoryFileList) {
|
const std::vector<std::string>& directoryFileList) {
|
||||||
if (FileUtils::FileExists(fbxFileName)) {
|
if (FileUtils::FileExists(fbxFileName)) {
|
||||||
return fbxFileName;
|
return fbxFileName;
|
||||||
}
|
}
|
||||||
// Get the file name with file extension.
|
|
||||||
const std::string fileName =
|
// From e.g. C:/Assets/Texture.jpg, extract 'Texture.jpg'
|
||||||
StringUtils::GetFileNameString(StringUtils::GetCleanPathString(fbxFileName));
|
const std::string fileName = FileUtils::GetFileName(fbxFileName);
|
||||||
|
|
||||||
// Try to find a match with extension.
|
// Try to find a match with extension.
|
||||||
for (const auto& file : directoryFileList) {
|
for (const auto& file : directoryFileList) {
|
||||||
if (StringUtils::CompareNoCase(fileName, file) == 0) {
|
if (StringUtils::CompareNoCase(fileName, FileUtils::GetFileName(file)) == 0) {
|
||||||
return std::string(directory) + file;
|
return directory + "/" + file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the file name without file extension.
|
// Get the file name without file extension.
|
||||||
const std::string fileBase = StringUtils::GetFileBaseString(fileName);
|
const std::string fileBase = FileUtils::GetFileBase(fileName);
|
||||||
|
|
||||||
// Try to find a match without file extension.
|
// Try to find a match that ignores file extension
|
||||||
for (const auto& file : directoryFileList) {
|
for (const auto& file : directoryFileList) {
|
||||||
// If the two extension-less base names match.
|
if (StringUtils::CompareNoCase(fileBase, FileUtils::GetFileBase(file)) == 0) {
|
||||||
if (StringUtils::CompareNoCase(fileBase, StringUtils::GetFileBaseString(file)) == 0) {
|
return directory + "/" + file;
|
||||||
// Return the name with extension of the file in the directory.
|
|
||||||
return std::string(directory) + file;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to locate the best match to the given texture filename, as provided in the FBX,
|
||||||
|
* possibly searching through the provided folders for a reasonable-looking match.
|
||||||
|
*
|
||||||
|
* Returns empty string if no match can be found, else the absolute path of the file.
|
||||||
|
**/
|
||||||
|
static std::string FindFbxTexture(
|
||||||
|
const std::string& textureFileName,
|
||||||
|
const std::vector<std::string>& folders,
|
||||||
|
const std::vector<std::vector<std::string>>& folderContents) {
|
||||||
|
// it might exist exactly as-is on the running machine's filesystem
|
||||||
|
if (FileUtils::FileExists(textureFileName)) {
|
||||||
|
return textureFileName;
|
||||||
|
}
|
||||||
|
// else look in other designated folders
|
||||||
|
for (int ii = 0; ii < folders.size(); ii++) {
|
||||||
|
const auto& fileLocation = FindFileLoosely(textureFileName, folders[ii], folderContents[ii]);
|
||||||
|
if (!fileLocation.empty()) {
|
||||||
|
return FileUtils::GetAbsolutePath(fileLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The texture file names inside of the FBX often contain some long author-specific
|
The texture file names inside of the FBX often contain some long author-specific
|
||||||
path with the wrong extensions. For instance, all of the art assets may be PSD
|
path with the wrong extensions. For instance, all of the art assets may be PSD
|
||||||
|
@ -954,50 +1020,60 @@ static std::string GetInferredFileName(
|
||||||
*/
|
*/
|
||||||
static void FindFbxTextures(
|
static void FindFbxTextures(
|
||||||
FbxScene* pScene,
|
FbxScene* pScene,
|
||||||
const char* fbxFileName,
|
const std::string& fbxFileName,
|
||||||
const char* extensions,
|
const std::set<std::string>& extensions,
|
||||||
std::map<const FbxTexture*, FbxString>& textureLocations) {
|
std::map<const FbxTexture*, FbxString>& textureLocations) {
|
||||||
// Get the folder the FBX file is in.
|
// figure out what folder the FBX file is in,
|
||||||
const std::string folder = StringUtils::GetFolderString(fbxFileName);
|
const auto& fbxFolder = FileUtils::getFolder(fbxFileName);
|
||||||
|
std::vector<std::string> folders{
|
||||||
|
// first search filename.fbm folder which the SDK itself expands embedded textures into,
|
||||||
|
fbxFolder + "/" + FileUtils::GetFileBase(fbxFileName) + ".fbm", // filename.fbm
|
||||||
|
// then the FBX folder itself,
|
||||||
|
fbxFolder,
|
||||||
|
// then finally our working directory
|
||||||
|
FileUtils::GetCurrentFolder(),
|
||||||
|
};
|
||||||
|
|
||||||
// Check if there is a filename.fbm folder to which embedded textures were extracted.
|
// List the contents of each of these folders (if they exist)
|
||||||
const std::string fbmFolderName = folder + StringUtils::GetFileBaseString(fbxFileName) + ".fbm/";
|
std::vector<std::vector<std::string>> folderContents;
|
||||||
|
for (const auto& folder : folders) {
|
||||||
// Search either in the folder with embedded textures or in the same folder as the FBX file.
|
if (FileUtils::FolderExists(folder)) {
|
||||||
const std::string searchFolder = FileUtils::FolderExists(fbmFolderName) ? fbmFolderName : folder;
|
folderContents.push_back(FileUtils::ListFolderFiles(folder, extensions));
|
||||||
|
} else {
|
||||||
// Get a list with all the texture files from either the folder with embedded textures or the same
|
folderContents.push_back({});
|
||||||
// folder as the FBX file.
|
}
|
||||||
std::vector<std::string> fileList = FileUtils::ListFolderFiles(searchFolder.c_str(), extensions);
|
}
|
||||||
|
|
||||||
// Try to match the FBX texture names with the actual files on disk.
|
// Try to match the FBX texture names with the actual files on disk.
|
||||||
for (int i = 0; i < pScene->GetTextureCount(); i++) {
|
for (int i = 0; i < pScene->GetTextureCount(); i++) {
|
||||||
const FbxFileTexture* pFileTexture = FbxCast<FbxFileTexture>(pScene->GetTexture(i));
|
const FbxFileTexture* pFileTexture = FbxCast<FbxFileTexture>(pScene->GetTexture(i));
|
||||||
if (pFileTexture == nullptr) {
|
if (pFileTexture != nullptr) {
|
||||||
continue;
|
const std::string fileLocation =
|
||||||
|
FindFbxTexture(pFileTexture->GetFileName(), folders, folderContents);
|
||||||
|
// always extend the mapping (even for files we didn't find)
|
||||||
|
textureLocations.emplace(pFileTexture, fileLocation.c_str());
|
||||||
|
if (fileLocation.empty()) {
|
||||||
|
fmt::printf(
|
||||||
|
"Warning: could not find a image file for texture: %s.\n", pFileTexture->GetName());
|
||||||
|
} else if (verboseOutput) {
|
||||||
|
fmt::printf("Found texture '%s' at: %s\n", pFileTexture->GetName(), fileLocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const std::string inferredName =
|
|
||||||
GetInferredFileName(pFileTexture->GetFileName(), searchFolder, fileList);
|
|
||||||
if (inferredName.empty()) {
|
|
||||||
fmt::printf(
|
|
||||||
"Warning: could not find a local image file for texture: %s.\n"
|
|
||||||
"Original filename: %s\n",
|
|
||||||
pFileTexture->GetName(),
|
|
||||||
pFileTexture->GetFileName());
|
|
||||||
}
|
|
||||||
// always extend the mapping, even for files we didn't find
|
|
||||||
textureLocations.emplace(pFileTexture, inferredName.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadFBXFile(RawModel& raw, const char* fbxFileName, const char* textureExtensions) {
|
bool LoadFBXFile(
|
||||||
|
RawModel& raw,
|
||||||
|
const std::string fbxFileName,
|
||||||
|
const std::set<std::string>& textureExtensions,
|
||||||
|
const GltfOptions& options) {
|
||||||
FbxManager* pManager = FbxManager::Create();
|
FbxManager* pManager = FbxManager::Create();
|
||||||
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, -1, pManager->GetIOSettings())) {
|
if (!pImporter->Initialize(fbxFileName.c_str(), -1, pManager->GetIOSettings())) {
|
||||||
if (verboseOutput) {
|
if (verboseOutput) {
|
||||||
fmt::printf("%s\n", pImporter->GetStatus().GetErrorString());
|
fmt::printf("%s\n", pImporter->GetStatus().GetErrorString());
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +1112,7 @@ bool LoadFBXFile(RawModel& raw, const char* fbxFileName, const char* textureExte
|
||||||
|
|
||||||
ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "");
|
ReadNodeHierarchy(raw, pScene, pScene->GetRootNode(), 0, "");
|
||||||
ReadNodeAttributes(raw, pScene, pScene->GetRootNode(), textureLocations);
|
ReadNodeAttributes(raw, pScene, pScene->GetRootNode(), textureLocations);
|
||||||
ReadAnimations(raw, pScene);
|
ReadAnimations(raw, pScene, options);
|
||||||
|
|
||||||
pScene->Destroy();
|
pScene->Destroy();
|
||||||
pManager->Destroy();
|
pManager->Destroy();
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "raw/RawModel.hpp"
|
#include "raw/RawModel.hpp"
|
||||||
|
|
||||||
bool LoadFBXFile(RawModel& raw, const char* fbxFileName, const char* textureExtensions);
|
bool LoadFBXFile(
|
||||||
|
RawModel& raw,
|
||||||
|
const std::string fbxFileName,
|
||||||
|
const std::set<std::string>& textureExtensions,
|
||||||
|
const GltfOptions& options);
|
||||||
|
|
||||||
json TranscribeProperty(FbxProperty& prop);
|
json TranscribeProperty(FbxProperty& prop);
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FbxBlendShapesAccess.hpp"
|
#include "FbxBlendShapesAccess.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -95,7 +94,7 @@ class FbxBlendShapesAccess {
|
||||||
}
|
}
|
||||||
|
|
||||||
FbxAnimCurve* GetAnimation(size_t channelIx, size_t animIx) const {
|
FbxAnimCurve* GetAnimation(size_t channelIx, size_t animIx) const {
|
||||||
return channels.at(channelIx).ExtractAnimation(animIx);
|
return channels.at(channelIx).ExtractAnimation(to_uint32(animIx));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "FBX2glTF.h"
|
#include "FBX2glTF.h"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FbxSkinningAccess.hpp"
|
#include "FbxSkinningAccess.hpp"
|
||||||
|
@ -28,7 +27,9 @@ FbxSkinningAccess::FbxSkinningAccess(const FbxMesh* pMesh, FbxScene* pScene, Fbx
|
||||||
const int* clusterIndices = cluster->GetControlPointIndices();
|
const int* clusterIndices = cluster->GetControlPointIndices();
|
||||||
const double* clusterWeights = cluster->GetControlPointWeights();
|
const double* clusterWeights = cluster->GetControlPointWeights();
|
||||||
|
|
||||||
assert(cluster->GetLinkMode() == FbxCluster::eNormalize);
|
assert(
|
||||||
|
cluster->GetLinkMode() == FbxCluster::eNormalize ||
|
||||||
|
cluster->GetLinkMode() == FbxCluster::eTotalOne);
|
||||||
|
|
||||||
// Transform link matrix.
|
// Transform link matrix.
|
||||||
FbxAMatrix transformLinkMatrix;
|
FbxAMatrix transformLinkMatrix;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -43,7 +42,7 @@ class FbxSkinningAccess {
|
||||||
return jointNodes[jointIndex];
|
return jointNodes[jointIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
const long GetJointId(const int jointIndex) const {
|
const uint64_t GetJointId(const int jointIndex) const {
|
||||||
return jointIds[jointIndex];
|
return jointIds[jointIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +54,7 @@ class FbxSkinningAccess {
|
||||||
return jointInverseGlobalTransforms[jointIndex];
|
return jointInverseGlobalTransforms[jointIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
const long GetRootNode() const {
|
const uint64_t GetRootNode() const {
|
||||||
assert(rootIndex != -1);
|
assert(rootIndex != -1);
|
||||||
return jointIds[rootIndex];
|
return jointIds[rootIndex];
|
||||||
}
|
}
|
||||||
|
@ -71,7 +70,7 @@ class FbxSkinningAccess {
|
||||||
private:
|
private:
|
||||||
int rootIndex;
|
int rootIndex;
|
||||||
int maxBoneInfluences;
|
int maxBoneInfluences;
|
||||||
std::vector<long> jointIds;
|
std::vector<uint64_t> jointIds;
|
||||||
std::vector<FbxNode*> jointNodes;
|
std::vector<FbxNode*> jointNodes;
|
||||||
std::vector<FbxMatrix> jointSkinningTransforms;
|
std::vector<FbxMatrix> jointSkinningTransforms;
|
||||||
std::vector<FbxMatrix> jointInverseGlobalTransforms;
|
std::vector<FbxMatrix> jointInverseGlobalTransforms;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "RoughnessMetallicMaterials.hpp"
|
#include "RoughnessMetallicMaterials.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "fbx/Fbx2Raw.hpp"
|
#include "fbx/Fbx2Raw.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "RoughnessMetallicMaterials.hpp"
|
#include "RoughnessMetallicMaterials.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TraditionalMaterials.hpp"
|
#include "TraditionalMaterials.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "FbxMaterials.hpp"
|
#include "FbxMaterials.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GltfModel.hpp"
|
#include "GltfModel.hpp"
|
||||||
|
@ -12,7 +11,7 @@
|
||||||
std::shared_ptr<BufferViewData> GltfModel::GetAlignedBufferView(
|
std::shared_ptr<BufferViewData> GltfModel::GetAlignedBufferView(
|
||||||
BufferData& buffer,
|
BufferData& buffer,
|
||||||
const BufferViewData::GL_ArrayType target) {
|
const BufferViewData::GL_ArrayType target) {
|
||||||
unsigned long bufferSize = this->binary->size();
|
uint32_t bufferSize = to_uint32(this->binary->size());
|
||||||
if ((bufferSize % 4) > 0) {
|
if ((bufferSize % 4) > 0) {
|
||||||
bufferSize += (4 - (bufferSize % 4));
|
bufferSize += (4 - (bufferSize % 4));
|
||||||
this->binary->resize(bufferSize);
|
this->binary->resize(bufferSize);
|
||||||
|
@ -27,7 +26,7 @@ GltfModel::AddRawBufferView(BufferData& buffer, const char* source, uint32_t byt
|
||||||
bufferView->byteLength = bytes;
|
bufferView->byteLength = bytes;
|
||||||
|
|
||||||
// make space for the new bytes (possibly moving the underlying data)
|
// make space for the new bytes (possibly moving the underlying data)
|
||||||
unsigned long bufferSize = this->binary->size();
|
uint32_t bufferSize = to_uint32(this->binary->size());
|
||||||
this->binary->resize(bufferSize + bytes);
|
this->binary->resize(bufferSize + bytes);
|
||||||
|
|
||||||
// and copy them into place
|
// and copy them into place
|
||||||
|
@ -52,7 +51,7 @@ std::shared_ptr<BufferViewData> GltfModel::AddBufferViewForFile(
|
||||||
|
|
||||||
std::vector<char> fileBuffer(size);
|
std::vector<char> fileBuffer(size);
|
||||||
if (file.read(fileBuffer.data(), size)) {
|
if (file.read(fileBuffer.data(), size)) {
|
||||||
result = AddRawBufferView(buffer, fileBuffer.data(), size);
|
result = AddRawBufferView(buffer, fileBuffer.data(), to_uint32(size));
|
||||||
} else {
|
} else {
|
||||||
fmt::printf("Warning: Couldn't read %lu bytes from %s, skipping file.\n", size, filename);
|
fmt::printf("Warning: Couldn't read %lu bytes from %s, skipping file.\n", size, filename);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -44,7 +43,7 @@ template <typename T>
|
||||||
class Holder {
|
class Holder {
|
||||||
public:
|
public:
|
||||||
std::shared_ptr<T> hold(T* ptr) {
|
std::shared_ptr<T> hold(T* ptr) {
|
||||||
ptr->ix = ptrs.size();
|
ptr->ix = to_uint32(ptrs.size());
|
||||||
ptrs.emplace_back(ptr);
|
ptrs.emplace_back(ptr);
|
||||||
return ptrs.back();
|
return ptrs.back();
|
||||||
}
|
}
|
||||||
|
@ -114,7 +113,7 @@ class GltfModel {
|
||||||
primitive.AddDracoAttrib(attrDef, attribArr);
|
primitive.AddDracoAttrib(attrDef, attribArr);
|
||||||
|
|
||||||
accessor = accessors.hold(new AccessorData(attrDef.glType));
|
accessor = accessors.hold(new AccessorData(attrDef.glType));
|
||||||
accessor->count = attribArr.size();
|
accessor->count = to_uint32(attribArr.size());
|
||||||
} else {
|
} else {
|
||||||
auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER);
|
auto bufferView = GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER);
|
||||||
accessor = AddAccessorWithView(*bufferView, attrDef.glType, attribArr, std::string(""));
|
accessor = AddAccessorWithView(*bufferView, attrDef.glType, attribArr, std::string(""));
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Raw2Gltf.hpp"
|
#include "Raw2Gltf.hpp"
|
||||||
|
@ -256,29 +255,28 @@ ModelData* Raw2Gltf(
|
||||||
if (material.info->shadingModel == RAW_SHADING_MODEL_PBR_MET_ROUGH) {
|
if (material.info->shadingModel == RAW_SHADING_MODEL_PBR_MET_ROUGH) {
|
||||||
/**
|
/**
|
||||||
* PBR FBX Material -> PBR Met/Rough glTF.
|
* PBR FBX Material -> PBR Met/Rough glTF.
|
||||||
|
*
|
||||||
|
* METALLIC and ROUGHNESS textures are packed in G and B channels of a rough/met texture.
|
||||||
|
* Other values translate directly.
|
||||||
*/
|
*/
|
||||||
RawMetRoughMatProps* props = (RawMetRoughMatProps*)material.info.get();
|
RawMetRoughMatProps* props = (RawMetRoughMatProps*)material.info.get();
|
||||||
|
|
||||||
// diffuse and emissive are noncontroversial
|
|
||||||
baseColorTex = simpleTex(RAW_TEXTURE_USAGE_ALBEDO);
|
|
||||||
diffuseFactor = props->diffuseFactor;
|
|
||||||
emissiveFactor = props->emissiveFactor;
|
|
||||||
emissiveIntensity = props->emissiveIntensity;
|
|
||||||
|
|
||||||
// we always send the metallic/roughness factors onto the glTF generator
|
|
||||||
metallic = props->metallic;
|
|
||||||
roughness = props->roughness;
|
|
||||||
|
|
||||||
// determine if we need to generate a combined map
|
// determine if we need to generate a combined map
|
||||||
bool hasMetallicMap = material.textures[RAW_TEXTURE_USAGE_METALLIC] >= 0;
|
bool hasMetallicMap = material.textures[RAW_TEXTURE_USAGE_METALLIC] >= 0;
|
||||||
bool hasRoughnessMap = material.textures[RAW_TEXTURE_USAGE_ROUGHNESS] >= 0;
|
bool hasRoughnessMap = material.textures[RAW_TEXTURE_USAGE_ROUGHNESS] >= 0;
|
||||||
bool hasOcclusionMap = material.textures[RAW_TEXTURE_USAGE_OCCLUSION] >= 0;
|
bool hasOcclusionMap = material.textures[RAW_TEXTURE_USAGE_OCCLUSION] >= 0;
|
||||||
bool atLeastTwoMaps = hasMetallicMap ? (hasRoughnessMap || hasOcclusionMap)
|
bool atLeastTwoMaps = hasMetallicMap ? (hasRoughnessMap || hasOcclusionMap)
|
||||||
: (hasRoughnessMap && hasMetallicMap);
|
: (hasRoughnessMap && hasMetallicMap);
|
||||||
if (atLeastTwoMaps) {
|
if (!atLeastTwoMaps) {
|
||||||
// if there's at least two of metallic/roughness/occlusion, it makes sense to
|
// this handles the case of 0 or 1 maps supplied
|
||||||
// merge them: occlusion into the red channel, metallic into blue channel, and
|
aoMetRoughTex = hasMetallicMap
|
||||||
// roughness into the green.
|
? simpleTex(RAW_TEXTURE_USAGE_METALLIC)
|
||||||
|
: (hasRoughnessMap
|
||||||
|
? simpleTex(RAW_TEXTURE_USAGE_ROUGHNESS)
|
||||||
|
: (hasOcclusionMap ? simpleTex(RAW_TEXTURE_USAGE_OCCLUSION) : nullptr));
|
||||||
|
} else {
|
||||||
|
// otherwise merge occlusion into the red channel, metallic into blue channel, and
|
||||||
|
// roughness into the green, of a new combinatory texture
|
||||||
aoMetRoughTex = textureBuilder.combine(
|
aoMetRoughTex = textureBuilder.combine(
|
||||||
{
|
{
|
||||||
material.textures[RAW_TEXTURE_USAGE_OCCLUSION],
|
material.textures[RAW_TEXTURE_USAGE_OCCLUSION],
|
||||||
|
@ -289,27 +287,24 @@ ModelData* Raw2Gltf(
|
||||||
[&](const std::vector<const TextureBuilder::pixel*> pixels)
|
[&](const std::vector<const TextureBuilder::pixel*> pixels)
|
||||||
-> TextureBuilder::pixel {
|
-> TextureBuilder::pixel {
|
||||||
const float occlusion = (*pixels[0])[0];
|
const float occlusion = (*pixels[0])[0];
|
||||||
const float metallic = (*pixels[1])[0];
|
const float metallic = (*pixels[1])[0] * (hasMetallicMap ? 1 : props->metallic);
|
||||||
const float roughness = (*pixels[2])[0];
|
const float roughness =
|
||||||
|
(*pixels[2])[0] * (hasRoughnessMap ? 1 : props->roughness);
|
||||||
return {{occlusion,
|
return {{occlusion,
|
||||||
props->invertRoughnessMap ? 1.0f - roughness : roughness,
|
props->invertRoughnessMap ? 1.0f - roughness : roughness,
|
||||||
metallic,
|
metallic,
|
||||||
1}};
|
1}};
|
||||||
},
|
},
|
||||||
false);
|
false);
|
||||||
if (hasOcclusionMap) {
|
|
||||||
// will only be true if there were actual non-trivial pixels
|
|
||||||
occlusionTexture = aoMetRoughTex.get();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// this handles the case of 0 or 1 maps supplied
|
|
||||||
if (hasMetallicMap) {
|
|
||||||
aoMetRoughTex = simpleTex(RAW_TEXTURE_USAGE_METALLIC);
|
|
||||||
} else if (hasRoughnessMap) {
|
|
||||||
aoMetRoughTex = simpleTex(RAW_TEXTURE_USAGE_ROUGHNESS);
|
|
||||||
}
|
|
||||||
// else only occlusion map is possible: that check is handled further below
|
|
||||||
}
|
}
|
||||||
|
baseColorTex = simpleTex(RAW_TEXTURE_USAGE_ALBEDO);
|
||||||
|
diffuseFactor = props->diffuseFactor;
|
||||||
|
metallic = props->metallic;
|
||||||
|
roughness = props->roughness;
|
||||||
|
emissiveFactor = props->emissiveFactor;
|
||||||
|
emissiveIntensity = props->emissiveIntensity;
|
||||||
|
// this will set occlusionTexture to null, if no actual occlusion map exists
|
||||||
|
occlusionTexture = aoMetRoughTex.get();
|
||||||
} else {
|
} else {
|
||||||
/**
|
/**
|
||||||
* Traditional FBX Material -> PBR Met/Rough glTF.
|
* Traditional FBX Material -> PBR Met/Rough glTF.
|
||||||
|
@ -393,7 +388,6 @@ ModelData* Raw2Gltf(
|
||||||
|
|
||||||
khrCmnUnlitMat.reset(new KHRCmnUnlitMaterial());
|
khrCmnUnlitMat.reset(new KHRCmnUnlitMaterial());
|
||||||
}
|
}
|
||||||
// after all the special cases have had a go, check if we need to look up occlusion map
|
|
||||||
if (!occlusionTexture) {
|
if (!occlusionTexture) {
|
||||||
occlusionTexture = simpleTex(RAW_TEXTURE_USAGE_OCCLUSION).get();
|
occlusionTexture = simpleTex(RAW_TEXTURE_USAGE_OCCLUSION).get();
|
||||||
}
|
}
|
||||||
|
@ -422,8 +416,6 @@ ModelData* Raw2Gltf(
|
||||||
|
|
||||||
const RawMaterial& rawMaterial =
|
const RawMaterial& rawMaterial =
|
||||||
surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
||||||
fmt::printf(
|
|
||||||
"Seeking material of id %ls, name %s...\n", rawMaterial.id, rawMaterial.name.c_str());
|
|
||||||
const MaterialData& mData = require(materialsById, rawMaterial.id);
|
const MaterialData& mData = require(materialsById, rawMaterial.id);
|
||||||
|
|
||||||
MeshData* mesh = nullptr;
|
MeshData* mesh = nullptr;
|
||||||
|
@ -447,11 +439,11 @@ ModelData* Raw2Gltf(
|
||||||
|
|
||||||
std::shared_ptr<PrimitiveData> primitive;
|
std::shared_ptr<PrimitiveData> primitive;
|
||||||
if (options.draco.enabled) {
|
if (options.draco.enabled) {
|
||||||
int triangleCount = surfaceModel.GetTriangleCount();
|
size_t triangleCount = surfaceModel.GetTriangleCount();
|
||||||
|
|
||||||
// initialize Draco mesh with vertex index information
|
// initialize Draco mesh with vertex index information
|
||||||
auto dracoMesh(std::make_shared<draco::Mesh>());
|
auto dracoMesh(std::make_shared<draco::Mesh>());
|
||||||
dracoMesh->SetNumFaces(static_cast<size_t>(triangleCount));
|
dracoMesh->SetNumFaces(triangleCount);
|
||||||
dracoMesh->set_num_points(surfaceModel.GetVertexCount());
|
dracoMesh->set_num_points(surfaceModel.GetVertexCount());
|
||||||
|
|
||||||
for (uint32_t ii = 0; ii < triangleCount; ii++) {
|
for (uint32_t ii = 0; ii < triangleCount; ii++) {
|
||||||
|
@ -464,7 +456,7 @@ ModelData* Raw2Gltf(
|
||||||
|
|
||||||
AccessorData& indexes =
|
AccessorData& indexes =
|
||||||
*gltf->accessors.hold(new AccessorData(useLongIndices ? GLT_UINT : GLT_USHORT));
|
*gltf->accessors.hold(new AccessorData(useLongIndices ? GLT_UINT : GLT_USHORT));
|
||||||
indexes.count = 3 * triangleCount;
|
indexes.count = to_uint32(3 * triangleCount);
|
||||||
primitive.reset(new PrimitiveData(indexes, mData, dracoMesh));
|
primitive.reset(new PrimitiveData(indexes, mData, dracoMesh));
|
||||||
} else {
|
} else {
|
||||||
const AccessorData& indexes = *gltf->AddAccessorWithView(
|
const AccessorData& indexes = *gltf->AddAccessorWithView(
|
||||||
|
@ -499,11 +491,13 @@ ModelData* Raw2Gltf(
|
||||||
GLT_VEC3F,
|
GLT_VEC3F,
|
||||||
draco::GeometryAttribute::NORMAL,
|
draco::GeometryAttribute::NORMAL,
|
||||||
draco::DT_FLOAT32);
|
draco::DT_FLOAT32);
|
||||||
gltf->AddAttributeToPrimitive<Vec3f>(buffer, surfaceModel, *primitive, ATTR_NORMAL);
|
const auto _ =
|
||||||
|
gltf->AddAttributeToPrimitive<Vec3f>(buffer, surfaceModel, *primitive, ATTR_NORMAL);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_TANGENT) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_TANGENT) != 0) {
|
||||||
const AttributeDefinition<Vec4f> ATTR_TANGENT("TANGENT", &RawVertex::tangent, GLT_VEC4F);
|
const AttributeDefinition<Vec4f> ATTR_TANGENT("TANGENT", &RawVertex::tangent, GLT_VEC4F);
|
||||||
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_TANGENT);
|
const auto _ = gltf->AddAttributeToPrimitive<Vec4f>(
|
||||||
|
buffer, surfaceModel, *primitive, ATTR_TANGENT);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_COLOR) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_COLOR) != 0) {
|
||||||
const AttributeDefinition<Vec4f> ATTR_COLOR(
|
const AttributeDefinition<Vec4f> ATTR_COLOR(
|
||||||
|
@ -512,7 +506,8 @@ ModelData* Raw2Gltf(
|
||||||
GLT_VEC4F,
|
GLT_VEC4F,
|
||||||
draco::GeometryAttribute::COLOR,
|
draco::GeometryAttribute::COLOR,
|
||||||
draco::DT_FLOAT32);
|
draco::DT_FLOAT32);
|
||||||
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_COLOR);
|
const auto _ =
|
||||||
|
gltf->AddAttributeToPrimitive<Vec4f>(buffer, surfaceModel, *primitive, ATTR_COLOR);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_UV0) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_UV0) != 0) {
|
||||||
const AttributeDefinition<Vec2f> ATTR_TEXCOORD_0(
|
const AttributeDefinition<Vec2f> ATTR_TEXCOORD_0(
|
||||||
|
@ -521,7 +516,8 @@ ModelData* Raw2Gltf(
|
||||||
GLT_VEC2F,
|
GLT_VEC2F,
|
||||||
draco::GeometryAttribute::TEX_COORD,
|
draco::GeometryAttribute::TEX_COORD,
|
||||||
draco::DT_FLOAT32);
|
draco::DT_FLOAT32);
|
||||||
gltf->AddAttributeToPrimitive<Vec2f>(buffer, surfaceModel, *primitive, ATTR_TEXCOORD_0);
|
const auto _ = gltf->AddAttributeToPrimitive<Vec2f>(
|
||||||
|
buffer, surfaceModel, *primitive, ATTR_TEXCOORD_0);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_UV1) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_UV1) != 0) {
|
||||||
const AttributeDefinition<Vec2f> ATTR_TEXCOORD_1(
|
const AttributeDefinition<Vec2f> ATTR_TEXCOORD_1(
|
||||||
|
@ -530,7 +526,8 @@ ModelData* Raw2Gltf(
|
||||||
GLT_VEC2F,
|
GLT_VEC2F,
|
||||||
draco::GeometryAttribute::TEX_COORD,
|
draco::GeometryAttribute::TEX_COORD,
|
||||||
draco::DT_FLOAT32);
|
draco::DT_FLOAT32);
|
||||||
gltf->AddAttributeToPrimitive<Vec2f>(buffer, surfaceModel, *primitive, ATTR_TEXCOORD_1);
|
const auto _ = gltf->AddAttributeToPrimitive<Vec2f>(
|
||||||
|
buffer, surfaceModel, *primitive, ATTR_TEXCOORD_1);
|
||||||
}
|
}
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_JOINT_INDICES) != 0) {
|
||||||
for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) {
|
for (int i = 0; i < surfaceModel.GetGlobalWeightCount(); i += 4) {
|
||||||
|
@ -639,7 +636,7 @@ ModelData* Raw2Gltf(
|
||||||
draco::Status status = encoder.EncodeMeshToBuffer(*primitive->dracoMesh, &dracoBuffer);
|
draco::Status status = encoder.EncodeMeshToBuffer(*primitive->dracoMesh, &dracoBuffer);
|
||||||
assert(status.code() == draco::Status::OK);
|
assert(status.code() == draco::Status::OK);
|
||||||
|
|
||||||
auto view = gltf->AddRawBufferView(buffer, dracoBuffer.data(), dracoBuffer.size());
|
auto view = gltf->AddRawBufferView(buffer, dracoBuffer.data(), to_uint32(dracoBuffer.size()));
|
||||||
primitive->NoteDracoBuffer(*view);
|
primitive->NoteDracoBuffer(*view);
|
||||||
}
|
}
|
||||||
mesh->AddPrimitive(primitive);
|
mesh->AddPrimitive(primitive);
|
||||||
|
@ -741,7 +738,7 @@ ModelData* Raw2Gltf(
|
||||||
type = LightData::Type::Spot;
|
type = LightData::Type::Spot;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
gltf->lights.hold(new LightData(
|
const auto _ = gltf->lights.hold(new LightData(
|
||||||
light.name,
|
light.name,
|
||||||
type,
|
type,
|
||||||
light.color,
|
light.color,
|
||||||
|
@ -848,13 +845,13 @@ ModelData* Raw2Gltf(
|
||||||
gltfOutStream.write(glb2BinaryHeader, 8);
|
gltfOutStream.write(glb2BinaryHeader, 8);
|
||||||
|
|
||||||
// append binary buffer directly to .glb file
|
// append binary buffer directly to .glb file
|
||||||
uint32_t binaryLength = gltf->binary->size();
|
size_t binaryLength = gltf->binary->size();
|
||||||
gltfOutStream.write((const char*)&(*gltf->binary)[0], binaryLength);
|
gltfOutStream.write((const char*)&(*gltf->binary)[0], binaryLength);
|
||||||
while ((binaryLength % 4) != 0) {
|
while ((binaryLength % 4) != 0) {
|
||||||
gltfOutStream.put('\0');
|
gltfOutStream.put('\0');
|
||||||
binaryLength++;
|
binaryLength++;
|
||||||
}
|
}
|
||||||
uint32_t totalLength = (uint32_t)gltfOutStream.tellp();
|
uint32_t totalLength = to_uint32(gltfOutStream.tellp());
|
||||||
|
|
||||||
// seek back to sub-header for json chunk
|
// seek back to sub-header for json chunk
|
||||||
gltfOutStream.seekp(8);
|
gltfOutStream.seekp(8);
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -120,7 +119,7 @@ const GLType GLT_QUATF = {CT_FLOAT, 4, "VEC4"};
|
||||||
* The base of any indexed glTF entity.
|
* The base of any indexed glTF entity.
|
||||||
*/
|
*/
|
||||||
struct Holdable {
|
struct Holdable {
|
||||||
uint32_t ix;
|
uint32_t ix = UINT_MAX;
|
||||||
|
|
||||||
virtual json serialize() const = 0;
|
virtual json serialize() const = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TextureBuilder.hpp"
|
#include "TextureBuilder.hpp"
|
||||||
|
@ -49,8 +48,7 @@ std::shared_ptr<TextureData> TextureBuilder::combine(
|
||||||
if (rawTexIx >= 0) {
|
if (rawTexIx >= 0) {
|
||||||
const RawTexture& rawTex = raw.GetTexture(rawTexIx);
|
const RawTexture& rawTex = raw.GetTexture(rawTexIx);
|
||||||
const std::string& fileLoc = rawTex.fileLocation;
|
const std::string& fileLoc = rawTex.fileLocation;
|
||||||
const std::string& name =
|
const std::string& name = FileUtils::GetFileBase(FileUtils::GetFileName(fileLoc));
|
||||||
StringUtils::GetFileBaseString(StringUtils::GetFileNameString(fileLoc));
|
|
||||||
if (!fileLoc.empty()) {
|
if (!fileLoc.empty()) {
|
||||||
info.pixels = stbi_load(fileLoc.c_str(), &info.width, &info.height, &info.channels, 0);
|
info.pixels = stbi_load(fileLoc.c_str(), &info.width, &info.height, &info.channels, 0);
|
||||||
if (!info.pixels) {
|
if (!info.pixels) {
|
||||||
|
@ -142,7 +140,7 @@ std::shared_ptr<TextureData> TextureBuilder::combine(
|
||||||
ImageData* image;
|
ImageData* image;
|
||||||
if (options.outputBinary) {
|
if (options.outputBinary) {
|
||||||
const auto bufferView =
|
const auto bufferView =
|
||||||
gltf.AddRawBufferView(*gltf.defaultBuffer, imgBuffer.data(), imgBuffer.size());
|
gltf.AddRawBufferView(*gltf.defaultBuffer, imgBuffer.data(), to_uint32(imgBuffer.size()));
|
||||||
image = new ImageData(mergedName, *bufferView, png ? "image/png" : "image/jpeg");
|
image = new ImageData(mergedName, *bufferView, png ? "image/png" : "image/jpeg");
|
||||||
} else {
|
} else {
|
||||||
const std::string imageFilename = mergedFilename + (png ? ".png" : ".jpg");
|
const std::string imageFilename = mergedFilename + (png ? ".png" : ".jpg");
|
||||||
|
@ -180,20 +178,30 @@ std::shared_ptr<TextureData> TextureBuilder::simple(int rawTexIndex, const std::
|
||||||
}
|
}
|
||||||
|
|
||||||
const RawTexture& rawTexture = raw.GetTexture(rawTexIndex);
|
const RawTexture& rawTexture = raw.GetTexture(rawTexIndex);
|
||||||
const std::string textureName = StringUtils::GetFileBaseString(rawTexture.name);
|
const std::string textureName = FileUtils::GetFileBase(rawTexture.name);
|
||||||
const std::string relativeFilename = StringUtils::GetFileNameString(rawTexture.fileLocation);
|
const std::string relativeFilename = FileUtils::GetFileName(rawTexture.fileLocation);
|
||||||
|
|
||||||
ImageData* image = nullptr;
|
ImageData* image = nullptr;
|
||||||
if (options.outputBinary) {
|
if (options.outputBinary) {
|
||||||
auto bufferView = gltf.AddBufferViewForFile(*gltf.defaultBuffer, rawTexture.fileLocation);
|
auto bufferView = gltf.AddBufferViewForFile(*gltf.defaultBuffer, rawTexture.fileLocation);
|
||||||
if (bufferView) {
|
if (bufferView) {
|
||||||
std::string suffix = StringUtils::GetFileSuffixString(rawTexture.fileLocation);
|
const auto& suffix = FileUtils::GetFileSuffix(rawTexture.fileLocation);
|
||||||
image = new ImageData(relativeFilename, *bufferView, ImageUtils::suffixToMimeType(suffix));
|
std::string mimeType;
|
||||||
|
if (suffix) {
|
||||||
|
mimeType = ImageUtils::suffixToMimeType(suffix.value());
|
||||||
|
} else {
|
||||||
|
mimeType = "image/jpeg";
|
||||||
|
fmt::printf(
|
||||||
|
"Warning: Can't deduce mime type of texture '%s'; using %s.\n",
|
||||||
|
rawTexture.fileLocation,
|
||||||
|
mimeType);
|
||||||
|
}
|
||||||
|
image = new ImageData(relativeFilename, *bufferView, mimeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (!relativeFilename.empty()) {
|
} else if (!relativeFilename.empty()) {
|
||||||
image = new ImageData(relativeFilename, relativeFilename);
|
image = new ImageData(relativeFilename, relativeFilename);
|
||||||
std::string outputPath = outputFolder + StringUtils::NormalizePath(relativeFilename);
|
std::string outputPath = outputFolder + "/" + relativeFilename;
|
||||||
if (FileUtils::CopyFile(rawTexture.fileLocation, outputPath, true)) {
|
if (FileUtils::CopyFile(rawTexture.fileLocation, outputPath, true)) {
|
||||||
if (verboseOutput) {
|
if (verboseOutput) {
|
||||||
fmt::printf("Copied texture '%s' to output folder: %s\n", textureName, outputPath);
|
fmt::printf("Copied texture '%s' to output folder: %s\n", textureName, outputPath);
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AccessorData.hpp"
|
#include "AccessorData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AnimationData.hpp"
|
#include "AnimationData.hpp"
|
||||||
|
@ -24,7 +23,7 @@ void AnimationData::AddNodeChannel(
|
||||||
const AccessorData& accessor,
|
const AccessorData& accessor,
|
||||||
std::string path) {
|
std::string path) {
|
||||||
assert(channels.size() == samplers.size());
|
assert(channels.size() == samplers.size());
|
||||||
uint32_t ix = channels.size();
|
uint32_t ix = to_uint32(channels.size());
|
||||||
channels.emplace_back(channel_t(ix, node, std::move(path)));
|
channels.emplace_back(channel_t(ix, node, std::move(path)));
|
||||||
samplers.emplace_back(sampler_t(timeAccessor, accessor.ix));
|
samplers.emplace_back(sampler_t(timeAccessor, accessor.ix));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cppcodec/base64_default_rfc4648.hpp>
|
#include <cppcodec/base64_default_rfc4648.hpp>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "BufferViewData.hpp"
|
#include "BufferViewData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CameraData.hpp"
|
#include "CameraData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ImageData.hpp"
|
#include "ImageData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "LightData.hpp"
|
#include "LightData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MaterialData.hpp"
|
#include "MaterialData.hpp"
|
||||||
|
@ -59,13 +58,15 @@ void to_json(json& j, const PBRMetallicRoughness& d) {
|
||||||
if (d.baseColorFactor.LengthSquared() > 0) {
|
if (d.baseColorFactor.LengthSquared() > 0) {
|
||||||
j["baseColorFactor"] = toStdVec(d.baseColorFactor);
|
j["baseColorFactor"] = toStdVec(d.baseColorFactor);
|
||||||
}
|
}
|
||||||
// we always copy metallic/roughness straight to the glTF:
|
|
||||||
// - if there's a texture, they're linear multiplier
|
|
||||||
// - if there's no texture, they're constants
|
|
||||||
j["metallicFactor"] = d.metallic;
|
|
||||||
j["roughnessFactor"] = d.roughness;
|
|
||||||
if (d.metRoughTexture != nullptr) {
|
if (d.metRoughTexture != nullptr) {
|
||||||
j["metallicRoughnessTexture"] = *d.metRoughTexture;
|
j["metallicRoughnessTexture"] = *d.metRoughTexture;
|
||||||
|
// if a texture is provided, throw away metallic/roughness values
|
||||||
|
j["roughnessFactor"] = 1.0f;
|
||||||
|
j["metallicFactor"] = 1.0f;
|
||||||
|
} else {
|
||||||
|
// without a texture, however, use metallic/roughness as constants
|
||||||
|
j["metallicFactor"] = d.metallic;
|
||||||
|
j["roughnessFactor"] = d.roughness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MeshData.hpp"
|
#include "MeshData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "NodeData.hpp"
|
#include "NodeData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PrimitiveData.hpp"
|
#include "PrimitiveData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -49,7 +48,7 @@ struct PrimitiveData {
|
||||||
componentCount * draco::DataTypeLength(attribute.dracoComponentType),
|
componentCount * draco::DataTypeLength(attribute.dracoComponentType),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
const int dracoAttId = dracoMesh->AddAttribute(att, true, attribArr.size());
|
const int dracoAttId = dracoMesh->AddAttribute(att, true, to_uint32(attribArr.size()));
|
||||||
draco::PointAttribute* attPtr = dracoMesh->attribute(dracoAttId);
|
draco::PointAttribute* attPtr = dracoMesh->attribute(dracoAttId);
|
||||||
|
|
||||||
std::vector<uint8_t> buf(sizeof(T));
|
std::vector<uint8_t> buf(sizeof(T));
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SceneData.hpp"
|
#include "SceneData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SkinData.hpp"
|
#include "SkinData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TextureData.hpp"
|
#include "TextureData.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <fbxsdk.h>
|
#include <fbxsdk.h>
|
||||||
|
|
||||||
#include <mathfu/matrix.h>
|
#include <mathfu/matrix.h>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "RawModel.hpp"
|
#include "RawModel.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,180 +1,55 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "File_Utils.hpp"
|
#include "File_Utils.hpp"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#define _getcwd getcwd
|
|
||||||
#define _mkdir(a) mkdir(a, 0777)
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
#include <direct.h>
|
|
||||||
#include <process.h>
|
|
||||||
#else
|
|
||||||
#include <direct.h>
|
|
||||||
#include <process.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "FBX2glTF.h"
|
#include "FBX2glTF.h"
|
||||||
#include "String_Utils.hpp"
|
#include "String_Utils.hpp"
|
||||||
|
|
||||||
namespace FileUtils {
|
namespace FileUtils {
|
||||||
|
|
||||||
std::string GetCurrentFolder() {
|
std::vector<std::string> ListFolderFiles(
|
||||||
char cwd[StringUtils::MAX_PATH_LENGTH];
|
std::string folder,
|
||||||
if (!_getcwd(cwd, sizeof(cwd))) {
|
const std::set<std::string>& matchExtensions) {
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
cwd[sizeof(cwd) - 1] = '\0';
|
|
||||||
StringUtils::GetCleanPath(cwd, cwd, StringUtils::PATH_UNIX);
|
|
||||||
const size_t length = strlen(cwd);
|
|
||||||
if (cwd[length - 1] != '/' && length < StringUtils::MAX_PATH_LENGTH - 1) {
|
|
||||||
cwd[length + 0] = '/';
|
|
||||||
cwd[length + 1] = '\0';
|
|
||||||
}
|
|
||||||
return std::string(cwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileExists(const std::string& filePath) {
|
|
||||||
std::ifstream stream(filePath);
|
|
||||||
return stream.good();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FolderExists(const std::string& folderPath) {
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
DIR* dir = opendir(folderPath.c_str());
|
|
||||||
if (dir) {
|
|
||||||
closedir(dir);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
const DWORD ftyp = GetFileAttributesA(folderPath.c_str());
|
|
||||||
if (ftyp == INVALID_FILE_ATTRIBUTES) {
|
|
||||||
return false; // bad path
|
|
||||||
}
|
|
||||||
return (ftyp & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MatchExtension(const char* fileExtension, const char* matchExtensions) {
|
|
||||||
if (matchExtensions[0] == '\0') {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (fileExtension[0] == '.') {
|
|
||||||
fileExtension++;
|
|
||||||
}
|
|
||||||
for (const char* end = matchExtensions; end[0] != '\0';) {
|
|
||||||
for (; end[0] == ';'; end++) {
|
|
||||||
}
|
|
||||||
const char* ext = end;
|
|
||||||
for (; end[0] != ';' && end[0] != '\0'; end++) {
|
|
||||||
}
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
if (strncasecmp(fileExtension, ext, end - ext) == 0)
|
|
||||||
#else
|
|
||||||
if (_strnicmp(fileExtension, ext, end - ext) == 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> ListFolderFiles(const char* folder, const char* matchExtensions) {
|
|
||||||
std::vector<std::string> fileList;
|
std::vector<std::string> fileList;
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
if (folder.empty()) {
|
||||||
DIR* dir = opendir(strlen(folder) > 0 ? folder : ".");
|
folder = ".";
|
||||||
if (dir != nullptr) {
|
}
|
||||||
for (;;) {
|
for (const auto& entry : boost::filesystem::directory_iterator(folder)) {
|
||||||
struct dirent* dp = readdir(dir);
|
const auto& suffix = FileUtils::GetFileSuffix(entry.path().string());
|
||||||
if (dp == nullptr) {
|
if (suffix.has_value()) {
|
||||||
break;
|
const auto& suffix_str = StringUtils::ToLower(suffix.value());
|
||||||
|
if (matchExtensions.find(suffix_str) != matchExtensions.end()) {
|
||||||
|
fileList.push_back(entry.path().filename().string());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp->d_type == DT_DIR) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* fileName = dp->d_name;
|
|
||||||
const char* fileExt = strrchr(fileName, '.');
|
|
||||||
|
|
||||||
if (!fileExt || !MatchExtension(fileExt, matchExtensions)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileList.emplace_back(fileName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closedir(dir);
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
std::string pathStr = folder;
|
|
||||||
pathStr += "*";
|
|
||||||
|
|
||||||
WIN32_FIND_DATA FindFileData;
|
|
||||||
HANDLE hFind = FindFirstFile(pathStr.c_str(), &FindFileData);
|
|
||||||
if (hFind != INVALID_HANDLE_VALUE) {
|
|
||||||
do {
|
|
||||||
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
|
|
||||||
std::string fileName = FindFileData.cFileName;
|
|
||||||
std::string::size_type extPos = fileName.rfind('.');
|
|
||||||
if (extPos != std::string::npos &&
|
|
||||||
MatchExtension(fileName.substr(extPos + 1).c_str(), matchExtensions)) {
|
|
||||||
fileList.push_back(fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (FindNextFile(hFind, &FindFileData));
|
|
||||||
|
|
||||||
FindClose(hFind);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return fileList;
|
return fileList;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CreatePath(const char* path) {
|
bool CreatePath(const std::string path) {
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
const auto& parent = boost::filesystem::path(path).parent_path();
|
||||||
StringUtils::PathSeparator separator = StringUtils::PATH_UNIX;
|
if (parent.empty()) {
|
||||||
#else
|
// this is either CWD or boost::filesystem root; either way it exists
|
||||||
StringUtils::PathSeparator separator = StringUtils::PATH_WIN;
|
return true;
|
||||||
#endif
|
|
||||||
std::string folder = StringUtils::GetFolderString(path);
|
|
||||||
std::string clean = StringUtils::GetCleanPathString(folder, separator);
|
|
||||||
std::string build = clean;
|
|
||||||
for (int i = 0; i < clean.length(); i++) {
|
|
||||||
if (clean[i] == separator && i > 0) {
|
|
||||||
build[i] = '\0';
|
|
||||||
if (i > 1 || build[1] != ':') {
|
|
||||||
if (_mkdir(build.c_str()) != 0 && errno != EEXIST) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build[i] = clean[i];
|
|
||||||
}
|
}
|
||||||
return true;
|
if (boost::filesystem::exists(parent)) {
|
||||||
|
return boost::filesystem::is_directory(parent);
|
||||||
|
}
|
||||||
|
return boost::filesystem::create_directory(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CopyFile(const std::string& srcFilename, const std::string& dstFilename, bool createPath) {
|
bool CopyFile(const std::string& srcFilename, const std::string& dstFilename, bool createPath) {
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
namespace FileUtils {
|
namespace FileUtils {
|
||||||
|
|
||||||
std::string GetCurrentFolder();
|
std::string GetCurrentFolder();
|
||||||
|
@ -19,13 +22,51 @@ std::string GetCurrentFolder();
|
||||||
bool FileExists(const std::string& folderPath);
|
bool FileExists(const std::string& folderPath);
|
||||||
bool FolderExists(const std::string& folderPath);
|
bool FolderExists(const std::string& folderPath);
|
||||||
|
|
||||||
bool MatchExtension(const char* fileExtension, const char* matchExtensions);
|
std::vector<std::string> ListFolderFiles(
|
||||||
std::vector<std::string> ListFolderFiles(const char* folder, const char* matchExtensions);
|
const std::string folder,
|
||||||
|
const std::set<std::string>& matchExtensions);
|
||||||
|
|
||||||
bool CreatePath(const char* path);
|
bool CreatePath(std::string path);
|
||||||
|
|
||||||
bool CopyFile(
|
bool CopyFile(
|
||||||
const std::string& srcFilename,
|
const std::string& srcFilename,
|
||||||
const std::string& dstFilename,
|
const std::string& dstFilename,
|
||||||
bool createPath = false);
|
bool createPath = false);
|
||||||
|
|
||||||
|
inline std::string GetAbsolutePath(const std::string& filePath) {
|
||||||
|
return boost::filesystem::absolute(filePath).string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string GetCurrentFolder() {
|
||||||
|
return boost::filesystem::current_path().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool FileExists(const std::string& filePath) {
|
||||||
|
return boost::filesystem::exists(filePath) && boost::filesystem::is_regular_file(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool FolderExists(const std::string& folderPath) {
|
||||||
|
return boost::filesystem::exists(folderPath) && boost::filesystem::is_directory(folderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string getFolder(const std::string& path) {
|
||||||
|
return boost::filesystem::path(path).parent_path().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string GetFileName(const std::string& path) {
|
||||||
|
return boost::filesystem::path(path).filename().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string GetFileBase(const std::string& path) {
|
||||||
|
return boost::filesystem::path(path).stem().string();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline boost::optional<std::string> GetFileSuffix(const std::string& path) {
|
||||||
|
const auto& extension = boost::filesystem::path(path).extension();
|
||||||
|
if (extension.empty()) {
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
return extension.string().substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace FileUtils
|
} // namespace FileUtils
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Image_Utils.hpp"
|
#include "Image_Utils.hpp"
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "String_Utils.hpp"
|
|
||||||
|
|
||||||
namespace StringUtils {
|
|
||||||
|
|
||||||
PathSeparator operator!(const PathSeparator& s) {
|
|
||||||
return (s == PATH_WIN) ? PATH_UNIX : PATH_WIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
PathSeparator GetPathSeparator() {
|
|
||||||
#if defined(__unix__) || defined(__APPLE__)
|
|
||||||
return PATH_UNIX;
|
|
||||||
#else
|
|
||||||
return PATH_WIN;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
const std::string NormalizePath(const std::string& path) {
|
|
||||||
PathSeparator separator = GetPathSeparator();
|
|
||||||
char replace;
|
|
||||||
if (separator == PATH_WIN) {
|
|
||||||
replace = PATH_UNIX;
|
|
||||||
} else {
|
|
||||||
replace = PATH_WIN;
|
|
||||||
}
|
|
||||||
std::string normalizedPath = path;
|
|
||||||
for (size_t s = normalizedPath.find(replace, 0); s != std::string::npos;
|
|
||||||
s = normalizedPath.find(replace, s)) {
|
|
||||||
normalizedPath[s] = separator;
|
|
||||||
}
|
|
||||||
return normalizedPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetFolderString(const std::string& path) {
|
|
||||||
size_t s = path.rfind(PATH_WIN);
|
|
||||||
s = (s != std::string::npos) ? s : path.rfind(PATH_UNIX);
|
|
||||||
return path.substr(0, s + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetCleanPathString(const std::string& path, const PathSeparator separator) {
|
|
||||||
std::string cleanPath = path;
|
|
||||||
for (size_t s = cleanPath.find(!separator, 0); s != std::string::npos;
|
|
||||||
s = cleanPath.find(!separator, s)) {
|
|
||||||
cleanPath[s] = separator;
|
|
||||||
}
|
|
||||||
return cleanPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetFileNameString(const std::string& path) {
|
|
||||||
size_t s = path.rfind(PATH_WIN);
|
|
||||||
s = (s != std::string::npos) ? s : path.rfind(PATH_UNIX);
|
|
||||||
return path.substr(s + 1, std::string::npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetFileBaseString(const std::string& path) {
|
|
||||||
const std::string fileName = GetFileNameString(path);
|
|
||||||
return fileName.substr(0, fileName.rfind('.')).c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string GetFileSuffixString(const std::string& path) {
|
|
||||||
const std::string fileName = GetFileNameString(path);
|
|
||||||
size_t pos = fileName.rfind('.');
|
|
||||||
if (pos == std::string::npos) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
return fileName.substr(++pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CompareNoCase(const std::string& s1, const std::string& s2) {
|
|
||||||
return strncasecmp(s1.c_str(), s2.c_str(), MAX_PATH_LENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace StringUtils
|
|
|
@ -1,14 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-present, Facebook, Inc.
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This source code is licensed under the BSD-style license found in the
|
* This source code is licensed under the BSD-style license found in the
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
* LICENSE file in the root directory of this source tree.
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cctype>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
@ -16,39 +17,17 @@
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define strncasecmp _strnicmp
|
#define strncasecmp _strnicmp
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace StringUtils {
|
namespace StringUtils {
|
||||||
|
|
||||||
static const unsigned int MAX_PATH_LENGTH = 1024;
|
inline std::string ToLower(std::string s) {
|
||||||
|
std::transform(s.begin(), s.end(), s.begin(), [](uint8_t c) { return std::tolower(c); });
|
||||||
enum PathSeparator { PATH_WIN = '\\', PATH_UNIX = '/' };
|
return s;
|
||||||
|
|
||||||
PathSeparator operator!(const PathSeparator& s);
|
|
||||||
|
|
||||||
PathSeparator GetPathSeparator();
|
|
||||||
const std::string NormalizePath(const std::string& path);
|
|
||||||
|
|
||||||
const std::string GetCleanPathString(
|
|
||||||
const std::string& path,
|
|
||||||
const PathSeparator separator = PATH_WIN);
|
|
||||||
|
|
||||||
template <size_t size>
|
|
||||||
void GetCleanPath(char (&dest)[size], const char* path, const PathSeparator separator = PATH_WIN) {
|
|
||||||
size_t len = size - 1;
|
|
||||||
strncpy(dest, path, len);
|
|
||||||
char* destPtr = dest;
|
|
||||||
while ((destPtr = strchr(destPtr, !separator)) != nullptr) {
|
|
||||||
*destPtr = separator;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string GetFolderString(const std::string& path);
|
inline int CompareNoCase(const std::string& s1, const std::string& s2) {
|
||||||
const std::string GetFileNameString(const std::string& path);
|
return strncasecmp(s1.c_str(), s2.c_str(), std::max(s1.length(), s2.length()));
|
||||||
const std::string GetFileBaseString(const std::string& path);
|
}
|
||||||
const std::string GetFileSuffixString(const std::string& path);
|
|
||||||
|
|
||||||
int CompareNoCase(const std::string& s1, const std::string& s2);
|
|
||||||
|
|
||||||
} // namespace StringUtils
|
} // namespace StringUtils
|
||||||
|
|
Loading…
Reference in New Issue