Merge remote-tracking branch 'upstream/master' into feature/collada-up_axis-api-improvements
commit
100fa76a90
|
@ -13,3 +13,10 @@ CHANGES text eol=lf
|
||||||
CREDITS text eol=lf
|
CREDITS text eol=lf
|
||||||
LICENSE text eol=lf
|
LICENSE text eol=lf
|
||||||
Readme.md text eol=lf
|
Readme.md text eol=lf
|
||||||
|
# make sure that repo-specific settings (.gitignore, CI-setup,...)
|
||||||
|
# are excluded from the source-package generated via 'git archive'
|
||||||
|
.git* export-ignore
|
||||||
|
/.travis* export-ignore
|
||||||
|
/.coveralls* export-ignore
|
||||||
|
appveyor.yml export-ignore
|
||||||
|
|
||||||
|
|
32
.travis.sh
32
.travis.sh
|
@ -1,6 +1,36 @@
|
||||||
function generate()
|
function generate()
|
||||||
{
|
{
|
||||||
cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS
|
OPTIONS="-DASSIMP_WERROR=ON"
|
||||||
|
|
||||||
|
if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
|
||||||
|
else
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SHARED_BUILD" = "ON" ] ; then
|
||||||
|
OPTIONS="$OPTIONS -DBUILD_SHARED_LIBS=ON"
|
||||||
|
else
|
||||||
|
OPTIONS="$OPTIONS -DBUILD_SHARED_LIBS=OFF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ENABLE_COVERALLS" = "ON" ] ; then
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_COVERALLS=ON"
|
||||||
|
else
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_COVERALLS=OFF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ASAN" = "ON" ] ; then
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_ASAN=ON"
|
||||||
|
else
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_ASAN=OFF"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$UBSAN" = "ON" ] ; then
|
||||||
|
OPTIONS="$OPTIONS -DASSIMP_UBSAN=ON"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmake -G "Unix Makefiles" $OPTIONS
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ $ANDROID ]; then
|
if [ $ANDROID ]; then
|
||||||
|
|
47
.travis.yml
47
.travis.yml
|
@ -1,9 +1,19 @@
|
||||||
sudo: required
|
sudo: required
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
|
cache: ccache
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
|
||||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install cmake python3 homebrew/x11/freeglut; fi
|
- 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||||
|
if brew ls --versions cmake > /dev/null; then
|
||||||
|
echo cmake already installed.;
|
||||||
|
else
|
||||||
|
brew install cmake;
|
||||||
|
fi;
|
||||||
|
brew install python3;
|
||||||
|
brew install homebrew/x11/freeglut;
|
||||||
|
fi'
|
||||||
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
|
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
|
||||||
# install latest LCOV (1.9 was failing)
|
# install latest LCOV (1.9 was failing)
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
|
||||||
|
@ -12,22 +22,36 @@ branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
osx_image: xcode8.3
|
os:
|
||||||
|
- linux
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
# COVERITY_SCAN_TOKEN
|
# COVERITY_SCAN_TOKEN
|
||||||
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
||||||
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
||||||
matrix:
|
|
||||||
- LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON
|
|
||||||
- LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF
|
|
||||||
- LINUX=1 SHARED_BUILD=ON ENABLE_COVERALLS=OFF
|
|
||||||
- LINUX=1 SHARED_BUILD=OFF ENABLE_COVERALLS=OFF
|
|
||||||
|
|
||||||
compiler:
|
matrix:
|
||||||
- gcc
|
include:
|
||||||
- clang
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env: SHARED_BUILD=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
env: ASAN=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
env: UBSAN=ON
|
||||||
|
- os: linux
|
||||||
|
compiler: clang
|
||||||
|
env: SHARED_BUILD=ON
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
||||||
|
@ -40,9 +64,6 @@ script:
|
||||||
- export COVERALLS_SERVICE_NAME=travis-ci
|
- export COVERALLS_SERVICE_NAME=travis-ci
|
||||||
- export COVERALLS_REPO_TOKEN=abc12345
|
- export COVERALLS_REPO_TOKEN=abc12345
|
||||||
- . ./.travis.sh
|
- . ./.travis.sh
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi
|
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi
|
||||||
|
|
12
CHANGES
12
CHANGES
|
@ -1,6 +1,18 @@
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
4.0.1 (2017-07-28)
|
||||||
|
- FIXES/HOUSEKEEPING:
|
||||||
|
- fix version test.
|
||||||
|
- Not compiling when using ASSIMP_DOUBLE_PRECISION
|
||||||
|
- Added support for python3
|
||||||
|
- Check if cmake is installed with brew
|
||||||
|
- Low performance in OptimizeMeshesProcess::ProcessNode with huge numbers of meshes
|
||||||
|
- Elapsed seconds not shown correctly
|
||||||
|
- StreamReader: fix out-of-range exception
|
||||||
|
- PPdPmdParser: fix compilation for clang
|
||||||
|
|
||||||
|
|
||||||
4.0.0 (2017-07-18)
|
4.0.0 (2017-07-18)
|
||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
|
|
133
CMakeLists.txt
133
CMakeLists.txt
|
@ -34,7 +34,7 @@
|
||||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
|
SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
|
||||||
cmake_minimum_required( VERSION 2.8 )
|
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||||
PROJECT( Assimp )
|
PROJECT( Assimp )
|
||||||
|
|
||||||
# All supported options ###############################################
|
# All supported options ###############################################
|
||||||
|
@ -62,11 +62,11 @@ OPTION( ASSIMP_BUILD_ZLIB
|
||||||
"Build your own zlib"
|
"Build your own zlib"
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
option( ASSIMP_BUILD_ASSIMP_TOOLS
|
OPTION( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
"If the supplementary tools for Assimp are built in addition to the library."
|
"If the supplementary tools for Assimp are built in addition to the library."
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
option ( ASSIMP_BUILD_SAMPLES
|
OPTION ( ASSIMP_BUILD_SAMPLES
|
||||||
"If the official samples are built as well (needs Glut)."
|
"If the official samples are built as well (needs Glut)."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
@ -75,10 +75,22 @@ OPTION ( ASSIMP_BUILD_TESTS
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
OPTION ( ASSIMP_COVERALLS
|
OPTION ( ASSIMP_COVERALLS
|
||||||
"Eańable this to measure test coverage."
|
"Enable this to measure test coverage."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
option ( SYSTEM_IRRXML
|
OPTION ( ASSIMP_WERROR
|
||||||
|
"Treat warnings as errors."
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION ( ASSIMP_ASAN
|
||||||
|
"Enable AddressSanitizer."
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION ( ASSIMP_UBSAN
|
||||||
|
"Enable Undefined Behavior sanitizer."
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION ( SYSTEM_IRRXML
|
||||||
"Use system installed Irrlicht/IrrXML library."
|
"Use system installed Irrlicht/IrrXML library."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
@ -88,11 +100,11 @@ OPTION ( BUILD_DOCS
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
add_definitions( -DWIN32_LEAN_AND_MEAN )
|
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
SET (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||||
OPTION( ASSIMP_INSTALL_PDB
|
OPTION( ASSIMP_INSTALL_PDB
|
||||||
"Install MSVC debug files."
|
"Install MSVC debug files."
|
||||||
ON
|
ON
|
||||||
|
@ -100,21 +112,24 @@ IF(MSVC)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|
||||||
IF(NOT BUILD_SHARED_LIBS)
|
IF(NOT BUILD_SHARED_LIBS)
|
||||||
|
MESSAGE(STATUS "Shared libraries disabled")
|
||||||
SET(LINK_SEARCH_START_STATIC TRUE)
|
SET(LINK_SEARCH_START_STATIC TRUE)
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(STATUS "Shared libraries enabled")
|
||||||
ENDIF(NOT BUILD_SHARED_LIBS)
|
ENDIF(NOT BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
# Define here the needed parameters
|
# Define here the needed parameters
|
||||||
SET (ASSIMP_VERSION_MAJOR 4)
|
SET (ASSIMP_VERSION_MAJOR 4)
|
||||||
SET (ASSIMP_VERSION_MINOR 0)
|
SET (ASSIMP_VERSION_MINOR 0)
|
||||||
SET (ASSIMP_VERSION_PATCH 0) # subversion revision?
|
SET (ASSIMP_VERSION_PATCH 1)
|
||||||
SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
||||||
SET (ASSIMP_SOVERSION 4)
|
SET (ASSIMP_SOVERSION 4)
|
||||||
SET (PROJECT_VERSION "${ASSIMP_VERSION}")
|
SET (PROJECT_VERSION "${ASSIMP_VERSION}")
|
||||||
|
|
||||||
SET(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
|
||||||
|
|
||||||
# Needed for openddl_parser config, no use of c++11 at this moment
|
# Needed for openddl_parser config, no use of c++11 at this moment
|
||||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
ADD_DEFINITIONS( -DOPENDDL_NO_USE_CPP11 )
|
||||||
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
|
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
|
||||||
|
|
||||||
# Get the current working branch
|
# Get the current working branch
|
||||||
|
@ -143,25 +158,19 @@ IF(ASSIMP_DOUBLE_PRECISION)
|
||||||
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||||
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
||||||
|
|
||||||
# Check for OpenMP support
|
CONFIGURE_FILE(
|
||||||
find_package(OpenMP)
|
|
||||||
if (OPENMP_FOUND)
|
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
configure_file(
|
|
||||||
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file(
|
CONFIGURE_FILE(
|
||||||
${CMAKE_CURRENT_LIST_DIR}/include/assimp/config.h.in
|
${CMAKE_CURRENT_LIST_DIR}/include/assimp/config.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/include/assimp/config.h
|
${CMAKE_CURRENT_BINARY_DIR}/include/assimp/config.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
INCLUDE_DIRECTORIES(
|
||||||
./
|
./
|
||||||
|
include
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/include
|
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||||
)
|
)
|
||||||
|
@ -179,7 +188,7 @@ IF( UNIX )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Use GNUInstallDirs for Unix predefined directories
|
# Use GNUInstallDirs for Unix predefined directories
|
||||||
include(GNUInstallDirs)
|
INCLUDE(GNUInstallDirs)
|
||||||
ENDIF( UNIX )
|
ENDIF( UNIX )
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,20 +201,48 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||||
ELSEIF(MSVC)
|
ELSEIF(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
add_compile_options(/MP)
|
add_compile_options(/MP)
|
||||||
|
|
||||||
|
# disable "elements of array '' will be default initialized" warning on MSVC2013
|
||||||
|
IF(MSVC12)
|
||||||
|
add_compile_options(/wd4351)
|
||||||
|
ENDIF()
|
||||||
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -pedantic -std=c++11" )
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||||
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
||||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
|
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" )
|
||||||
add_definitions( -U__STRICT_ANSI__ )
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||||
|
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
if (ASSIMP_COVERALLS)
|
if (ASSIMP_COVERALLS)
|
||||||
include(Coveralls)
|
MESSAGE(STATUS "Coveralls enabled")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
INCLUDE(Coveralls)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES( include )
|
if (ASSIMP_WERROR)
|
||||||
|
MESSAGE(STATUS "Treating warnings as errors")
|
||||||
|
IF (MSVC)
|
||||||
|
add_compile_options(/WX)
|
||||||
|
ELSE()
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
||||||
|
ENDIF()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (ASSIMP_ASAN)
|
||||||
|
MESSAGE(STATUS "AddressSanitizer enabled")
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (ASSIMP_UBSAN)
|
||||||
|
MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
|
||||||
|
endif()
|
||||||
|
|
||||||
INCLUDE (FindPkgMacros)
|
INCLUDE (FindPkgMacros)
|
||||||
INCLUDE (PrecompiledHeader)
|
INCLUDE (PrecompiledHeader)
|
||||||
|
@ -237,13 +274,13 @@ ENDIF()
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall)
|
||||||
# add make uninstall capability
|
# add make uninstall capability
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||||
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# cmake configuration files
|
# cmake configuration files
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
|
|
||||||
FIND_PACKAGE( DirectX )
|
FIND_PACKAGE( DirectX )
|
||||||
|
@ -265,9 +302,9 @@ ENDIF( NOT ASSIMP_BUILD_ZLIB )
|
||||||
|
|
||||||
IF( NOT ZLIB_FOUND )
|
IF( NOT ZLIB_FOUND )
|
||||||
message(STATUS "compiling zlib from souces")
|
message(STATUS "compiling zlib from souces")
|
||||||
include(CheckIncludeFile)
|
INCLUDE(CheckIncludeFile)
|
||||||
include(CheckTypeSize)
|
INCLUDE(CheckTypeSize)
|
||||||
include(CheckFunctionExists)
|
INCLUDE(CheckFunctionExists)
|
||||||
# compile from sources
|
# compile from sources
|
||||||
add_subdirectory(contrib/zlib)
|
add_subdirectory(contrib/zlib)
|
||||||
SET(ZLIB_FOUND 1)
|
SET(ZLIB_FOUND 1)
|
||||||
|
@ -472,13 +509,25 @@ if(WIN32)
|
||||||
|
|
||||||
if(MSVC12 OR MSVC14)
|
if(MSVC12 OR MSVC14)
|
||||||
add_custom_target(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)
|
add_custom_target(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
|
IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
|
||||||
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
|
||||||
|
ELSE()
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
|
||||||
|
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
|
||||||
|
ENDIF()
|
||||||
ENDIF(MSVC12 OR MSVC14)
|
ENDIF(MSVC12 OR MSVC14)
|
||||||
ENDIF (WIN32)
|
ENDIF (WIN32)
|
||||||
|
|
91
Readme.md
91
Readme.md
|
@ -1,5 +1,6 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
==================================
|
==================================
|
||||||
|
A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
|
||||||
### Current build status ###
|
### Current build status ###
|
||||||
[](https://travis-ci.org/assimp/assimp)
|
[](https://travis-ci.org/assimp/assimp)
|
||||||
[](https://ci.appveyor.com/project/kimkulling/assimp)
|
[](https://ci.appveyor.com/project/kimkulling/assimp)
|
||||||
|
@ -7,7 +8,6 @@ Open Asset Import Library (assimp)
|
||||||
<img alt="Coverity Scan Build Status"
|
<img alt="Coverity Scan Build Status"
|
||||||
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
||||||
</a>
|
</a>
|
||||||
<span class="badge-patreon"><a href="https://www.patreon.com/assimp" title="Donate to this project using Patreon"><img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" /></a></span>
|
|
||||||
[](https://coveralls.io/github/assimp/assimp?branch=master)
|
[](https://coveralls.io/github/assimp/assimp?branch=master)
|
||||||
[](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
<br>
|
<br>
|
||||||
|
@ -18,6 +18,11 @@ Additionally, assimp features various __mesh post processing tools__: normals an
|
||||||
|
|
||||||
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
|
||||||
|
|
||||||
|
Monthly donations via Patreon:
|
||||||
|
<br>[](http://www.patreon.com/assimp)
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
One-off donations via PayPal:
|
One-off donations via PayPal:
|
||||||
<br>[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
|
<br>[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
|
||||||
|
|
||||||
|
@ -29,50 +34,67 @@ Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
||||||
|
|
||||||
A full list [is here](http://assimp.org/main_features_formats.html).
|
A full list [is here](http://assimp.org/main_features_formats.html).
|
||||||
__Importers__:
|
__Importers__:
|
||||||
|
- 3D
|
||||||
- 3DS
|
- 3DS
|
||||||
- BLEND (Blender)
|
- 3MF
|
||||||
- DAE/Collada
|
- AC
|
||||||
- FBX
|
- AC3D
|
||||||
- IFC-STEP
|
- ACC
|
||||||
|
- AMJ
|
||||||
- ASE
|
- ASE
|
||||||
|
- ASK
|
||||||
|
- B3D;
|
||||||
|
- BLEND (Blender)
|
||||||
|
- BVH
|
||||||
|
- COB
|
||||||
|
- CMS
|
||||||
|
- DAE/Collada
|
||||||
- DXF
|
- DXF
|
||||||
- HMP
|
- ENFF
|
||||||
|
- FBX
|
||||||
|
- glTF 1.0 + GLB
|
||||||
|
- glTF 2.0
|
||||||
|
- HMB
|
||||||
|
- IFC-STEP
|
||||||
|
- IRR / IRRMESH
|
||||||
|
- LWO
|
||||||
|
- LWS
|
||||||
|
- LXO
|
||||||
- MD2
|
- MD2
|
||||||
- MD3
|
- MD3
|
||||||
- MD5
|
- MD5
|
||||||
- MDC
|
- MDC
|
||||||
- MDL
|
- MDL
|
||||||
- NFF
|
- MESH / MESH.XML
|
||||||
- PLY
|
- MOT
|
||||||
- STL
|
|
||||||
- X
|
|
||||||
- OBJ
|
|
||||||
- OpenGEX
|
|
||||||
- SMD
|
|
||||||
- LWO
|
|
||||||
- LXO
|
|
||||||
- LWS
|
|
||||||
- TER
|
|
||||||
- AC3D
|
|
||||||
- MS3D
|
- MS3D
|
||||||
- COB
|
|
||||||
- Q3BSP
|
|
||||||
- XGL
|
|
||||||
- CSM
|
|
||||||
- BVH
|
|
||||||
- B3D
|
|
||||||
- NDO
|
- NDO
|
||||||
- Ogre Binary
|
- NFF
|
||||||
- Ogre XML
|
- OBJ
|
||||||
- Q3D
|
- OFF
|
||||||
- ASSBIN (Assimp custom format)
|
- OGEX
|
||||||
- glTF (partial)
|
- PLY
|
||||||
- 3MF
|
- PMX
|
||||||
|
- PRJ
|
||||||
|
- Q3O
|
||||||
|
- Q3S
|
||||||
|
- RAW
|
||||||
|
- SCN
|
||||||
|
- SIB
|
||||||
|
- SMD
|
||||||
|
- STL
|
||||||
|
- STP
|
||||||
|
- TER
|
||||||
|
- UC
|
||||||
|
- VTA
|
||||||
|
- X
|
||||||
|
- X3D
|
||||||
|
- XGL
|
||||||
|
- ZGL
|
||||||
|
|
||||||
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
||||||
|
|
||||||
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
- C4D (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange)
|
||||||
|
|
||||||
__Exporters__:
|
__Exporters__:
|
||||||
|
|
||||||
|
@ -85,7 +107,8 @@ __Exporters__:
|
||||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||||
- ASSBIN
|
- ASSBIN
|
||||||
- STEP
|
- STEP
|
||||||
- glTF (partial)
|
- glTF 1.0 (partial)
|
||||||
|
- glTF 2.0 (partial)
|
||||||
|
|
||||||
### Building ###
|
### Building ###
|
||||||
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
||||||
|
@ -96,6 +119,8 @@ Take a look into the `INSTALL` file. Our build system is CMake, if you used CMak
|
||||||
* [.NET](port/AssimpNET/Readme.md)
|
* [.NET](port/AssimpNET/Readme.md)
|
||||||
* [Pascal](port/AssimpPascal/Readme.md)
|
* [Pascal](port/AssimpPascal/Readme.md)
|
||||||
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
||||||
|
* [Unity 3d Plugin] (https://www.assetstore.unity3d.com/en/#!/content/91777)
|
||||||
|
* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (currently supported obj, ply, stl, ~collada)
|
||||||
|
|
||||||
### Other tools ###
|
### Other tools ###
|
||||||
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
||||||
|
|
57
appveyor.yml
57
appveyor.yml
|
@ -10,32 +10,53 @@ branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
|
image:
|
||||||
|
- Visual Studio 2013
|
||||||
|
- Visual Studio 2015
|
||||||
|
- Visual Studio 2017
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
- x86
|
- Win32
|
||||||
- x64
|
- x64
|
||||||
|
|
||||||
configuration:
|
configuration: Release
|
||||||
- 14 2015
|
|
||||||
- 12 2013
|
|
||||||
#- MinGW
|
|
||||||
#- 10 2010 # only works for x86
|
|
||||||
|
|
||||||
init:
|
|
||||||
- if "%platform%" EQU "x64" ( for %%a in (2008 2010 MinGW) do ( if "%Configuration%"=="%%a" (echo "Skipping unsupported configuration" && exit /b 1 ) ) )
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# Make compiler command line tools available
|
- set PATH=C:\Ruby24-x64\bin;%PATH%
|
||||||
- call c:\projects\assimp\scripts\appveyor\compiler_setup.bat
|
- set CMAKE_DEFINES -DASSIMP_WERROR=ON
|
||||||
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013
|
||||||
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
|
||||||
|
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
|
||||||
|
- if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
|
||||||
|
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%"
|
||||||
|
|
||||||
build_script:
|
cache:
|
||||||
- cd c:\projects\assimp
|
- code\assimp.dir\%CONFIGURATION%
|
||||||
- if "%platform%" equ "x64" (cmake CMakeLists.txt -G "Visual Studio %Configuration% Win64")
|
- contrib\zlib\zlibstatic.dir\%CONFIGURATION%
|
||||||
- if "%platform%" equ "x86" (cmake CMakeLists.txt -G "Visual Studio %Configuration%")
|
- contrib\zlib\zlib.dir\%CONFIGURATION%
|
||||||
- if "%platform%" equ "x64" (msbuild /m /p:Configuration=Release /p:Platform="x64" Assimp.sln)
|
- tools\assimp_cmd\assimp_cmd.dir\%CONFIGURATION%
|
||||||
- if "%platform%" equ "x86" (msbuild /m /p:Configuration=Release /p:Platform="Win32" Assimp.sln)
|
- tools\assimp_view\assimp_viewer.dir\%CONFIGURATION%
|
||||||
|
- test\unit.dir\%CONFIGURATION%
|
||||||
|
- bin\.mtime_cache
|
||||||
|
|
||||||
|
before_build:
|
||||||
|
- ruby scripts\AppVeyor\mtime_cache -g scripts\AppVeyor\cacheglobs.txt -c bin\.mtime_cache\cache.json
|
||||||
|
|
||||||
|
build:
|
||||||
|
parallel: true
|
||||||
|
project: Assimp.sln
|
||||||
|
|
||||||
after_build:
|
after_build:
|
||||||
- 7z a assimp.7z c:\projects\assimp\bin\release\* c:\projects\assimp\lib\release\*
|
- 7z a assimp.7z bin\%CONFIGURATION%\* lib\%CONFIGURATION%\*
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- cmd: bin\%CONFIGURATION%\unit.exe --gtest_output=xml:testout.xml
|
||||||
|
|
||||||
|
on_finish:
|
||||||
|
- ps: (new-object net.webclient).UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\testout.xml))
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: assimp.7z
|
- path: assimp.7z
|
||||||
|
|
|
@ -56,18 +56,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
static const unsigned int NotSet = 0xcdcdcdcd;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup final material indices, generae a default material if necessary
|
// Setup final material indices, generae a default material if necessary
|
||||||
void Discreet3DSImporter::ReplaceDefaultMaterial()
|
void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||||
{
|
{
|
||||||
|
|
||||||
// Try to find an existing material that matches the
|
// Try to find an existing material that matches the
|
||||||
// typical default material setting:
|
// typical default material setting:
|
||||||
// - no textures
|
// - no textures
|
||||||
// - diffuse color (in grey!)
|
// - diffuse color (in grey!)
|
||||||
// NOTE: This is here to workaround the fact that some
|
// NOTE: This is here to workaround the fact that some
|
||||||
// exporters are writing a default material, too.
|
// exporters are writing a default material, too.
|
||||||
unsigned int idx = 0xcdcdcdcd;
|
unsigned int idx( NotSet );
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
||||||
{
|
{
|
||||||
std::string s = mScene->mMaterials[i].mName;
|
std::string s = mScene->mMaterials[i].mName;
|
||||||
|
@ -93,7 +94,9 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||||
}
|
}
|
||||||
idx = i;
|
idx = i;
|
||||||
}
|
}
|
||||||
if (0xcdcdcdcd == idx)idx = (unsigned int)mScene->mMaterials.size();
|
if ( NotSet == idx ) {
|
||||||
|
idx = ( unsigned int )mScene->mMaterials.size();
|
||||||
|
}
|
||||||
|
|
||||||
// now iterate through all meshes and through all faces and
|
// now iterate through all meshes and through all faces and
|
||||||
// find all faces that are using the default material
|
// find all faces that are using the default material
|
||||||
|
|
|
@ -1381,7 +1381,7 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent )
|
||||||
bGamma = true;
|
bGamma = true;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_RGBF:
|
case Discreet3DS::CHUNK_RGBF:
|
||||||
if (sizeof(ai_real) * 3 > diff) {
|
if (sizeof(float) * 3 > diff) {
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -686,7 +686,6 @@ std::list<unsigned int> mesh_idx;
|
||||||
tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
|
tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
|
||||||
tmesh->mVertices = new aiVector3D[tmesh->mNumVertices];
|
tmesh->mVertices = new aiVector3D[tmesh->mNumVertices];
|
||||||
tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices];
|
tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices];
|
||||||
tmesh->mFaces = new aiFace[face_list_cur.size()];
|
|
||||||
|
|
||||||
memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
|
memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
|
||||||
memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D));
|
memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D));
|
||||||
|
|
|
@ -139,6 +139,17 @@ inline size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
|
// Serialize a color value
|
||||||
|
template <>
|
||||||
|
inline size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v)
|
||||||
|
{
|
||||||
|
size_t t = Write<float>(stream,v.r);
|
||||||
|
t += Write<float>(stream,v.g);
|
||||||
|
t += Write<float>(stream,v.b);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Serialize a color value
|
// Serialize a color value
|
||||||
template <>
|
template <>
|
||||||
|
@ -325,7 +336,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
{
|
{
|
||||||
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
|
AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
|
||||||
|
|
||||||
size_t nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
|
unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
|
||||||
|
|
||||||
Write<aiString>(&chunk,node->mName);
|
Write<aiString>(&chunk,node->mName);
|
||||||
Write<aiMatrix4x4>(&chunk,node->mTransformation);
|
Write<aiMatrix4x4>(&chunk,node->mTransformation);
|
||||||
|
@ -639,9 +650,9 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
Write<float>(&chunk,l->mAttenuationQuadratic);
|
Write<float>(&chunk,l->mAttenuationQuadratic);
|
||||||
}
|
}
|
||||||
|
|
||||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorDiffuse);
|
Write<aiColor3D>(&chunk,l->mColorDiffuse);
|
||||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorSpecular);
|
Write<aiColor3D>(&chunk,l->mColorSpecular);
|
||||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorAmbient);
|
Write<aiColor3D>(&chunk,l->mColorAmbient);
|
||||||
|
|
||||||
if (l->mType == aiLightSource_SPOT) {
|
if (l->mType == aiLightSource_SPOT) {
|
||||||
Write<float>(&chunk,l->mAngleInnerCone);
|
Write<float>(&chunk,l->mAngleInnerCone);
|
||||||
|
|
|
@ -71,7 +71,6 @@ class AssbinImporter : public BaseImporter
|
||||||
private:
|
private:
|
||||||
bool shortened;
|
bool shortened;
|
||||||
bool compressed;
|
bool compressed;
|
||||||
protected:
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool CanRead(
|
virtual bool CanRead(
|
||||||
|
|
|
@ -82,6 +82,20 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
//#define DEBUG_B3D
|
//#define DEBUG_B3D
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void DeleteAllBarePointers(std::vector<T>& x)
|
||||||
|
{
|
||||||
|
for(auto p : x)
|
||||||
|
{
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
B3DImporter::~B3DImporter()
|
||||||
|
{
|
||||||
|
DeleteAllBarePointers(_animations);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{
|
bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{
|
||||||
|
|
||||||
|
@ -157,7 +171,8 @@ int B3DImporter::ReadByte(){
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
int B3DImporter::ReadInt(){
|
int B3DImporter::ReadInt(){
|
||||||
if( _pos+4<=_buf.size() ){
|
if( _pos+4<=_buf.size() ){
|
||||||
int n=*(int*)&_buf[_pos];
|
int n;
|
||||||
|
memcpy(&n, &_buf[_pos], 4);
|
||||||
_pos+=4;
|
_pos+=4;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -168,7 +183,8 @@ int B3DImporter::ReadInt(){
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
float B3DImporter::ReadFloat(){
|
float B3DImporter::ReadFloat(){
|
||||||
if( _pos+4<=_buf.size() ){
|
if( _pos+4<=_buf.size() ){
|
||||||
float n=*(float*)&_buf[_pos];
|
float n;
|
||||||
|
memcpy(&n, &_buf[_pos], 4);
|
||||||
_pos+=4;
|
_pos+=4;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -558,13 +574,19 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
||||||
void B3DImporter::ReadBB3D( aiScene *scene ){
|
void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||||
|
|
||||||
_textures.clear();
|
_textures.clear();
|
||||||
|
|
||||||
_materials.clear();
|
_materials.clear();
|
||||||
|
|
||||||
_vertices.clear();
|
_vertices.clear();
|
||||||
|
|
||||||
_meshes.clear();
|
_meshes.clear();
|
||||||
|
|
||||||
|
DeleteAllBarePointers(_nodes);
|
||||||
_nodes.clear();
|
_nodes.clear();
|
||||||
|
|
||||||
_nodeAnims.clear();
|
_nodeAnims.clear();
|
||||||
|
|
||||||
|
DeleteAllBarePointers(_animations);
|
||||||
_animations.clear();
|
_animations.clear();
|
||||||
|
|
||||||
string t=ReadChunk();
|
string t=ReadChunk();
|
||||||
|
|
|
@ -59,6 +59,8 @@ namespace Assimp{
|
||||||
|
|
||||||
class B3DImporter : public BaseImporter{
|
class B3DImporter : public BaseImporter{
|
||||||
public:
|
public:
|
||||||
|
B3DImporter() = default;
|
||||||
|
virtual ~B3DImporter();
|
||||||
|
|
||||||
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: ";
|
template< > const char* LogFunctions< BlenderBMeshConverter >::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "BLEND_BMESH: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -253,7 +253,7 @@ public:
|
||||||
* a compiler complain is the result.
|
* a compiler complain is the result.
|
||||||
* @param dest Destination value to be written
|
* @param dest Destination value to be written
|
||||||
* @param db File database, including input stream. */
|
* @param db File database, including input stream. */
|
||||||
template <typename T> inline void Convert (T& dest, const FileDatabase& db) const;
|
template <typename T> void Convert (T& dest, const FileDatabase& db) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// generic converter
|
// generic converter
|
||||||
|
|
|
@ -589,7 +589,10 @@ template <> inline void Structure :: Convert<short> (short& dest,const FileData
|
||||||
{
|
{
|
||||||
// automatic rescaling from short to float and vice versa (seems to be used by normals)
|
// automatic rescaling from short to float and vice versa (seems to be used by normals)
|
||||||
if (name == "float") {
|
if (name == "float") {
|
||||||
dest = static_cast<short>(db.reader->GetF4() * 32767.f);
|
float f = db.reader->GetF4();
|
||||||
|
if ( f > 1.0f )
|
||||||
|
f = 1.0f;
|
||||||
|
dest = static_cast<short>( f * 32767.f);
|
||||||
//db.reader->IncPtr(-4);
|
//db.reader->IncPtr(-4);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template<> const std::string LogFunctions<BlenderImporter>::log_prefix = "BLEND: ";
|
template<> const char* LogFunctions<BlenderImporter>::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "BLEND: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -59,7 +59,11 @@ static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
|
||||||
|
|
||||||
namspace Assimp
|
namspace Assimp
|
||||||
{
|
{
|
||||||
template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: ";
|
template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "BLEND_TESS_GL: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -252,7 +256,11 @@ void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: ";
|
template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "BLEND_TESS_P2T: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -393,7 +393,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
{
|
{
|
||||||
assert(object != NULL && object->GetType() == Opolygon);
|
ai_assert(object != NULL && object->GetType() == Opolygon);
|
||||||
|
|
||||||
// based on Melange sample code
|
// based on Melange sample code
|
||||||
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
||||||
|
@ -635,7 +635,7 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
|
||||||
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
|
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
|
||||||
|
|
||||||
BaseMaterial* const mat = ttag.GetMaterial();
|
BaseMaterial* const mat = ttag.GetMaterial();
|
||||||
assert(mat != NULL);
|
ai_assert(mat != NULL);
|
||||||
|
|
||||||
const MaterialMap::const_iterator it = material_mapping.find(mat);
|
const MaterialMap::const_iterator it = material_mapping.find(mat);
|
||||||
if(it == material_mapping.end()) {
|
if(it == material_mapping.end()) {
|
||||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "LogAux.h"
|
#include "LogAux.h"
|
||||||
|
|
||||||
#include <set>
|
#include <map>
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
|
|
@ -61,6 +61,7 @@ SET( PUBLIC_HEADERS
|
||||||
${HEADER_PATH}/color4.inl
|
${HEADER_PATH}/color4.inl
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
|
${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
|
||||||
${HEADER_PATH}/defs.h
|
${HEADER_PATH}/defs.h
|
||||||
|
${HEADER_PATH}/Defines.h
|
||||||
${HEADER_PATH}/cfileio.h
|
${HEADER_PATH}/cfileio.h
|
||||||
${HEADER_PATH}/light.h
|
${HEADER_PATH}/light.h
|
||||||
${HEADER_PATH}/material.h
|
${HEADER_PATH}/material.h
|
||||||
|
@ -661,6 +662,14 @@ ADD_ASSIMP_IMPORTER( GLTF
|
||||||
glTFImporter.h
|
glTFImporter.h
|
||||||
glTFExporter.h
|
glTFExporter.h
|
||||||
glTFExporter.cpp
|
glTFExporter.cpp
|
||||||
|
glTF2Asset.h
|
||||||
|
glTF2Asset.inl
|
||||||
|
glTF2AssetWriter.h
|
||||||
|
glTF2AssetWriter.inl
|
||||||
|
glTF2Importer.cpp
|
||||||
|
glTF2Importer.h
|
||||||
|
glTF2Exporter.h
|
||||||
|
glTF2Exporter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER( 3MF
|
ADD_ASSIMP_IMPORTER( 3MF
|
||||||
|
@ -934,6 +943,7 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||||
endif(ASSIMP_ANDROID_JNIIOSYSTEM)
|
endif(ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||||
|
|
||||||
if(MSVC AND ASSIMP_INSTALL_PDB)
|
if(MSVC AND ASSIMP_INSTALL_PDB)
|
||||||
|
IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
|
||||||
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
|
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
|
||||||
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||||
CONFIGURATIONS Debug
|
CONFIGURATIONS Debug
|
||||||
|
@ -942,6 +952,16 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
|
||||||
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||||
CONFIGURATIONS RelWithDebInfo
|
CONFIGURATIONS RelWithDebInfo
|
||||||
)
|
)
|
||||||
|
ELSE()
|
||||||
|
install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
|
||||||
|
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||||
|
CONFIGURATIONS Debug
|
||||||
|
)
|
||||||
|
install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}.pdb
|
||||||
|
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||||
|
CONFIGURATIONS RelWithDebInfo
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (ASSIMP_COVERALLS)
|
if (ASSIMP_COVERALLS)
|
||||||
|
|
|
@ -866,8 +866,8 @@ void ColladaExporter::WriteController( size_t pIndex)
|
||||||
|
|
||||||
std::vector<ai_real> bind_poses;
|
std::vector<ai_real> bind_poses;
|
||||||
bind_poses.reserve(mesh->mNumBones * 16);
|
bind_poses.reserve(mesh->mNumBones * 16);
|
||||||
for( size_t i = 0; i < mesh->mNumBones; ++i)
|
for(unsigned int i = 0; i < mesh->mNumBones; ++i)
|
||||||
for( size_t j = 0; j < 4; ++j)
|
for( unsigned int j = 0; j < 4; ++j)
|
||||||
bind_poses.insert(bind_poses.end(), mesh->mBones[i]->mOffsetMatrix[j], mesh->mBones[i]->mOffsetMatrix[j] + 4);
|
bind_poses.insert(bind_poses.end(), mesh->mBones[i]->mOffsetMatrix[j], mesh->mBones[i]->mOffsetMatrix[j] + 4);
|
||||||
|
|
||||||
WriteFloatArray( idstr + "-skin-bind_poses", FloatType_Mat4x4, (const ai_real*) bind_poses.data(), bind_poses.size() / 16);
|
WriteFloatArray( idstr + "-skin-bind_poses", FloatType_Mat4x4, (const ai_real*) bind_poses.data(), bind_poses.size() / 16);
|
||||||
|
@ -924,11 +924,11 @@ void ColladaExporter::WriteController( size_t pIndex)
|
||||||
|
|
||||||
ai_uint weight_index = 0;
|
ai_uint weight_index = 0;
|
||||||
std::vector<ai_int> joint_weight_indices(2 * joint_weight_indices_length, (ai_int)-1);
|
std::vector<ai_int> joint_weight_indices(2 * joint_weight_indices_length, (ai_int)-1);
|
||||||
for( size_t i = 0; i < mesh->mNumBones; ++i)
|
for( unsigned int i = 0; i < mesh->mNumBones; ++i)
|
||||||
for( size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
|
for( unsigned j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
|
||||||
{
|
{
|
||||||
unsigned int vId = mesh->mBones[i]->mWeights[j].mVertexId;
|
unsigned int vId = mesh->mBones[i]->mWeights[j].mVertexId;
|
||||||
for( size_t k = 0; k < num_influences[vId]; ++k)
|
for( ai_uint k = 0; k < num_influences[vId]; ++k)
|
||||||
{
|
{
|
||||||
if (joint_weight_indices[2 * (accum_influences[vId] + k)] == -1)
|
if (joint_weight_indices[2 * (accum_influences[vId] + k)] == -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -128,7 +128,10 @@ protected:
|
||||||
/// Enters a new xml element, which increases the indentation
|
/// Enters a new xml element, which increases the indentation
|
||||||
void PushTag() { startstr.append( " "); }
|
void PushTag() { startstr.append( " "); }
|
||||||
/// Leaves an element, decreasing the indentation
|
/// Leaves an element, decreasing the indentation
|
||||||
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
|
void PopTag() {
|
||||||
|
ai_assert( startstr.length() > 1);
|
||||||
|
startstr.erase( startstr.length() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a mesh ID for the given mesh
|
/// Creates a mesh ID for the given mesh
|
||||||
std::string GetMeshId( size_t pIndex) const {
|
std::string GetMeshId( size_t pIndex) const {
|
||||||
|
|
|
@ -119,7 +119,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
|
||||||
* might be NULL and it's our duty to return true here.
|
* might be NULL and it's our duty to return true here.
|
||||||
*/
|
*/
|
||||||
if (!pIOHandler)return true;
|
if (!pIOHandler)return true;
|
||||||
const char* tokens[] = {"collada"};
|
const char* tokens[] = {"<collada"};
|
||||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -674,7 +674,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
// create morph target meshes if any
|
// create morph target meshes if any
|
||||||
std::vector<aiMesh*> targetMeshes;
|
std::vector<aiMesh*> targetMeshes;
|
||||||
std::vector<float> targetWeights;
|
std::vector<float> targetWeights;
|
||||||
Collada::MorphMethod method;
|
Collada::MorphMethod method = Collada::Normalized;
|
||||||
|
|
||||||
for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
||||||
it != pParser.mControllerLibrary.end(); it++)
|
it != pParser.mControllerLibrary.end(); it++)
|
||||||
|
@ -728,7 +728,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
||||||
? aiMorphingMethod_MORPH_RELATIVE
|
? aiMorphingMethod_MORPH_RELATIVE
|
||||||
: aiMorphingMethod_MORPH_NORMALIZED;
|
: aiMorphingMethod_MORPH_NORMALIZED;
|
||||||
dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()];
|
dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()];
|
||||||
dstMesh->mNumAnimMeshes = animMeshes.size();
|
dstMesh->mNumAnimMeshes = static_cast<unsigned int>(animMeshes.size());
|
||||||
for (unsigned int i = 0; i < animMeshes.size(); i++)
|
for (unsigned int i = 0; i < animMeshes.size(); i++)
|
||||||
dstMesh->mAnimMeshes[i] = animMeshes.at(i);
|
dstMesh->mAnimMeshes[i] = animMeshes.at(i);
|
||||||
}
|
}
|
||||||
|
@ -1377,9 +1377,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
||||||
{
|
{
|
||||||
aiNodeAnim* dstAnim = new aiNodeAnim;
|
aiNodeAnim* dstAnim = new aiNodeAnim;
|
||||||
dstAnim->mNodeName = nodeName;
|
dstAnim->mNodeName = nodeName;
|
||||||
dstAnim->mNumPositionKeys = resultTrafos.size();
|
dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||||
dstAnim->mNumRotationKeys= resultTrafos.size();
|
dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||||
dstAnim->mNumScalingKeys = resultTrafos.size();
|
dstAnim->mNumScalingKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||||
dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
|
dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
|
||||||
dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
|
dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
|
||||||
dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
|
dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
|
||||||
|
@ -1445,11 +1445,11 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
||||||
++morphAnimChannelIndex;
|
++morphAnimChannelIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
morphAnim->mNumKeys = morphTimeValues.size();
|
morphAnim->mNumKeys = static_cast<unsigned int>(morphTimeValues.size());
|
||||||
morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys];
|
morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys];
|
||||||
for (unsigned int key = 0; key < morphAnim->mNumKeys; key++)
|
for (unsigned int key = 0; key < morphAnim->mNumKeys; key++)
|
||||||
{
|
{
|
||||||
morphAnim->mKeys[key].mNumValuesAndWeights = morphChannels.size();
|
morphAnim->mKeys[key].mNumValuesAndWeights = static_cast<unsigned int>(morphChannels.size());
|
||||||
morphAnim->mKeys[key].mValues = new unsigned int [morphChannels.size()];
|
morphAnim->mKeys[key].mValues = new unsigned int [morphChannels.size()];
|
||||||
morphAnim->mKeys[key].mWeights = new double [morphChannels.size()];
|
morphAnim->mKeys[key].mWeights = new double [morphChannels.size()];
|
||||||
|
|
||||||
|
@ -1470,13 +1470,13 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
||||||
{
|
{
|
||||||
aiAnimation* anim = new aiAnimation;
|
aiAnimation* anim = new aiAnimation;
|
||||||
anim->mName.Set( pName);
|
anim->mName.Set( pName);
|
||||||
anim->mNumChannels = anims.size();
|
anim->mNumChannels = static_cast<unsigned int>(anims.size());
|
||||||
if (anim->mNumChannels > 0)
|
if (anim->mNumChannels > 0)
|
||||||
{
|
{
|
||||||
anim->mChannels = new aiNodeAnim*[anims.size()];
|
anim->mChannels = new aiNodeAnim*[anims.size()];
|
||||||
std::copy( anims.begin(), anims.end(), anim->mChannels);
|
std::copy( anims.begin(), anims.end(), anim->mChannels);
|
||||||
}
|
}
|
||||||
anim->mNumMorphMeshChannels = morphAnims.size();
|
anim->mNumMorphMeshChannels = static_cast<unsigned int>(morphAnims.size());
|
||||||
if (anim->mNumMorphMeshChannels > 0)
|
if (anim->mNumMorphMeshChannels > 0)
|
||||||
{
|
{
|
||||||
anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
|
anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
|
||||||
|
|
|
@ -2231,7 +2231,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
if (primType != Prim_TriFans && primType != Prim_TriStrips &&
|
if (primType != Prim_TriFans && primType != Prim_TriStrips && primType != Prim_LineStrip &&
|
||||||
primType != Prim_Lines) { // this is ONLY to workaround a bug in SketchUp 15.3.331 where it writes the wrong 'count' when it writes out the 'lines'.
|
primType != Prim_Lines) { // this is ONLY to workaround a bug in SketchUp 15.3.331 where it writes the wrong 'count' when it writes out the 'lines'.
|
||||||
ai_assert(actualPrimitives == numPrimitives);
|
ai_assert(actualPrimitives == numPrimitives);
|
||||||
}
|
}
|
||||||
|
@ -2400,6 +2400,10 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pP
|
||||||
size_t numberOfVertices = indices.size() / numOffsets;
|
size_t numberOfVertices = indices.size() / numOffsets;
|
||||||
numPrimitives = numberOfVertices - 2;
|
numPrimitives = numberOfVertices - 2;
|
||||||
}
|
}
|
||||||
|
if (pPrimType == Prim_LineStrip) {
|
||||||
|
size_t numberOfVertices = indices.size() / numOffsets;
|
||||||
|
numPrimitives = numberOfVertices - 1;
|
||||||
|
}
|
||||||
|
|
||||||
pMesh->mFaceSize.reserve( numPrimitives);
|
pMesh->mFaceSize.reserve( numPrimitives);
|
||||||
pMesh->mFacePosIndices.reserve( indices.size() / numOffsets);
|
pMesh->mFacePosIndices.reserve( indices.size() / numOffsets);
|
||||||
|
@ -2416,6 +2420,11 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pP
|
||||||
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
|
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
|
||||||
CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
|
CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
|
||||||
break;
|
break;
|
||||||
|
case Prim_LineStrip:
|
||||||
|
numPoints = 2;
|
||||||
|
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
|
||||||
|
CopyVertex(currentVertex, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
|
||||||
|
break;
|
||||||
case Prim_Triangles:
|
case Prim_Triangles:
|
||||||
numPoints = 3;
|
numPoints = 3;
|
||||||
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
|
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
|
||||||
|
|
|
@ -95,14 +95,10 @@ public:
|
||||||
XmlSerializer(XmlReader* xmlReader)
|
XmlSerializer(XmlReader* xmlReader)
|
||||||
: xmlReader(xmlReader)
|
: xmlReader(xmlReader)
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportXml(aiScene* scene)
|
void ImportXml(aiScene* scene) {
|
||||||
{
|
|
||||||
|
|
||||||
scene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
|
||||||
|
|
||||||
scene->mRootNode = new aiNode();
|
scene->mRootNode = new aiNode();
|
||||||
std::vector<aiNode*> children;
|
std::vector<aiNode*> children;
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -228,7 +229,7 @@ ZipFile::~ZipFile() {
|
||||||
|
|
||||||
size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
||||||
const size_t size = pSize * pCount;
|
const size_t size = pSize * pCount;
|
||||||
assert(size <= m_Size);
|
ai_assert(size <= m_Size);
|
||||||
|
|
||||||
std::memcpy(pvBuffer, m_Buffer, size);
|
std::memcpy(pvBuffer, m_Buffer, size);
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportPr
|
||||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
@ -144,6 +145,8 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||||
|
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
||||||
|
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
|
|
|
@ -50,12 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "FBXDocument.h"
|
#include "FBXDocument.h"
|
||||||
#include "FBXImporter.h"
|
#include "FBXImporter.h"
|
||||||
#include "FBXDocumentUtil.h"
|
#include "FBXDocumentUtil.h"
|
||||||
#include "FBXProperties.h"
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
using namespace Util;
|
using namespace Util;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
|
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
|
||||||
|
@ -88,17 +87,16 @@ AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurve::~AnimationCurve()
|
AnimationCurve::~AnimationCurve()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name,
|
||||||
const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
|
const Document& doc, const char* const * target_prop_whitelist /*= NULL*/,
|
||||||
|
size_t whitelist_size /*= 0*/)
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
, target()
|
, target()
|
||||||
, doc(doc)
|
, doc(doc)
|
||||||
|
@ -155,18 +153,16 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
||||||
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurveNode::~AnimationCurveNode()
|
AnimationCurveNode::~AnimationCurveNode()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
||||||
{
|
{
|
||||||
if(curves.empty()) {
|
if ( curves.empty() ) {
|
||||||
// resolve attached animation curves
|
// resolve attached animation curves
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
||||||
|
|
||||||
|
@ -196,7 +192,6 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
|
||||||
return curves;
|
return curves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
|
@ -208,14 +203,12 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::s
|
||||||
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
|
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationLayer::~AnimationLayer()
|
AnimationLayer::~AnimationLayer()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
||||||
size_t whitelist_size /*= 0*/) const
|
size_t whitelist_size /*= 0*/) const
|
||||||
|
@ -299,14 +292,13 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationStack::~AnimationStack()
|
AnimationStack::~AnimationStack()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
} //!FBX
|
} //!FBX
|
||||||
} //!Assimp
|
} //!Assimp
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||||
|
|
|
@ -56,47 +56,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
enum Flag
|
//enum Flag
|
||||||
{
|
//{
|
||||||
e_unknown_0 = 1 << 0,
|
// e_unknown_0 = 1 << 0,
|
||||||
e_unknown_1 = 1 << 1,
|
// e_unknown_1 = 1 << 1,
|
||||||
e_unknown_2 = 1 << 2,
|
// e_unknown_2 = 1 << 2,
|
||||||
e_unknown_3 = 1 << 3,
|
// e_unknown_3 = 1 << 3,
|
||||||
e_unknown_4 = 1 << 4,
|
// e_unknown_4 = 1 << 4,
|
||||||
e_unknown_5 = 1 << 5,
|
// e_unknown_5 = 1 << 5,
|
||||||
e_unknown_6 = 1 << 6,
|
// e_unknown_6 = 1 << 6,
|
||||||
e_unknown_7 = 1 << 7,
|
// e_unknown_7 = 1 << 7,
|
||||||
e_unknown_8 = 1 << 8,
|
// e_unknown_8 = 1 << 8,
|
||||||
e_unknown_9 = 1 << 9,
|
// e_unknown_9 = 1 << 9,
|
||||||
e_unknown_10 = 1 << 10,
|
// e_unknown_10 = 1 << 10,
|
||||||
e_unknown_11 = 1 << 11,
|
// e_unknown_11 = 1 << 11,
|
||||||
e_unknown_12 = 1 << 12,
|
// e_unknown_12 = 1 << 12,
|
||||||
e_unknown_13 = 1 << 13,
|
// e_unknown_13 = 1 << 13,
|
||||||
e_unknown_14 = 1 << 14,
|
// e_unknown_14 = 1 << 14,
|
||||||
e_unknown_15 = 1 << 15,
|
// e_unknown_15 = 1 << 15,
|
||||||
e_unknown_16 = 1 << 16,
|
// e_unknown_16 = 1 << 16,
|
||||||
e_unknown_17 = 1 << 17,
|
// e_unknown_17 = 1 << 17,
|
||||||
e_unknown_18 = 1 << 18,
|
// e_unknown_18 = 1 << 18,
|
||||||
e_unknown_19 = 1 << 19,
|
// e_unknown_19 = 1 << 19,
|
||||||
e_unknown_20 = 1 << 20,
|
// e_unknown_20 = 1 << 20,
|
||||||
e_unknown_21 = 1 << 21,
|
// e_unknown_21 = 1 << 21,
|
||||||
e_unknown_22 = 1 << 22,
|
// e_unknown_22 = 1 << 22,
|
||||||
e_unknown_23 = 1 << 23,
|
// e_unknown_23 = 1 << 23,
|
||||||
e_flag_field_size_64_bit = 1 << 24, // Not sure what is
|
// e_flag_field_size_64_bit = 1 << 24, // Not sure what is
|
||||||
e_unknown_25 = 1 << 25,
|
// e_unknown_25 = 1 << 25,
|
||||||
e_unknown_26 = 1 << 26,
|
// e_unknown_26 = 1 << 26,
|
||||||
e_unknown_27 = 1 << 27,
|
// e_unknown_27 = 1 << 27,
|
||||||
e_unknown_28 = 1 << 28,
|
// e_unknown_28 = 1 << 28,
|
||||||
e_unknown_29 = 1 << 29,
|
// e_unknown_29 = 1 << 29,
|
||||||
e_unknown_30 = 1 << 30,
|
// e_unknown_30 = 1 << 30,
|
||||||
e_unknown_31 = 1 << 31
|
// e_unknown_31 = 1 << 31
|
||||||
};
|
//};
|
||||||
|
//
|
||||||
bool check_flag(uint32_t flags, Flag to_check)
|
//bool check_flag(uint32_t flags, Flag to_check)
|
||||||
{
|
//{
|
||||||
return (flags & to_check) != 0;
|
// return (flags & to_check) != 0;
|
||||||
}
|
//}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
|
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
|
||||||
:
|
:
|
||||||
|
@ -152,7 +151,8 @@ uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
|
||||||
TokenizeError("cannot ReadWord, out of bounds",input, cursor);
|
TokenizeError("cannot ReadWord, out of bounds",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
|
uint32_t word;
|
||||||
|
memcpy(&word, cursor, 4);
|
||||||
AI_SWAP4(word);
|
AI_SWAP4(word);
|
||||||
|
|
||||||
cursor += k_to_read;
|
cursor += k_to_read;
|
||||||
|
@ -341,10 +341,10 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, uint32_t const flags)
|
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, bool const is64bits)
|
||||||
{
|
{
|
||||||
// the first word contains the offset at which this block ends
|
// the first word contains the offset at which this block ends
|
||||||
const uint64_t end_offset = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : */ReadWord(input, cursor, end);
|
const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// we may get 0 if reading reached the end of the file -
|
// we may get 0 if reading reached the end of the file -
|
||||||
// fbx files have a mysterious extra footer which I don't know
|
// fbx files have a mysterious extra footer which I don't know
|
||||||
|
@ -362,10 +362,10 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
// the second data word contains the number of properties in the scope
|
// the second data word contains the number of properties in the scope
|
||||||
const uint64_t prop_count = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : */ReadWord(input, cursor, end);
|
const uint64_t prop_count = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// the third data word contains the length of the property list
|
// the third data word contains the length of the property list
|
||||||
const uint64_t prop_length = /*check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) :*/ ReadWord(input, cursor, end);
|
const uint64_t prop_length = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// now comes the name of the scope/key
|
// now comes the name of the scope/key
|
||||||
const char* sbeg, *send;
|
const char* sbeg, *send;
|
||||||
|
@ -392,7 +392,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
// at the end of each nested block, there is a NUL record to indicate
|
// at the end of each nested block, there is a NUL record to indicate
|
||||||
// that the sub-scope exists (i.e. to distinguish between P: and P : {})
|
// that the sub-scope exists (i.e. to distinguish between P: and P : {})
|
||||||
// this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit.
|
// this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit.
|
||||||
const size_t sentinel_block_length = /*check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : */(sizeof(uint32_t) * 3 + 1);
|
const size_t sentinel_block_length = is64bits ? (sizeof(uint64_t)* 3 + 1) : (sizeof(uint32_t)* 3 + 1);
|
||||||
|
|
||||||
if (Offset(input, cursor) < end_offset) {
|
if (Offset(input, cursor) < end_offset) {
|
||||||
if (end_offset - Offset(input, cursor) < sentinel_block_length) {
|
if (end_offset - Offset(input, cursor) < sentinel_block_length) {
|
||||||
|
@ -403,7 +403,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
|
|
||||||
// XXX this is vulnerable to stack overflowing ..
|
// XXX this is vulnerable to stack overflowing ..
|
||||||
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
||||||
ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, flags);
|
ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits);
|
||||||
}
|
}
|
||||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
||||||
|
|
||||||
|
@ -426,6 +426,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
|
||||||
void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
|
void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
|
||||||
{
|
{
|
||||||
ai_assert(input);
|
ai_assert(input);
|
||||||
|
@ -438,19 +439,17 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
||||||
TokenizeError("magic bytes not found",0);
|
TokenizeError("magic bytes not found",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* cursor = input + 18;
|
||||||
//uint32_t offset = 0x15;
|
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||||
const char* cursor = input + 0x15;
|
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||||
|
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||||
const uint32_t flags = ReadWord(input, cursor, input + length);
|
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||||
|
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||||
const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
|
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||||
(void) padding_0;
|
const bool is64bits = version >= 7500;
|
||||||
const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused
|
|
||||||
(void) padding_1;
|
|
||||||
while (cursor < input + length)
|
while (cursor < input + length)
|
||||||
{
|
{
|
||||||
if(!ReadScope(output_tokens, input, cursor, input + length, flags)) {
|
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,4 +66,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif // INCLUDED_AI_FBX_COMPILECONFIG_H
|
||||||
|
|
|
@ -55,9 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
|
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -949,8 +949,7 @@ std::string Converter::NameTransformationChainNode( const std::string& name, Tra
|
||||||
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
|
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Converter::GenerateTransformationNodeChain( const Model& model,
|
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes )
|
||||||
std::vector<aiNode*>& output_nodes )
|
|
||||||
{
|
{
|
||||||
const PropertyTable& props = model.Props();
|
const PropertyTable& props = model.Props();
|
||||||
const Model::RotOrder rot = model.RotationOrder();
|
const Model::RotOrder rot = model.RotationOrder();
|
||||||
|
@ -1065,6 +1064,10 @@ void Converter::GenerateTransformationNodeChain( const Model& model,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( comp == TransformationComp_PostRotation ) {
|
||||||
|
chain[ i ] = chain[ i ].Inverse();
|
||||||
|
}
|
||||||
|
|
||||||
aiNode* nd = new aiNode();
|
aiNode* nd = new aiNode();
|
||||||
output_nodes.push_back( nd );
|
output_nodes.push_back( nd );
|
||||||
|
|
||||||
|
@ -1093,7 +1096,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
|
||||||
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
|
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
|
||||||
|
|
||||||
// create metadata on node
|
// create metadata on node
|
||||||
std::size_t numStaticMetaData = 2;
|
const std::size_t numStaticMetaData = 2;
|
||||||
aiMetadata* data = aiMetadata::Alloc( static_cast<unsigned int>(unparsedProperties.size() + numStaticMetaData) );
|
aiMetadata* data = aiMetadata::Alloc( static_cast<unsigned int>(unparsedProperties.size() + numStaticMetaData) );
|
||||||
nd.mMetaData = data;
|
nd.mMetaData = data;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -2368,8 +2371,13 @@ void Converter::ConvertAnimationStack( const AnimationStack& st )
|
||||||
|
|
||||||
int64_t start_time = st.LocalStart();
|
int64_t start_time = st.LocalStart();
|
||||||
int64_t stop_time = st.LocalStop();
|
int64_t stop_time = st.LocalStop();
|
||||||
double start_timeF = CONVERT_FBX_TIME( start_time );
|
bool has_local_startstop = start_time != 0 || stop_time != 0;
|
||||||
double stop_timeF = CONVERT_FBX_TIME( stop_time );
|
if ( !has_local_startstop ) {
|
||||||
|
// no time range given, so accept every keyframe and use the actual min/max time
|
||||||
|
// the numbers are INT64_MIN/MAX, the 20000 is for safety because GenerateNodeAnimations uses an epsilon of 10000
|
||||||
|
start_time = -9223372036854775807ll + 20000;
|
||||||
|
stop_time = 9223372036854775807ll - 20000;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for( const NodeMap::value_type& kv : node_map ) {
|
for( const NodeMap::value_type& kv : node_map ) {
|
||||||
|
@ -2401,27 +2409,23 @@ void Converter::ConvertAnimationStack( const AnimationStack& st )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//adjust relative timing for animation
|
double start_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(start_time) * anim_fps) : min_time;
|
||||||
{
|
double stop_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(stop_time) * anim_fps) : max_time;
|
||||||
double start_fps = start_timeF * anim_fps;
|
|
||||||
|
|
||||||
for ( unsigned int c = 0; c < anim->mNumChannels; c++ )
|
// adjust relative timing for animation
|
||||||
{
|
for ( unsigned int c = 0; c < anim->mNumChannels; c++ ) {
|
||||||
aiNodeAnim* channel = anim->mChannels[ c ];
|
aiNodeAnim* channel = anim->mChannels[ c ];
|
||||||
for ( uint32_t i = 0; i < channel->mNumPositionKeys; i++ )
|
for ( uint32_t i = 0; i < channel->mNumPositionKeys; i++ )
|
||||||
channel->mPositionKeys[ i ].mTime -= start_fps;
|
channel->mPositionKeys[ i ].mTime -= start_time_fps;
|
||||||
for ( uint32_t i = 0; i < channel->mNumRotationKeys; i++ )
|
for ( uint32_t i = 0; i < channel->mNumRotationKeys; i++ )
|
||||||
channel->mRotationKeys[ i ].mTime -= start_fps;
|
channel->mRotationKeys[ i ].mTime -= start_time_fps;
|
||||||
for ( uint32_t i = 0; i < channel->mNumScalingKeys; i++ )
|
for ( uint32_t i = 0; i < channel->mNumScalingKeys; i++ )
|
||||||
channel->mScalingKeys[ i ].mTime -= start_fps;
|
channel->mScalingKeys[ i ].mTime -= start_time_fps;
|
||||||
}
|
|
||||||
|
|
||||||
max_time -= min_time;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for some mysterious reason, mDuration is simply the maximum key -- the
|
// for some mysterious reason, mDuration is simply the maximum key -- the
|
||||||
// validator always assumes animations to start at zero.
|
// validator always assumes animations to start at zero.
|
||||||
anim->mDuration = ( stop_timeF - start_timeF ) * anim_fps;
|
anim->mDuration = stop_time_fps - start_time_fps;
|
||||||
anim->mTicksPerSecond = anim_fps;
|
anim->mTicksPerSecond = anim_fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3119,7 +3123,6 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||||
const aiVector3D& def_value,
|
const aiVector3D& def_value,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
|
@ -3140,7 +3143,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
|
||||||
|
|
||||||
valOut[ i ].mTime = temp[ i ].mTime;
|
valOut[ i ].mTime = temp[ i ].mTime;
|
||||||
|
|
||||||
|
|
||||||
GetRotationMatrix( order, temp[ i ].mValue, m );
|
GetRotationMatrix( order, temp[ i ].mValue, m );
|
||||||
aiQuaternion quat = aiQuaternion( aiMatrix3x3( m ) );
|
aiQuaternion quat = aiQuaternion( aiMatrix3x3( m ) );
|
||||||
|
|
||||||
|
@ -3159,7 +3161,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
|
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
|
||||||
aiVectorKey* out_translation,
|
aiVectorKey* out_translation,
|
||||||
const KeyFrameListList& scaling,
|
const KeyFrameListList& scaling,
|
||||||
|
@ -3218,7 +3219,6 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
|
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
|
||||||
{
|
{
|
||||||
aiMatrix4x4 m;
|
aiMatrix4x4 m;
|
||||||
|
@ -3227,7 +3227,6 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
|
||||||
return aiQuaternion( aiMatrix3x3( m ) );
|
return aiQuaternion( aiMatrix3x3( m ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& maxTime,
|
double& maxTime,
|
||||||
|
@ -3248,7 +3247,6 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const Animat
|
||||||
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
|
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
|
@ -3267,7 +3265,6 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const
|
||||||
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
|
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||||
const LayerMap& /*layers*/,
|
const LayerMap& /*layers*/,
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
|
@ -3289,7 +3286,8 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
|
||||||
|
|
||||||
void Converter::TransferDataToScene()
|
void Converter::TransferDataToScene()
|
||||||
{
|
{
|
||||||
ai_assert( !out->mMeshes && !out->mNumMeshes );
|
ai_assert( !out->mMeshes );
|
||||||
|
ai_assert( !out->mNumMeshes );
|
||||||
|
|
||||||
// note: the trailing () ensures initialization with NULL - not
|
// note: the trailing () ensures initialization with NULL - not
|
||||||
// many C++ users seem to know this, so pointing it out to avoid
|
// many C++ users seem to know this, so pointing it out to avoid
|
||||||
|
|
|
@ -70,13 +70,13 @@ LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc)
|
||||||
, id(id)
|
, id(id)
|
||||||
, flags()
|
, flags()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LazyObject::~LazyObject()
|
LazyObject::~LazyObject()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -232,16 +232,15 @@ Object::Object(uint64_t id, const Element& element, const std::string& name)
|
||||||
, name(name)
|
, name(name)
|
||||||
, id(id)
|
, id(id)
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Object::~Object()
|
Object::~Object()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
|
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
|
||||||
: props(props)
|
: props(props)
|
||||||
|
@ -292,11 +291,10 @@ Document::~Document()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static const int LowerSupportedVersion = 7100;
|
static const unsigned int LowerSupportedVersion = 7100;
|
||||||
static const int UpperSupportedVersion = 7400;
|
static const unsigned int UpperSupportedVersion = 7400;
|
||||||
|
|
||||||
void Document::ReadHeader()
|
void Document::ReadHeader() {
|
||||||
{
|
|
||||||
// Read ID objects from "Objects" section
|
// Read ID objects from "Objects" section
|
||||||
const Scope& sc = parser.GetRootScope();
|
const Scope& sc = parser.GetRootScope();
|
||||||
const Element* const ehead = sc["FBXHeaderExtension"];
|
const Element* const ehead = sc["FBXHeaderExtension"];
|
||||||
|
@ -362,7 +360,6 @@ void Document::ReadGlobalSettings()
|
||||||
globals.reset(new FileGlobalSettings(*this, props));
|
globals.reset(new FileGlobalSettings(*this, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Document::ReadObjects()
|
void Document::ReadObjects()
|
||||||
{
|
{
|
||||||
|
@ -388,7 +385,6 @@ void Document::ReadObjects()
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* err;
|
const char* err;
|
||||||
|
|
||||||
const uint64_t id = ParseTokenAsID(*tok[0], err);
|
const uint64_t id = ParseTokenAsID(*tok[0], err);
|
||||||
if(err) {
|
if(err) {
|
||||||
DOMError(err,el.second);
|
DOMError(err,el.second);
|
||||||
|
@ -470,8 +466,6 @@ void Document::ReadPropertyTemplates()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Document::ReadConnections()
|
void Document::ReadConnections()
|
||||||
{
|
{
|
||||||
|
@ -483,7 +477,6 @@ void Document::ReadConnections()
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t insertionOrder = 0l;
|
uint64_t insertionOrder = 0l;
|
||||||
|
|
||||||
const Scope& sconns = *econns->Compound();
|
const Scope& sconns = *econns->Compound();
|
||||||
const ElementCollection conns = sconns.GetCollection("C");
|
const ElementCollection conns = sconns.GetCollection("C");
|
||||||
for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) {
|
for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) {
|
||||||
|
@ -492,7 +485,9 @@ void Document::ReadConnections()
|
||||||
|
|
||||||
// PP = property-property connection, ignored for now
|
// PP = property-property connection, ignored for now
|
||||||
// (tokens: "PP", ID1, "Property1", ID2, "Property2")
|
// (tokens: "PP", ID1, "Property1", ID2, "Property2")
|
||||||
if(type == "PP") continue;
|
if ( type == "PP" ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1));
|
const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1));
|
||||||
const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2));
|
const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2));
|
||||||
|
@ -519,11 +514,10 @@ void Document::ReadConnections()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||||
{
|
{
|
||||||
if (!animationStacksResolved.empty() || !animationStacks.size()) {
|
if (!animationStacksResolved.empty() || animationStacks.empty()) {
|
||||||
return animationStacksResolved;
|
return animationStacksResolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +535,6 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||||
return animationStacksResolved;
|
return animationStacksResolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LazyObject* Document::GetObject(uint64_t id) const
|
LazyObject* Document::GetObject(uint64_t id) const
|
||||||
{
|
{
|
||||||
|
@ -552,8 +545,7 @@ LazyObject* Document::GetObject(uint64_t id) const
|
||||||
#define MAX_CLASSNAMES 6
|
#define MAX_CLASSNAMES 6
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id,
|
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const
|
||||||
const ConnectionMap& conns) const
|
|
||||||
{
|
{
|
||||||
std::vector<const Connection*> temp;
|
std::vector<const Connection*> temp;
|
||||||
|
|
||||||
|
@ -570,7 +562,6 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id,
|
||||||
return temp; // NRVO should handle this
|
return temp; // NRVO should handle this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src,
|
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src,
|
||||||
const ConnectionMap& conns,
|
const ConnectionMap& conns,
|
||||||
|
@ -579,17 +570,17 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
||||||
|
|
||||||
{
|
{
|
||||||
ai_assert(classnames);
|
ai_assert(classnames);
|
||||||
ai_assert(count != 0 && count <= MAX_CLASSNAMES);
|
ai_assert( count != 0 );
|
||||||
|
ai_assert( count <= MAX_CLASSNAMES);
|
||||||
|
|
||||||
size_t lenghts[MAX_CLASSNAMES];
|
size_t lenghts[MAX_CLASSNAMES];
|
||||||
|
|
||||||
const size_t c = count;
|
const size_t c = count;
|
||||||
for (size_t i = 0; i < c; ++i) {
|
for (size_t i = 0; i < c; ++i) {
|
||||||
lenghts[i] = strlen(classnames[i]);
|
lenghts[ i ] = strlen(classnames[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<const Connection*> temp;
|
std::vector<const Connection*> temp;
|
||||||
|
|
||||||
const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range =
|
const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range =
|
||||||
conns.equal_range(id);
|
conns.equal_range(id);
|
||||||
|
|
||||||
|
@ -621,25 +612,19 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
||||||
return temp; // NRVO should handle this
|
return temp; // NRVO should handle this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
|
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
|
||||||
{
|
{
|
||||||
return GetConnectionsSequenced(source, ConnectionsBySource());
|
return GetConnectionsSequenced(source, ConnectionsBySource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest,
|
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest, const char* classname) const
|
||||||
const char* classname) const
|
|
||||||
{
|
{
|
||||||
const char* arr[] = {classname};
|
const char* arr[] = {classname};
|
||||||
return GetConnectionsBySourceSequenced(dest, arr,1);
|
return GetConnectionsBySourceSequenced(dest, arr,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
|
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
|
||||||
const char* const* classnames, size_t count) const
|
const char* const* classnames, size_t count) const
|
||||||
|
@ -647,7 +632,6 @@ std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_
|
||||||
return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
|
return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
||||||
const char* classname) const
|
const char* classname) const
|
||||||
|
@ -656,14 +640,12 @@ std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(ui
|
||||||
return GetConnectionsByDestinationSequenced(dest, arr,1);
|
return GetConnectionsByDestinationSequenced(dest, arr,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const
|
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const
|
||||||
{
|
{
|
||||||
return GetConnectionsSequenced(dest, ConnectionsByDestination());
|
return GetConnectionsSequenced(dest, ConnectionsByDestination());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
||||||
const char* const* classnames, size_t count) const
|
const char* const* classnames, size_t count) const
|
||||||
|
@ -672,7 +654,6 @@ std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(ui
|
||||||
return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count);
|
return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop,
|
Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop,
|
||||||
const Document& doc)
|
const Document& doc)
|
||||||
|
@ -688,14 +669,12 @@ Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, co
|
||||||
ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end());
|
ai_assert(!dest || doc.Objects().find(dest) != doc.Objects().end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Connection::~Connection()
|
Connection::~Connection()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LazyObject& Connection::LazySourceObject() const
|
LazyObject& Connection::LazySourceObject() const
|
||||||
{
|
{
|
||||||
|
@ -704,7 +683,6 @@ LazyObject& Connection::LazySourceObject() const
|
||||||
return *lazy;
|
return *lazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
LazyObject& Connection::LazyDestinationObject() const
|
LazyObject& Connection::LazyDestinationObject() const
|
||||||
{
|
{
|
||||||
|
@ -713,7 +691,6 @@ LazyObject& Connection::LazyDestinationObject() const
|
||||||
return *lazy;
|
return *lazy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const Object* Connection::SourceObject() const
|
const Object* Connection::SourceObject() const
|
||||||
{
|
{
|
||||||
|
@ -722,7 +699,6 @@ const Object* Connection::SourceObject() const
|
||||||
return lazy->Get();
|
return lazy->Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const Object* Connection::DestinationObject() const
|
const Object* Connection::DestinationObject() const
|
||||||
{
|
{
|
||||||
|
@ -735,4 +711,3 @@ const Object* Connection::DestinationObject() const
|
||||||
} // !Assimp
|
} // !Assimp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -338,12 +338,7 @@ public:
|
||||||
class Model : public Object
|
class Model : public Object
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
enum RotOrder {
|
||||||
virtual ~Model();
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum RotOrder
|
|
||||||
{
|
|
||||||
RotOrder_EulerXYZ = 0,
|
RotOrder_EulerXYZ = 0,
|
||||||
RotOrder_EulerXZY,
|
RotOrder_EulerXZY,
|
||||||
RotOrder_EulerYZX,
|
RotOrder_EulerYZX,
|
||||||
|
@ -357,8 +352,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum TransformInheritance
|
enum TransformInheritance {
|
||||||
{
|
|
||||||
TransformInheritance_RrSs = 0,
|
TransformInheritance_RrSs = 0,
|
||||||
TransformInheritance_RSrs,
|
TransformInheritance_RSrs,
|
||||||
TransformInheritance_Rrs,
|
TransformInheritance_Rrs,
|
||||||
|
@ -366,7 +360,10 @@ public:
|
||||||
TransformInheritance_MAX // end-of-enum sentinel
|
TransformInheritance_MAX // end-of-enum sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||||
|
|
||||||
|
virtual ~Model();
|
||||||
|
|
||||||
fbx_simple_property(QuaternionInterpolate, int, 0)
|
fbx_simple_property(QuaternionInterpolate, int, 0)
|
||||||
|
|
||||||
fbx_simple_property(RotationOffset, aiVector3D, aiVector3D())
|
fbx_simple_property(RotationOffset, aiVector3D, aiVector3D())
|
||||||
|
@ -443,7 +440,6 @@ public:
|
||||||
fbx_simple_property(LODBox, bool, false)
|
fbx_simple_property(LODBox, bool, false)
|
||||||
fbx_simple_property(Freeze, bool, false)
|
fbx_simple_property(Freeze, bool, false)
|
||||||
|
|
||||||
public:
|
|
||||||
const std::string& Shading() const {
|
const std::string& Shading() const {
|
||||||
return shading;
|
return shading;
|
||||||
}
|
}
|
||||||
|
@ -462,13 +458,11 @@ public:
|
||||||
return materials;
|
return materials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Get geometry links */
|
/** Get geometry links */
|
||||||
const std::vector<const Geometry*>& GetGeometry() const {
|
const std::vector<const Geometry*>& GetGeometry() const {
|
||||||
return geometry;
|
return geometry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Get node attachments */
|
/** Get node attachments */
|
||||||
const std::vector<const NodeAttribute*>& GetAttributes() const {
|
const std::vector<const NodeAttribute*>& GetAttributes() const {
|
||||||
return attributes;
|
return attributes;
|
||||||
|
@ -477,7 +471,6 @@ public:
|
||||||
/** convenience method to check if the node has a Null node marker */
|
/** convenience method to check if the node has a Null node marker */
|
||||||
bool IsNull() const;
|
bool IsNull() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ResolveLinks(const Element& element, const Document& doc);
|
void ResolveLinks(const Element& element, const Document& doc);
|
||||||
|
|
||||||
|
@ -603,10 +596,10 @@ public:
|
||||||
return textures[index];
|
return textures[index];
|
||||||
|
|
||||||
}
|
}
|
||||||
const int textureCount() const {
|
int textureCount() const {
|
||||||
return static_cast<int>(textures.size());
|
return static_cast<int>(textures.size());
|
||||||
}
|
}
|
||||||
const BlendMode GetBlendMode() const
|
BlendMode GetBlendMode() const
|
||||||
{
|
{
|
||||||
return blendMode;
|
return blendMode;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +647,7 @@ public:
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t ContentLength() const {
|
uint32_t ContentLength() const {
|
||||||
return contentLength;
|
return contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -805,7 +798,6 @@ private:
|
||||||
|
|
||||||
typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
|
typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
|
||||||
|
|
||||||
|
|
||||||
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
||||||
class AnimationLayer : public Object
|
class AnimationLayer : public Object
|
||||||
{
|
{
|
||||||
|
@ -828,10 +820,8 @@ private:
|
||||||
const Document& doc;
|
const Document& doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<const AnimationLayer*> AnimationLayerList;
|
typedef std::vector<const AnimationLayer*> AnimationLayerList;
|
||||||
|
|
||||||
|
|
||||||
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
||||||
class AnimationStack : public Object
|
class AnimationStack : public Object
|
||||||
{
|
{
|
||||||
|
@ -839,7 +829,6 @@ public:
|
||||||
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||||
virtual ~AnimationStack();
|
virtual ~AnimationStack();
|
||||||
|
|
||||||
public:
|
|
||||||
fbx_simple_property(LocalStart, int64_t, 0L)
|
fbx_simple_property(LocalStart, int64_t, 0L)
|
||||||
fbx_simple_property(LocalStop, int64_t, 0L)
|
fbx_simple_property(LocalStop, int64_t, 0L)
|
||||||
fbx_simple_property(ReferenceStart, int64_t, 0L)
|
fbx_simple_property(ReferenceStart, int64_t, 0L)
|
||||||
|
@ -879,7 +868,6 @@ private:
|
||||||
typedef std::vector<float> WeightArray;
|
typedef std::vector<float> WeightArray;
|
||||||
typedef std::vector<unsigned int> WeightIndexArray;
|
typedef std::vector<unsigned int> WeightIndexArray;
|
||||||
|
|
||||||
|
|
||||||
/** DOM class for skin deformer clusters (aka subdeformers) */
|
/** DOM class for skin deformer clusters (aka subdeformers) */
|
||||||
class Cluster : public Deformer
|
class Cluster : public Deformer
|
||||||
{
|
{
|
||||||
|
@ -924,8 +912,6 @@ private:
|
||||||
const Model* node;
|
const Model* node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** DOM class for skin deformers */
|
/** DOM class for skin deformers */
|
||||||
class Skin : public Deformer
|
class Skin : public Deformer
|
||||||
{
|
{
|
||||||
|
@ -1009,10 +995,8 @@ public:
|
||||||
typedef std::map<uint64_t, LazyObject*> ObjectMap;
|
typedef std::map<uint64_t, LazyObject*> ObjectMap;
|
||||||
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
|
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
|
||||||
|
|
||||||
|
|
||||||
typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
|
typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
|
||||||
|
|
||||||
|
|
||||||
/** DOM class for global document settings, a single instance per document can
|
/** DOM class for global document settings, a single instance per document can
|
||||||
* be accessed via Document.Globals(). */
|
* be accessed via Document.Globals(). */
|
||||||
class FileGlobalSettings
|
class FileGlobalSettings
|
||||||
|
@ -1074,9 +1058,6 @@ private:
|
||||||
const Document& doc;
|
const Document& doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** DOM root for a FBX file */
|
/** DOM root for a FBX file */
|
||||||
class Document
|
class Document
|
||||||
{
|
{
|
||||||
|
@ -1154,8 +1135,6 @@ private:
|
||||||
const ConnectionMap&,
|
const ConnectionMap&,
|
||||||
const char* const* classnames,
|
const char* const* classnames,
|
||||||
size_t count) const;
|
size_t count) const;
|
||||||
|
|
||||||
private:
|
|
||||||
void ReadHeader();
|
void ReadHeader();
|
||||||
void ReadObjects();
|
void ReadObjects();
|
||||||
void ReadPropertyTemplates();
|
void ReadPropertyTemplates();
|
||||||
|
|
|
@ -59,7 +59,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template<> const std::string LogFunctions<FBXImporter>::log_prefix = "FBX: ";
|
template<> const char* LogFunctions<FBXImporter>::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "FBX: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -243,7 +243,6 @@ const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, un
|
||||||
ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );
|
ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );
|
||||||
count = m_mapping_counts[ in_index ];
|
count = m_mapping_counts[ in_index ];
|
||||||
|
|
||||||
// ai_assert( count != 0 );
|
|
||||||
ai_assert( m_mapping_offsets[ in_index ] + count <= m_mappings.size() );
|
ai_assert( m_mapping_offsets[ in_index ] + count <= m_mappings.size() );
|
||||||
|
|
||||||
return &m_mappings[ m_mapping_offsets[ in_index ] ];
|
return &m_mappings[ m_mapping_offsets[ in_index ] ];
|
||||||
|
|
|
@ -77,14 +77,12 @@ Model::Model(uint64_t id, const Element& element, const Document& doc, const std
|
||||||
ResolveLinks(element,doc);
|
ResolveLinks(element,doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Model::~Model()
|
Model::~Model()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Model::ResolveLinks(const Element& element, const Document& doc)
|
void Model::ResolveLinks(const Element& element, const Document& doc)
|
||||||
{
|
{
|
||||||
|
@ -132,7 +130,6 @@ void Model::ResolveLinks(const Element& element, const Document& doc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool Model::IsNull() const
|
bool Model::IsNull() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
using namespace Util;
|
using namespace Util;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||||
|
@ -75,7 +75,7 @@ NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
NodeAttribute::~NodeAttribute()
|
NodeAttribute::~NodeAttribute()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,33 +101,30 @@ CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Docume
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
CameraSwitcher::~CameraSwitcher()
|
CameraSwitcher::~CameraSwitcher()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||||
: NodeAttribute(id,element,doc,name)
|
: NodeAttribute(id,element,doc,name)
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Camera::~Camera()
|
Camera::~Camera()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||||
: NodeAttribute(id,element,doc,name)
|
: NodeAttribute(id,element,doc,name)
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -224,41 +224,36 @@ Parser::Parser (const TokenList& tokens, bool is_binary)
|
||||||
root.reset(new Scope(*this,true));
|
root.reset(new Scope(*this,true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Parser::~Parser()
|
Parser::~Parser()
|
||||||
{
|
{
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
TokenPtr Parser::AdvanceToNextToken()
|
TokenPtr Parser::AdvanceToNextToken()
|
||||||
{
|
{
|
||||||
last = current;
|
last = current;
|
||||||
if (cursor == tokens.end()) {
|
if (cursor == tokens.end()) {
|
||||||
current = NULL;
|
current = NULL;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
current = *cursor++;
|
current = *cursor++;
|
||||||
}
|
}
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
TokenPtr Parser::CurrentToken() const
|
TokenPtr Parser::CurrentToken() const
|
||||||
{
|
{
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
TokenPtr Parser::LastToken() const
|
TokenPtr Parser::LastToken() const
|
||||||
{
|
{
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
||||||
{
|
{
|
||||||
|
@ -286,7 +281,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
||||||
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
||||||
ai_assert(length > 0);
|
ai_assert(length > 0);
|
||||||
|
|
||||||
const char* out;
|
const char* out = nullptr;
|
||||||
const uint64_t id = strtoul10_64(t.begin(),&out,&length);
|
const uint64_t id = strtoul10_64(t.begin(),&out,&length);
|
||||||
if (out > t.end()) {
|
if (out > t.end()) {
|
||||||
err_out = "failed to parse ID (text)";
|
err_out = "failed to parse ID (text)";
|
||||||
|
@ -296,7 +291,6 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
||||||
{
|
{
|
||||||
|
@ -333,7 +327,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* out;
|
const char* out = nullptr;
|
||||||
const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length));
|
const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length));
|
||||||
if (out > t.end()) {
|
if (out > t.end()) {
|
||||||
err_out = "failed to parse ID";
|
err_out = "failed to parse ID";
|
||||||
|
@ -446,7 +440,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
|
||||||
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
unsigned int length = static_cast<unsigned int>(t.end() - t.begin());
|
||||||
ai_assert(length > 0);
|
ai_assert(length > 0);
|
||||||
|
|
||||||
const char* out;
|
const char* out = nullptr;
|
||||||
const int64_t id = strtol10_64(t.begin(), &out, &length);
|
const int64_t id = strtol10_64(t.begin(), &out, &length);
|
||||||
if (out > t.end()) {
|
if (out > t.end()) {
|
||||||
err_out = "failed to parse Int64 (text)";
|
err_out = "failed to parse Int64 (text)";
|
||||||
|
|
|
@ -85,12 +85,9 @@ typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> Element
|
||||||
class Element
|
class Element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Element(const Token& key_token, Parser& parser);
|
Element(const Token& key_token, Parser& parser);
|
||||||
~Element();
|
~Element();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
const Scope* Compound() const {
|
const Scope* Compound() const {
|
||||||
return compound.get();
|
return compound.get();
|
||||||
}
|
}
|
||||||
|
@ -104,14 +101,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const Token& key_token;
|
const Token& key_token;
|
||||||
TokenList tokens;
|
TokenList tokens;
|
||||||
std::unique_ptr<Scope> compound;
|
std::unique_ptr<Scope> compound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** FBX data entity that consists of a 'scope', a collection
|
/** FBX data entity that consists of a 'scope', a collection
|
||||||
* of not necessarily unique #Element instances.
|
* of not necessarily unique #Element instances.
|
||||||
*
|
*
|
||||||
|
@ -125,14 +119,10 @@ private:
|
||||||
* @endverbatim */
|
* @endverbatim */
|
||||||
class Scope
|
class Scope
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Scope(Parser& parser, bool topLevel = false);
|
Scope(Parser& parser, bool topLevel = false);
|
||||||
~Scope();
|
~Scope();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
const Element* operator[] (const std::string& index) const {
|
const Element* operator[] (const std::string& index) const {
|
||||||
ElementMap::const_iterator it = elements.find(index);
|
ElementMap::const_iterator it = elements.find(index);
|
||||||
return it == elements.end() ? NULL : (*it).second;
|
return it == elements.end() ? NULL : (*it).second;
|
||||||
|
@ -158,28 +148,23 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ElementMap elements;
|
ElementMap elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** FBX parsing class, takes a list of input tokens and generates a hierarchy
|
/** FBX parsing class, takes a list of input tokens and generates a hierarchy
|
||||||
* of nested #Scope instances, representing the fbx DOM.*/
|
* of nested #Scope instances, representing the fbx DOM.*/
|
||||||
class Parser
|
class Parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Parse given a token list. Does not take ownership of the tokens -
|
/** Parse given a token list. Does not take ownership of the tokens -
|
||||||
* the objects must persist during the entire parser lifetime */
|
* the objects must persist during the entire parser lifetime */
|
||||||
Parser (const TokenList& tokens,bool is_binary);
|
Parser (const TokenList& tokens,bool is_binary);
|
||||||
~Parser();
|
~Parser();
|
||||||
|
|
||||||
public:
|
|
||||||
const Scope& GetRootScope() const {
|
const Scope& GetRootScope() const {
|
||||||
return *root.get();
|
return *root.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IsBinary() const {
|
bool IsBinary() const {
|
||||||
return is_binary;
|
return is_binary;
|
||||||
}
|
}
|
||||||
|
@ -233,8 +218,6 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el);
|
||||||
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
|
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& e);
|
||||||
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
|
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// extract a required element from a scope, abort if the element cannot be found
|
// extract a required element from a scope, abort if the element cannot be found
|
||||||
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
|
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element = NULL);
|
||||||
|
|
||||||
|
@ -243,8 +226,6 @@ const Scope& GetRequiredScope(const Element& el);
|
||||||
// get token at a particular index
|
// get token at a particular index
|
||||||
const Token& GetRequiredToken(const Element& el, unsigned int index);
|
const Token& GetRequiredToken(const Element& el, unsigned int index);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// read a 4x4 matrix from an array of 16 floats
|
// read a 4x4 matrix from an array of 16 floats
|
||||||
aiMatrix4x4 ReadMatrix(const Element& element);
|
aiMatrix4x4 ReadMatrix(const Element& element);
|
||||||
|
|
||||||
|
|
|
@ -55,17 +55,14 @@ namespace FBX {
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class Element;
|
class Element;
|
||||||
|
|
||||||
|
|
||||||
/** Represents a dynamic property. Type info added by deriving classes,
|
/** Represents a dynamic property. Type info added by deriving classes,
|
||||||
* see #TypedProperty.
|
* see #TypedProperty.
|
||||||
Example:
|
Example:
|
||||||
@verbatim
|
@verbatim
|
||||||
P: "ShininessExponent", "double", "Number", "",0.5
|
P: "ShininessExponent", "double", "Number", "",0.5
|
||||||
@endvebatim
|
@endvebatim
|
||||||
|
|
||||||
*/
|
*/
|
||||||
class Property
|
class Property {
|
||||||
{
|
|
||||||
protected:
|
protected:
|
||||||
Property();
|
Property();
|
||||||
|
|
||||||
|
@ -79,17 +76,14 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class TypedProperty : public Property
|
class TypedProperty : public Property {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit TypedProperty(const T& value)
|
explicit TypedProperty(const T& value)
|
||||||
: value(value)
|
: value(value) {
|
||||||
{
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
const T& Value() const {
|
const T& Value() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -106,15 +100,13 @@ typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap;
|
||||||
/**
|
/**
|
||||||
* Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
|
* Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
|
||||||
*/
|
*/
|
||||||
class PropertyTable
|
class PropertyTable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
// in-memory property table with no source element
|
// in-memory property table with no source element
|
||||||
PropertyTable();
|
PropertyTable();
|
||||||
PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps);
|
PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps);
|
||||||
~PropertyTable();
|
~PropertyTable();
|
||||||
|
|
||||||
public:
|
|
||||||
const Property* Get(const std::string& name) const;
|
const Property* Get(const std::string& name) const;
|
||||||
|
|
||||||
// PropertyTable's need not be coupled with FBX elements so this can be NULL
|
// PropertyTable's need not be coupled with FBX elements so this can be NULL
|
||||||
|
@ -135,41 +127,37 @@ private:
|
||||||
const Element* const element;
|
const Element* const element;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
inline
|
||||||
const T& defaultValue)
|
T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
|
||||||
{
|
|
||||||
const Property* const prop = in.Get(name);
|
const Property* const prop = in.Get(name);
|
||||||
if(!prop) {
|
if( nullptr == prop) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// strong typing, no need to be lenient
|
// strong typing, no need to be lenient
|
||||||
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
|
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
|
||||||
if(!tprop) {
|
if( nullptr == tprop) {
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tprop->Value();
|
return tprop->Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
inline
|
||||||
bool& result)
|
T PropertyGet(const PropertyTable& in, const std::string& name, bool& result) {
|
||||||
{
|
|
||||||
const Property* const prop = in.Get(name);
|
const Property* const prop = in.Get(name);
|
||||||
if(!prop) {
|
if( nullptr == prop) {
|
||||||
result = false;
|
result = false;
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
// strong typing, no need to be lenient
|
// strong typing, no need to be lenient
|
||||||
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
|
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
|
||||||
if(!tprop) {
|
if( nullptr == tprop) {
|
||||||
result = false;
|
result = false;
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
@ -178,7 +166,6 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
||||||
return tprop->Value();
|
return tprop->Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} //! FBX
|
} //! FBX
|
||||||
} //! Assimp
|
} //! Assimp
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,6 @@ public:
|
||||||
return std::string(begin(),end());
|
return std::string(begin(),end());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
bool IsBinary() const {
|
bool IsBinary() const {
|
||||||
return column == BINARY_MARKER;
|
return column == BINARY_MARKER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
|
|
||||||
|
// Workaround for issue #1361
|
||||||
|
// https://github.com/assimp/assimp/issues/1361
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#define _GLIBCXX_USE_C99 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "FIReader.hpp"
|
#include "FIReader.hpp"
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
|
@ -162,7 +168,7 @@ struct FIBase64ValueImpl: public FIBase64Value {
|
||||||
if (!strValueValid) {
|
if (!strValueValid) {
|
||||||
strValueValid = true;
|
strValueValid = true;
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
uint8_t c1, c2;
|
uint8_t c1 = 0, c2;
|
||||||
int imod3 = 0;
|
int imod3 = 0;
|
||||||
std::vector<uint8_t>::size_type valueSize = value.size();
|
std::vector<uint8_t>::size_type valueSize = value.size();
|
||||||
for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
|
for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
|
||||||
|
|
|
@ -111,7 +111,7 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <class T>
|
template <class T>
|
||||||
inline const bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
inline bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||||
const char* szName)
|
const char* szName)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szName);
|
ai_assert(NULL != szName);
|
||||||
|
|
|
@ -448,7 +448,8 @@ void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
|
||||||
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
|
void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
|
||||||
const unsigned char** szCursorOut)
|
const unsigned char** szCursorOut)
|
||||||
{
|
{
|
||||||
ai_assert(0 != iNumSkins && NULL != szCursor);
|
ai_assert( 0 != iNumSkins );
|
||||||
|
ai_assert( nullptr != szCursor);
|
||||||
|
|
||||||
// read the type of the skin ...
|
// read the type of the skin ...
|
||||||
// sometimes we need to skip 12 bytes here, I don't know why ...
|
// sometimes we need to skip 12 bytes here, I don't know why ...
|
||||||
|
|
|
@ -272,7 +272,6 @@ bool IntersectsBoundaryProfile(const IfcVector3& e0, const IfcVector3& e1, const
|
||||||
const IfcVector3& b0 = boundary[i];
|
const IfcVector3& b0 = boundary[i];
|
||||||
const IfcVector3& b1 = boundary[(i + 1) % bcount];
|
const IfcVector3& b1 = boundary[(i + 1) % bcount];
|
||||||
IfcVector3 b = b1 - b0;
|
IfcVector3 b = b1 - b0;
|
||||||
IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
|
|
||||||
|
|
||||||
// segment-segment intersection
|
// segment-segment intersection
|
||||||
// solve b0 + b*s = e0 + e*t for (s,t)
|
// solve b0 + b*s = e0 + e*t for (s,t)
|
||||||
|
@ -281,6 +280,7 @@ bool IntersectsBoundaryProfile(const IfcVector3& e0, const IfcVector3& e1, const
|
||||||
// no solutions (parallel lines)
|
// no solutions (parallel lines)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
|
||||||
|
|
||||||
const IfcFloat x = b0.x - e0.x;
|
const IfcFloat x = b0.x - e0.x;
|
||||||
const IfcFloat y = b0.y - e0.y;
|
const IfcFloat y = b0.y - e0.y;
|
||||||
|
@ -381,7 +381,6 @@ bool PointInPoly(const IfcVector3& p, const std::vector<IfcVector3>& boundary)
|
||||||
IntersectsBoundaryProfile(p, p + IfcVector3(0.6, -0.6, 0.0), boundary, true, intersected_boundary, true);
|
IntersectsBoundaryProfile(p, p + IfcVector3(0.6, -0.6, 0.0), boundary, true, intersected_boundary, true);
|
||||||
votes += intersected_boundary.size() % 2;
|
votes += intersected_boundary.size() % 2;
|
||||||
|
|
||||||
// ai_assert(votes == 3 || votes == 0);
|
|
||||||
return votes > 1;
|
return votes > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -548,8 +548,6 @@ bool Curve :: InRange(IfcFloat u) const
|
||||||
const ParamRange range = GetParametricRange();
|
const ParamRange range = GetParametricRange();
|
||||||
if (IsClosed()) {
|
if (IsClosed()) {
|
||||||
return true;
|
return true;
|
||||||
//ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
|
|
||||||
//u = range.first + std::fmod(u-range.first,range.second-range.first);
|
|
||||||
}
|
}
|
||||||
const IfcFloat epsilon = 1e-5;
|
const IfcFloat epsilon = 1e-5;
|
||||||
return u - range.first > -epsilon && range.second - u > -epsilon;
|
return u - range.first > -epsilon && range.second - u > -epsilon;
|
||||||
|
|
|
@ -66,7 +66,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template<> const std::string LogFunctions<IFCImporter>::log_prefix = "IFC: ";
|
template<> const char* LogFunctions<IFCImporter>::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "IFC: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -1492,7 +1492,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||||
vmax -= vmin;
|
vmax -= vmin;
|
||||||
|
|
||||||
// If this happens then the projection must have been wrong.
|
// If this happens then the projection must have been wrong.
|
||||||
assert(vmax.Length());
|
ai_assert(vmax.Length());
|
||||||
|
|
||||||
ClipperLib::ExPolygons clipped;
|
ClipperLib::ExPolygons clipped;
|
||||||
ClipperLib::Polygons holes_union;
|
ClipperLib::Polygons holes_union;
|
||||||
|
@ -1616,7 +1616,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||||
std::vector<IfcVector3> tmpvec;
|
std::vector<IfcVector3> tmpvec;
|
||||||
for(ClipperLib::Polygon& opening : holes_union) {
|
for(ClipperLib::Polygon& opening : holes_union) {
|
||||||
|
|
||||||
assert(ClipperLib::Orientation(opening));
|
ai_assert(ClipperLib::Orientation(opening));
|
||||||
|
|
||||||
tmpvec.clear();
|
tmpvec.clear();
|
||||||
|
|
||||||
|
@ -1705,7 +1705,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||||
static_cast<IfcFloat>( tri->GetPoint(i)->y )
|
static_cast<IfcFloat>( tri->GetPoint(i)->y )
|
||||||
);
|
);
|
||||||
|
|
||||||
assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0);
|
ai_assert(v.x <= 1.0 && v.x >= 0.0 && v.y <= 1.0 && v.y >= 0.0);
|
||||||
const IfcVector3 v3 = minv * IfcVector3(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ;
|
const IfcVector3 v3 = minv * IfcVector3(vmin.x + v.x * vmax.x, vmin.y + v.y * vmax.y,coord) ;
|
||||||
|
|
||||||
curmesh.verts.push_back(v3);
|
curmesh.verts.push_back(v3);
|
||||||
|
|
|
@ -128,7 +128,7 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh&
|
||||||
meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
|
meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
|
||||||
}
|
}
|
||||||
|
|
||||||
meshout.vertcnt.push_back(segments);
|
meshout.vertcnt.push_back(static_cast<unsigned int>(segments));
|
||||||
}
|
}
|
||||||
else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
|
else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
|
||||||
// construct simplified IBeam shape
|
// construct simplified IBeam shape
|
||||||
|
|
|
@ -284,11 +284,17 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
bool isEndOfCache( size_t pos, size_t cacheSize ) {
|
||||||
|
return ( pos == cacheSize );
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline
|
||||||
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
|
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
|
||||||
buffer.resize(m_cacheSize);
|
buffer.resize(m_cacheSize);
|
||||||
if (m_cachePos == m_cacheSize || 0 == m_filePos) {
|
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
|
||||||
if (!readNextBlock()) {
|
if (!readNextBlock()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -300,11 +306,16 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
|
||||||
++m_cachePos;
|
++m_cachePos;
|
||||||
}
|
}
|
||||||
++m_cachePos;
|
++m_cachePos;
|
||||||
|
if ( isEndOfCache( m_cachePos, m_cacheSize ) ) {
|
||||||
|
if ( !readNextBlock() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (!IsLineEnd(m_cache[m_cachePos])) {
|
while (!IsLineEnd(m_cache[ m_cachePos ])) {
|
||||||
buffer[i] = m_cache[m_cachePos];
|
buffer[i] = m_cache[ m_cachePos ];
|
||||||
m_cachePos++;
|
m_cachePos++;
|
||||||
i++;
|
i++;
|
||||||
if (m_cachePos >= m_cacheSize) {
|
if (m_cachePos >= m_cacheSize) {
|
||||||
|
|
|
@ -182,6 +182,7 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
# include "glTFImporter.h"
|
# include "glTFImporter.h"
|
||||||
|
# include "glTF2Importer.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
# include "C4DImporter.h"
|
# include "C4DImporter.h"
|
||||||
|
@ -336,6 +337,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
||||||
#endif
|
#endif
|
||||||
#if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER )
|
||||||
out.push_back( new glTFImporter() );
|
out.push_back( new glTFImporter() );
|
||||||
|
out.push_back( new glTF2Importer() );
|
||||||
#endif
|
#endif
|
||||||
#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
|
#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||||
out.push_back( new C4DImporter() );
|
out.push_back( new C4DImporter() );
|
||||||
|
|
|
@ -60,34 +60,34 @@ public:
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void ThrowException(const std::string& msg)
|
static void ThrowException(const std::string& msg)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError(log_prefix+msg);
|
throw DeadlyImportError(Prefix()+msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void LogWarn(const Formatter::format& message) {
|
static void LogWarn(const Formatter::format& message) {
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
DefaultLogger::get()->warn(log_prefix+(std::string)message);
|
DefaultLogger::get()->warn(Prefix()+(std::string)message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void LogError(const Formatter::format& message) {
|
static void LogError(const Formatter::format& message) {
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
DefaultLogger::get()->error(log_prefix+(std::string)message);
|
DefaultLogger::get()->error(Prefix()+(std::string)message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void LogInfo(const Formatter::format& message) {
|
static void LogInfo(const Formatter::format& message) {
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
DefaultLogger::get()->info(log_prefix+(std::string)message);
|
DefaultLogger::get()->info(Prefix()+(std::string)message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void LogDebug(const Formatter::format& message) {
|
static void LogDebug(const Formatter::format& message) {
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
DefaultLogger::get()->debug(log_prefix+(std::string)message);
|
DefaultLogger::get()->debug(Prefix()+(std::string)message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +125,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static const char* Prefix();
|
||||||
static const std::string log_prefix;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -126,16 +126,16 @@ struct Header {
|
||||||
int32_t version;
|
int32_t version;
|
||||||
|
|
||||||
//! scale factors for each axis
|
//! scale factors for each axis
|
||||||
aiVector3D scale;
|
ai_real scale[3];
|
||||||
|
|
||||||
//! translation factors for each axis
|
//! translation factors for each axis
|
||||||
aiVector3D translate;
|
ai_real translate[3];
|
||||||
|
|
||||||
//! bounding radius of the mesh
|
//! bounding radius of the mesh
|
||||||
float boundingradius;
|
float boundingradius;
|
||||||
|
|
||||||
//! Position of the viewer's exe. Ignored
|
//! Position of the viewer's exe. Ignored
|
||||||
aiVector3D vEyePos;
|
ai_real vEyePos[3];
|
||||||
|
|
||||||
//! Number of textures
|
//! Number of textures
|
||||||
int32_t num_skins;
|
int32_t num_skins;
|
||||||
|
@ -164,7 +164,7 @@ struct Header {
|
||||||
|
|
||||||
//! Could be the total size of the file (and not a float)
|
//! Could be the total size of the file (and not a float)
|
||||||
float size;
|
float size;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -223,7 +223,7 @@ struct Header_MDL7 {
|
||||||
|
|
||||||
//! Size of the Frame_MDL7 data structure used in the file
|
//! Size of the Frame_MDL7 data structure used in the file
|
||||||
uint16_t frame_stc_size;
|
uint16_t frame_stc_size;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -242,7 +242,7 @@ struct Bone_MDL7 {
|
||||||
|
|
||||||
//! Optional name of the bone
|
//! Optional name of the bone
|
||||||
char name[1 /* DUMMY SIZE */];
|
char name[1 /* DUMMY SIZE */];
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
||||||
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
||||||
|
@ -290,7 +290,7 @@ struct Group_MDL7 {
|
||||||
|
|
||||||
//! Number of frames
|
//! Number of frames
|
||||||
int32_t numframes;
|
int32_t numframes;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
|
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
|
||||||
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
|
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
|
||||||
|
@ -312,7 +312,7 @@ struct Deformer_MDL7 {
|
||||||
int32_t group_index;
|
int32_t group_index;
|
||||||
int32_t elements;
|
int32_t elements;
|
||||||
int32_t deformerdata_size;
|
int32_t deformerdata_size;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -324,7 +324,7 @@ struct DeformerElement_MDL7 {
|
||||||
int32_t element_index;
|
int32_t element_index;
|
||||||
char element_name[AI_MDL7_MAX_BONENAMESIZE];
|
char element_name[AI_MDL7_MAX_BONENAMESIZE];
|
||||||
int32_t weights;
|
int32_t weights;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct DeformerWeight_MDL7
|
/** \struct DeformerWeight_MDL7
|
||||||
|
@ -334,7 +334,7 @@ struct DeformerWeight_MDL7 {
|
||||||
//! for deformer_typ==0 (==bones) index == vertex index
|
//! for deformer_typ==0 (==bones) index == vertex index
|
||||||
int32_t index;
|
int32_t index;
|
||||||
float weight;
|
float weight;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// don't know why this was in the original headers ...
|
// don't know why this was in the original headers ...
|
||||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||||
|
@ -345,7 +345,7 @@ typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||||
*/
|
*/
|
||||||
struct ColorValue_MDL7 {
|
struct ColorValue_MDL7 {
|
||||||
float r,g,b,a;
|
float r,g,b,a;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Material_MDL7
|
/** \struct Material_MDL7
|
||||||
|
@ -366,7 +366,7 @@ struct Material_MDL7 {
|
||||||
|
|
||||||
//! Phong power
|
//! Phong power
|
||||||
float Power;
|
float Power;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Skin
|
/** \struct Skin
|
||||||
|
@ -388,7 +388,7 @@ struct Skin {
|
||||||
|
|
||||||
//! Texture data
|
//! Texture data
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -399,7 +399,7 @@ struct Skin {
|
||||||
struct Skin_MDL5 {
|
struct Skin_MDL5 {
|
||||||
int32_t size, width, height;
|
int32_t size, width, height;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// maximum length of texture file name
|
// maximum length of texture file name
|
||||||
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
||||||
|
@ -416,7 +416,7 @@ struct Skin_MDL7 {
|
||||||
int32_t width;
|
int32_t width;
|
||||||
int32_t height;
|
int32_t height;
|
||||||
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct RGB565
|
/** \struct RGB565
|
||||||
|
@ -426,7 +426,7 @@ struct RGB565 {
|
||||||
uint16_t r : 5;
|
uint16_t r : 5;
|
||||||
uint16_t g : 6;
|
uint16_t g : 6;
|
||||||
uint16_t b : 5;
|
uint16_t b : 5;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct ARGB4
|
/** \struct ARGB4
|
||||||
|
@ -455,7 +455,7 @@ struct GroupSkin {
|
||||||
|
|
||||||
//! Data of each image
|
//! Data of each image
|
||||||
uint8_t **data;
|
uint8_t **data;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord
|
/** \struct TexCoord
|
||||||
|
@ -470,7 +470,7 @@ struct TexCoord {
|
||||||
|
|
||||||
//! Texture coordinate in the ty direction
|
//! Texture coordinate in the ty direction
|
||||||
int32_t t;
|
int32_t t;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord_MDL3
|
/** \struct TexCoord_MDL3
|
||||||
|
@ -482,7 +482,7 @@ struct TexCoord_MDL3 {
|
||||||
|
|
||||||
//! position, vertically in range 0..skinheight-1
|
//! position, vertically in range 0..skinheight-1
|
||||||
int16_t v;
|
int16_t v;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct TexCoord_MDL7
|
/** \struct TexCoord_MDL7
|
||||||
|
@ -494,7 +494,7 @@ struct TexCoord_MDL7 {
|
||||||
|
|
||||||
//! position, vertically in range 0..1
|
//! position, vertically in range 0..1
|
||||||
float v;
|
float v;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct SkinSet_MDL7
|
/** \struct SkinSet_MDL7
|
||||||
|
@ -510,7 +510,7 @@ struct SkinSet_MDL7
|
||||||
|
|
||||||
//! Material index
|
//! Material index
|
||||||
int32_t material; // size 4
|
int32_t material; // size 4
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle
|
/** \struct Triangle
|
||||||
|
@ -523,7 +523,7 @@ struct Triangle
|
||||||
|
|
||||||
//! Vertex indices
|
//! Vertex indices
|
||||||
int32_t vertex[3];
|
int32_t vertex[3];
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle_MDL3
|
/** \struct Triangle_MDL3
|
||||||
|
@ -536,7 +536,7 @@ struct Triangle_MDL3
|
||||||
|
|
||||||
//! Index of 3 skin vertices in range 0..numskinverts
|
//! Index of 3 skin vertices in range 0..numskinverts
|
||||||
uint16_t index_uv[3];
|
uint16_t index_uv[3];
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Triangle_MDL7
|
/** \struct Triangle_MDL7
|
||||||
|
@ -549,7 +549,7 @@ struct Triangle_MDL7
|
||||||
|
|
||||||
//! Two skinsets. The second will be used for multi-texturing
|
//! Two skinsets. The second will be used for multi-texturing
|
||||||
SkinSet_MDL7 skinsets[2];
|
SkinSet_MDL7 skinsets[2];
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
||||||
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
|
# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
|
||||||
|
@ -577,7 +577,7 @@ struct Vertex
|
||||||
{
|
{
|
||||||
uint8_t v[3];
|
uint8_t v[3];
|
||||||
uint8_t normalIndex;
|
uint8_t normalIndex;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -603,7 +603,7 @@ struct Vertex_MDL7
|
||||||
uint8_t norm162index;
|
uint8_t norm162index;
|
||||||
float norm[3];
|
float norm[3];
|
||||||
};
|
};
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct BoneTransform_MDL7
|
/** \struct BoneTransform_MDL7
|
||||||
|
@ -620,7 +620,7 @@ struct BoneTransform_MDL7
|
||||||
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
|
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
|
||||||
//! THIS STUPID FILE FORMAT!
|
//! THIS STUPID FILE FORMAT!
|
||||||
int8_t _unused_[2];
|
int8_t _unused_[2];
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
||||||
|
@ -654,7 +654,7 @@ struct SimpleFrame
|
||||||
|
|
||||||
//! Vertex list of the frame
|
//! Vertex list of the frame
|
||||||
Vertex *verts;
|
Vertex *verts;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct Frame
|
/** \struct Frame
|
||||||
|
@ -667,7 +667,7 @@ struct Frame
|
||||||
|
|
||||||
//! Frame data
|
//! Frame data
|
||||||
SimpleFrame frame;
|
SimpleFrame frame;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
|
@ -684,7 +684,7 @@ struct SimpleFrame_MDLn_SP
|
||||||
|
|
||||||
//! Vertex list of the frame
|
//! Vertex list of the frame
|
||||||
Vertex_MDL4 *verts;
|
Vertex_MDL4 *verts;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------
|
||||||
/** \struct GroupFrame
|
/** \struct GroupFrame
|
||||||
|
@ -706,7 +706,7 @@ struct GroupFrame
|
||||||
|
|
||||||
//! List of single frames
|
//! List of single frames
|
||||||
SimpleFrame *frames;
|
SimpleFrame *frames;
|
||||||
} /* PACK_STRUCT */;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
#include "./../include/assimp/Compiler/poppack1.h"
|
#include "./../include/assimp/Compiler/poppack1.h"
|
||||||
|
|
||||||
|
|
|
@ -1132,7 +1132,9 @@ bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInf
|
||||||
const unsigned char* szCurrent,
|
const unsigned char* szCurrent,
|
||||||
const unsigned char** szCurrentOut)
|
const unsigned char** szCurrentOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szCurrent && NULL != szCurrentOut);
|
ai_assert( nullptr != szCurrent );
|
||||||
|
ai_assert( nullptr != szCurrentOut);
|
||||||
|
|
||||||
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)mBuffer;
|
const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)mBuffer;
|
||||||
|
|
||||||
// if we have no bones we can simply skip all frames,
|
// if we have no bones we can simply skip all frames,
|
||||||
|
|
|
@ -118,7 +118,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
|
||||||
|
|
||||||
// Get the file-size and validate it, throwing an exception when fails
|
// Get the file-size and validate it, throwing an exception when fails
|
||||||
fileStream.seekg(0, fileStream.end);
|
fileStream.seekg(0, fileStream.end);
|
||||||
size_t fileSize = fileStream.tellg();
|
size_t fileSize = static_cast<size_t>(fileStream.tellg());
|
||||||
fileStream.seekg(0, fileStream.beg);
|
fileStream.seekg(0, fileStream.beg);
|
||||||
|
|
||||||
if (fileSize < sizeof(pmx::PmxModel)) {
|
if (fileSize < sizeof(pmx::PmxModel)) {
|
||||||
|
@ -278,7 +278,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
||||||
bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
|
bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
|
||||||
aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
|
aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
|
||||||
bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
|
bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
|
||||||
aiVertexWeight(index, 1.0 - vsBDEF2_ptr->bone_weight));
|
aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight));
|
||||||
break;
|
break;
|
||||||
case pmx::PmxVertexSkinningType::BDEF4:
|
case pmx::PmxVertexSkinningType::BDEF4:
|
||||||
bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
|
bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
|
||||||
|
@ -295,7 +295,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
||||||
bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
|
bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
|
||||||
aiVertexWeight(index, vsSDEF_ptr->bone_weight));
|
aiVertexWeight(index, vsSDEF_ptr->bone_weight));
|
||||||
bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
|
bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
|
||||||
aiVertexWeight(index, 1.0 - vsSDEF_ptr->bone_weight));
|
aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight));
|
||||||
break;
|
break;
|
||||||
case pmx::PmxVertexSkinningType::QDEF:
|
case pmx::PmxVertexSkinningType::QDEF:
|
||||||
const auto vsQDEF_ptr =
|
const auto vsQDEF_ptr =
|
||||||
|
@ -325,7 +325,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
||||||
aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
|
aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
|
||||||
auto it = bone_vertex_map.find(ii);
|
auto it = bone_vertex_map.find(ii);
|
||||||
if (it != bone_vertex_map.end()) {
|
if (it != bone_vertex_map.end()) {
|
||||||
pBone->mNumWeights = it->second.size();
|
pBone->mNumWeights = static_cast<unsigned int>(it->second.size());
|
||||||
pBone->mWeights = it->second.data();
|
pBone->mWeights = it->second.data();
|
||||||
it->second.swap(*(new vector<aiVertexWeight>));
|
it->second.swap(*(new vector<aiVertexWeight>));
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,17 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace pmd
|
namespace pmd
|
||||||
{
|
{
|
||||||
/// ヘッダ
|
|
||||||
class PmdHeader
|
class PmdHeader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// モデル名
|
|
||||||
std::string name;
|
std::string name;
|
||||||
/// モデル名(英語)
|
|
||||||
std::string name_english;
|
std::string name_english;
|
||||||
/// コメント
|
|
||||||
std::string comment;
|
std::string comment;
|
||||||
/// コメント(英語)
|
|
||||||
std::string comment_english;
|
std::string comment_english;
|
||||||
|
|
||||||
bool Read(std::ifstream* stream)
|
bool Read(std::ifstream* stream)
|
||||||
|
@ -83,26 +78,19 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 頂点
|
|
||||||
class PmdVertex
|
class PmdVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
|
|
||||||
/// 法線
|
|
||||||
float normal[3];
|
float normal[3];
|
||||||
|
|
||||||
/// UV座標
|
|
||||||
float uv[2];
|
float uv[2];
|
||||||
|
|
||||||
/// 関連ボーンインデックス
|
|
||||||
uint16_t bone_index[2];
|
uint16_t bone_index[2];
|
||||||
|
|
||||||
/// ボーンウェイト
|
|
||||||
uint8_t bone_weight;
|
uint8_t bone_weight;
|
||||||
|
|
||||||
/// エッジ不可視
|
|
||||||
bool edge_invisible;
|
bool edge_invisible;
|
||||||
|
|
||||||
bool Read(std::ifstream* stream)
|
bool Read(std::ifstream* stream)
|
||||||
|
@ -117,27 +105,17 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 材質
|
|
||||||
class PmdMaterial
|
class PmdMaterial
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// 減衰色
|
|
||||||
float diffuse[4];
|
float diffuse[4];
|
||||||
/// 光沢度
|
|
||||||
float power;
|
float power;
|
||||||
/// 光沢色
|
|
||||||
float specular[3];
|
float specular[3];
|
||||||
/// 環境色
|
|
||||||
float ambient[3];
|
float ambient[3];
|
||||||
/// トーンインデックス
|
|
||||||
uint8_t toon_index;
|
uint8_t toon_index;
|
||||||
/// エッジ
|
|
||||||
uint8_t edge_flag;
|
uint8_t edge_flag;
|
||||||
/// インデックス数
|
|
||||||
uint32_t index_count;
|
uint32_t index_count;
|
||||||
/// テクスチャファイル名
|
|
||||||
std::string texture_filename;
|
std::string texture_filename;
|
||||||
/// スフィアファイル名
|
|
||||||
std::string sphere_filename;
|
std::string sphere_filename;
|
||||||
|
|
||||||
bool Read(std::ifstream* stream)
|
bool Read(std::ifstream* stream)
|
||||||
|
@ -158,7 +136,7 @@ namespace pmd
|
||||||
sphere_filename.clear();
|
sphere_filename.clear();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*pstar = (char)NULL;
|
*pstar = 0;
|
||||||
texture_filename = std::string(buffer);
|
texture_filename = std::string(buffer);
|
||||||
sphere_filename = std::string(pstar+1);
|
sphere_filename = std::string(pstar+1);
|
||||||
}
|
}
|
||||||
|
@ -180,23 +158,15 @@ namespace pmd
|
||||||
RotationMovement
|
RotationMovement
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ボーン
|
|
||||||
class PmdBone
|
class PmdBone
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// ボーン名
|
|
||||||
std::string name;
|
std::string name;
|
||||||
/// ボーン名(英語)
|
|
||||||
std::string name_english;
|
std::string name_english;
|
||||||
/// 親ボーン番号
|
|
||||||
uint16_t parent_bone_index;
|
uint16_t parent_bone_index;
|
||||||
/// 末端ボーン番号
|
|
||||||
uint16_t tail_pos_bone_index;
|
uint16_t tail_pos_bone_index;
|
||||||
/// ボーン種類
|
|
||||||
BoneType bone_type;
|
BoneType bone_type;
|
||||||
/// IKボーン番号
|
|
||||||
uint16_t ik_parent_bone_index;
|
uint16_t ik_parent_bone_index;
|
||||||
/// ボーンのヘッドの位置
|
|
||||||
float bone_head_pos[3];
|
float bone_head_pos[3];
|
||||||
|
|
||||||
void Read(std::istream *stream)
|
void Read(std::istream *stream)
|
||||||
|
@ -219,19 +189,13 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// IK
|
|
||||||
class PmdIk
|
class PmdIk
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// IKボーン番号
|
|
||||||
uint16_t ik_bone_index;
|
uint16_t ik_bone_index;
|
||||||
/// IKターゲットボーン番号
|
|
||||||
uint16_t target_bone_index;
|
uint16_t target_bone_index;
|
||||||
/// 再帰回数
|
|
||||||
uint16_t interations;
|
uint16_t interations;
|
||||||
/// 角度制限
|
|
||||||
float angle_limit;
|
float angle_limit;
|
||||||
/// 影響下ボーン番号
|
|
||||||
std::vector<uint16_t> ik_child_bone_index;
|
std::vector<uint16_t> ik_child_bone_index;
|
||||||
|
|
||||||
void Read(std::istream *stream)
|
void Read(std::istream *stream)
|
||||||
|
@ -303,7 +267,6 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ボーン枠用の枠名
|
|
||||||
class PmdBoneDispName
|
class PmdBoneDispName
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -338,59 +301,36 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 衝突形状
|
|
||||||
enum class RigidBodyShape : uint8_t
|
enum class RigidBodyShape : uint8_t
|
||||||
{
|
{
|
||||||
/// 球
|
|
||||||
Sphere = 0,
|
Sphere = 0,
|
||||||
/// 直方体
|
|
||||||
Box = 1,
|
Box = 1,
|
||||||
/// カプセル
|
|
||||||
Cpusel = 2
|
Cpusel = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 剛体タイプ
|
|
||||||
enum class RigidBodyType : uint8_t
|
enum class RigidBodyType : uint8_t
|
||||||
{
|
{
|
||||||
/// ボーン追従
|
|
||||||
BoneConnected = 0,
|
BoneConnected = 0,
|
||||||
/// 物理演算
|
|
||||||
Physics = 1,
|
Physics = 1,
|
||||||
/// 物理演算(Bone位置合せ)
|
|
||||||
ConnectedPhysics = 2
|
ConnectedPhysics = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 剛体
|
|
||||||
class PmdRigidBody
|
class PmdRigidBody
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// 名前
|
|
||||||
std::string name;
|
std::string name;
|
||||||
/// 関連ボーン番号
|
|
||||||
uint16_t related_bone_index;
|
uint16_t related_bone_index;
|
||||||
/// グループ番号
|
|
||||||
uint8_t group_index;
|
uint8_t group_index;
|
||||||
/// マスク
|
|
||||||
uint16_t mask;
|
uint16_t mask;
|
||||||
/// 形状
|
|
||||||
RigidBodyShape shape;
|
RigidBodyShape shape;
|
||||||
/// 大きさ
|
|
||||||
float size[3];
|
float size[3];
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
/// 回転
|
|
||||||
float orientation[3];
|
float orientation[3];
|
||||||
/// 質量
|
|
||||||
float weight;
|
float weight;
|
||||||
/// 移動ダンピング
|
|
||||||
float linear_damping;
|
float linear_damping;
|
||||||
/// 回転ダンピング
|
|
||||||
float anglar_damping;
|
float anglar_damping;
|
||||||
/// 反発係数
|
|
||||||
float restitution;
|
float restitution;
|
||||||
/// 摩擦係数
|
|
||||||
float friction;
|
float friction;
|
||||||
/// 演算方法
|
|
||||||
RigidBodyType rigid_type;
|
RigidBodyType rigid_type;
|
||||||
|
|
||||||
void Read(std::istream *stream)
|
void Read(std::istream *stream)
|
||||||
|
@ -414,31 +354,19 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 剛体の拘束
|
|
||||||
class PmdConstraint
|
class PmdConstraint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// 名前
|
|
||||||
std::string name;
|
std::string name;
|
||||||
/// 剛体Aのインデックス
|
|
||||||
uint32_t rigid_body_index_a;
|
uint32_t rigid_body_index_a;
|
||||||
/// 剛体Bのインデックス
|
|
||||||
uint32_t rigid_body_index_b;
|
uint32_t rigid_body_index_b;
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
/// 回転
|
|
||||||
float orientation[3];
|
float orientation[3];
|
||||||
/// 最小移動制限
|
|
||||||
float linear_lower_limit[3];
|
float linear_lower_limit[3];
|
||||||
/// 最大移動制限
|
|
||||||
float linear_upper_limit[3];
|
float linear_upper_limit[3];
|
||||||
/// 最小回転制限
|
|
||||||
float angular_lower_limit[3];
|
float angular_lower_limit[3];
|
||||||
/// 最大回転制限
|
|
||||||
float angular_upper_limit[3];
|
float angular_upper_limit[3];
|
||||||
/// 移動に対する復元力
|
|
||||||
float linear_stiffness[3];
|
float linear_stiffness[3];
|
||||||
/// 回転に対する復元力
|
|
||||||
float angular_stiffness[3];
|
float angular_stiffness[3];
|
||||||
|
|
||||||
void Read(std::istream *stream)
|
void Read(std::istream *stream)
|
||||||
|
@ -459,7 +387,6 @@ namespace pmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// PMDモデル
|
|
||||||
class PmdModel
|
class PmdModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -491,7 +418,6 @@ namespace pmd
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ファイルからPmdModelを生成する
|
|
||||||
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
|
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
|
||||||
{
|
{
|
||||||
auto result = mmd::make_unique<PmdModel>();
|
auto result = mmd::make_unique<PmdModel>();
|
||||||
|
|
|
@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
{
|
{
|
||||||
/// インデックス値を読み込む
|
|
||||||
int ReadIndex(std::istream *stream, int size)
|
int ReadIndex(std::istream *stream, int size)
|
||||||
{
|
{
|
||||||
switch (size)
|
switch (size)
|
||||||
|
@ -79,7 +78,6 @@ namespace pmx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 文字列を読み込む
|
|
||||||
std::string ReadString(std::istream *stream, uint8_t encoding)
|
std::string ReadString(std::istream *stream, uint8_t encoding)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
|
@ -218,8 +216,8 @@ namespace pmx
|
||||||
|
|
||||||
void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
|
void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
|
||||||
{
|
{
|
||||||
this->material_name = std::move(ReadString(stream, setting->encoding));
|
this->material_name = ReadString(stream, setting->encoding);
|
||||||
this->material_english_name = std::move(ReadString(stream, setting->encoding));
|
this->material_english_name = ReadString(stream, setting->encoding);
|
||||||
stream->read((char*) this->diffuse, sizeof(float) * 4);
|
stream->read((char*) this->diffuse, sizeof(float) * 4);
|
||||||
stream->read((char*) this->specular, sizeof(float) * 3);
|
stream->read((char*) this->specular, sizeof(float) * 3);
|
||||||
stream->read((char*) &this->specularlity, sizeof(float));
|
stream->read((char*) &this->specularlity, sizeof(float));
|
||||||
|
@ -238,7 +236,7 @@ namespace pmx
|
||||||
else {
|
else {
|
||||||
this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
|
this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
|
||||||
}
|
}
|
||||||
this->memo = std::move(ReadString(stream, setting->encoding));
|
this->memo = ReadString(stream, setting->encoding);
|
||||||
stream->read((char*) &this->index_count, sizeof(int));
|
stream->read((char*) &this->index_count, sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,8 +253,8 @@ namespace pmx
|
||||||
|
|
||||||
void PmxBone::Read(std::istream *stream, PmxSetting *setting)
|
void PmxBone::Read(std::istream *stream, PmxSetting *setting)
|
||||||
{
|
{
|
||||||
this->bone_name = std::move(ReadString(stream, setting->encoding));
|
this->bone_name = ReadString(stream, setting->encoding);
|
||||||
this->bone_english_name = std::move(ReadString(stream, setting->encoding));
|
this->bone_english_name = ReadString(stream, setting->encoding);
|
||||||
stream->read((char*) this->position, sizeof(float) * 3);
|
stream->read((char*) this->position, sizeof(float) * 3);
|
||||||
this->parent_index = ReadIndex(stream, setting->bone_index_size);
|
this->parent_index = ReadIndex(stream, setting->bone_index_size);
|
||||||
stream->read((char*) &this->level, sizeof(int));
|
stream->read((char*) &this->level, sizeof(int));
|
||||||
|
@ -530,10 +528,10 @@ namespace pmx
|
||||||
this->setting.Read(stream);
|
this->setting.Read(stream);
|
||||||
|
|
||||||
// モデル情報
|
// モデル情報
|
||||||
this->model_name = std::move(ReadString(stream, setting.encoding));
|
this->model_name = ReadString(stream, setting.encoding);
|
||||||
this->model_english_name = std::move(ReadString(stream, setting.encoding));
|
this->model_english_name = ReadString(stream, setting.encoding);
|
||||||
this->model_comment = std::move(ReadString(stream, setting.encoding));
|
this->model_comment = ReadString(stream, setting.encoding);
|
||||||
this->model_english_comment = std::move(ReadString(stream, setting.encoding));
|
this->model_english_comment = ReadString(stream, setting.encoding);
|
||||||
|
|
||||||
// 頂点
|
// 頂点
|
||||||
stream->read((char*) &vertex_count, sizeof(int));
|
stream->read((char*) &vertex_count, sizeof(int));
|
||||||
|
@ -607,7 +605,6 @@ namespace pmx
|
||||||
this->joints[i].Read(stream, &setting);
|
this->joints[i].Read(stream, &setting);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// ソフトボディ
|
|
||||||
//if (this->version == 2.1f)
|
//if (this->version == 2.1f)
|
||||||
//{
|
//{
|
||||||
// stream->read((char*) &this->soft_body_count, sizeof(int));
|
// stream->read((char*) &this->soft_body_count, sizeof(int));
|
||||||
|
|
|
@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace pmx
|
namespace pmx
|
||||||
{
|
{
|
||||||
/// インデックス設定
|
|
||||||
class PmxSetting
|
class PmxSetting
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -64,26 +63,17 @@ namespace pmx
|
||||||
, rigidbody_index_size(0)
|
, rigidbody_index_size(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// エンコード方式
|
|
||||||
uint8_t encoding;
|
uint8_t encoding;
|
||||||
/// 追加UV数
|
|
||||||
uint8_t uv;
|
uint8_t uv;
|
||||||
/// 頂点インデックスサイズ
|
|
||||||
uint8_t vertex_index_size;
|
uint8_t vertex_index_size;
|
||||||
/// テクスチャインデックスサイズ
|
|
||||||
uint8_t texture_index_size;
|
uint8_t texture_index_size;
|
||||||
/// マテリアルインデックスサイズ
|
|
||||||
uint8_t material_index_size;
|
uint8_t material_index_size;
|
||||||
/// ボーンインデックスサイズ
|
|
||||||
uint8_t bone_index_size;
|
uint8_t bone_index_size;
|
||||||
/// モーフインデックスサイズ
|
|
||||||
uint8_t morph_index_size;
|
uint8_t morph_index_size;
|
||||||
/// 剛体インデックスサイズ
|
|
||||||
uint8_t rigidbody_index_size;
|
uint8_t rigidbody_index_size;
|
||||||
void Read(std::istream *stream);
|
void Read(std::istream *stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 頂点スキニングタイプ
|
|
||||||
enum class PmxVertexSkinningType : uint8_t
|
enum class PmxVertexSkinningType : uint8_t
|
||||||
{
|
{
|
||||||
BDEF1 = 0,
|
BDEF1 = 0,
|
||||||
|
@ -93,7 +83,6 @@ namespace pmx
|
||||||
QDEF = 4,
|
QDEF = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 頂点スキニング
|
|
||||||
class PmxVertexSkinning
|
class PmxVertexSkinning
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -200,7 +189,6 @@ namespace pmx
|
||||||
void Read(std::istream *stresam, PmxSetting *setting);
|
void Read(std::istream *stresam, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 頂点
|
|
||||||
class PmxVertex
|
class PmxVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -219,24 +207,16 @@ namespace pmx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
/// 法線
|
|
||||||
float normal[3];
|
float normal[3];
|
||||||
/// テクスチャ座標
|
|
||||||
float uv[2];
|
float uv[2];
|
||||||
/// 追加テクスチャ座標
|
|
||||||
float uva[4][4];
|
float uva[4][4];
|
||||||
/// スキニングタイプ
|
|
||||||
PmxVertexSkinningType skinning_type;
|
PmxVertexSkinningType skinning_type;
|
||||||
/// スキニング
|
|
||||||
std::unique_ptr<PmxVertexSkinning> skinning;
|
std::unique_ptr<PmxVertexSkinning> skinning;
|
||||||
/// エッジ倍率
|
|
||||||
float edge;
|
float edge;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// マテリアル
|
|
||||||
class PmxMaterial
|
class PmxMaterial
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -261,42 +241,25 @@ namespace pmx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// モデル名
|
|
||||||
std::string material_name;
|
std::string material_name;
|
||||||
/// モデル英名
|
|
||||||
std::string material_english_name;
|
std::string material_english_name;
|
||||||
/// 減衰色
|
|
||||||
float diffuse[4];
|
float diffuse[4];
|
||||||
/// 光沢色
|
|
||||||
float specular[3];
|
float specular[3];
|
||||||
/// 光沢度
|
|
||||||
float specularlity;
|
float specularlity;
|
||||||
/// 環境色
|
|
||||||
float ambient[3];
|
float ambient[3];
|
||||||
/// 描画フラグ
|
|
||||||
uint8_t flag;
|
uint8_t flag;
|
||||||
/// エッジ色
|
|
||||||
float edge_color[4];
|
float edge_color[4];
|
||||||
/// エッジサイズ
|
|
||||||
float edge_size;
|
float edge_size;
|
||||||
/// アルベドテクスチャインデックス
|
|
||||||
int diffuse_texture_index;
|
int diffuse_texture_index;
|
||||||
/// スフィアテクスチャインデックス
|
|
||||||
int sphere_texture_index;
|
int sphere_texture_index;
|
||||||
/// スフィアテクスチャ演算モード
|
|
||||||
uint8_t sphere_op_mode;
|
uint8_t sphere_op_mode;
|
||||||
/// 共有トゥーンフラグ
|
|
||||||
uint8_t common_toon_flag;
|
uint8_t common_toon_flag;
|
||||||
/// トゥーンテクスチャインデックス
|
|
||||||
int toon_texture_index;
|
int toon_texture_index;
|
||||||
/// メモ
|
|
||||||
std::string memo;
|
std::string memo;
|
||||||
/// 頂点インデックス数
|
|
||||||
int index_count;
|
int index_count;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// リンク
|
|
||||||
class PmxIkLink
|
class PmxIkLink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -310,18 +273,13 @@ namespace pmx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// リンクボーンインデックス
|
|
||||||
int link_target;
|
int link_target;
|
||||||
/// 角度制限
|
|
||||||
uint8_t angle_lock;
|
uint8_t angle_lock;
|
||||||
/// 最大制限角度
|
|
||||||
float max_radian[3];
|
float max_radian[3];
|
||||||
/// 最小制限角度
|
|
||||||
float min_radian[3];
|
float min_radian[3];
|
||||||
void Read(std::istream *stream, PmxSetting *settingn);
|
void Read(std::istream *stream, PmxSetting *settingn);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ボーン
|
|
||||||
class PmxBone
|
class PmxBone
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -347,43 +305,24 @@ namespace pmx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ボーン名
|
|
||||||
std::string bone_name;
|
std::string bone_name;
|
||||||
/// ボーン英名
|
|
||||||
std::string bone_english_name;
|
std::string bone_english_name;
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
/// 親ボーンインデックス
|
|
||||||
int parent_index;
|
int parent_index;
|
||||||
/// 階層
|
|
||||||
int level;
|
int level;
|
||||||
/// ボーンフラグ
|
|
||||||
uint16_t bone_flag;
|
uint16_t bone_flag;
|
||||||
/// 座標オフセット(has Target)
|
|
||||||
float offset[3];
|
float offset[3];
|
||||||
/// 接続先ボーンインデックス(not has Target)
|
|
||||||
int target_index;
|
int target_index;
|
||||||
/// 付与親ボーンインデックス
|
|
||||||
int grant_parent_index;
|
int grant_parent_index;
|
||||||
/// 付与率
|
|
||||||
float grant_weight;
|
float grant_weight;
|
||||||
/// 固定軸の方向
|
|
||||||
float lock_axis_orientation[3];
|
float lock_axis_orientation[3];
|
||||||
/// ローカル軸のX軸方向
|
|
||||||
float local_axis_x_orientation[3];
|
float local_axis_x_orientation[3];
|
||||||
/// ローカル軸のY軸方向
|
|
||||||
float local_axis_y_orientation[3];
|
float local_axis_y_orientation[3];
|
||||||
/// 外部親変形のkey値
|
|
||||||
int key;
|
int key;
|
||||||
/// IKターゲットボーン
|
|
||||||
int ik_target_bone_index;
|
int ik_target_bone_index;
|
||||||
/// IKループ回数
|
|
||||||
int ik_loop;
|
int ik_loop;
|
||||||
/// IKループ計算時の角度制限(ラジアン)
|
|
||||||
float ik_loop_angle_limit;
|
float ik_loop_angle_limit;
|
||||||
/// IKリンク数
|
|
||||||
int ik_link_count;
|
int ik_link_count;
|
||||||
/// IKリンク
|
|
||||||
std::unique_ptr<PmxIkLink []> ik_links;
|
std::unique_ptr<PmxIkLink []> ik_links;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
@ -543,7 +482,6 @@ namespace pmx
|
||||||
void Read(std::istream *stream, PmxSetting *setting); //override;
|
void Read(std::istream *stream, PmxSetting *setting); //override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// モーフ
|
|
||||||
class PmxMorph
|
class PmxMorph
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -551,34 +489,21 @@ namespace pmx
|
||||||
: offset_count(0)
|
: offset_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/// モーフ名
|
|
||||||
std::string morph_name;
|
std::string morph_name;
|
||||||
/// モーフ英名
|
|
||||||
std::string morph_english_name;
|
std::string morph_english_name;
|
||||||
/// カテゴリ
|
|
||||||
MorphCategory category;
|
MorphCategory category;
|
||||||
/// モーフタイプ
|
|
||||||
MorphType morph_type;
|
MorphType morph_type;
|
||||||
/// オフセット数
|
|
||||||
int offset_count;
|
int offset_count;
|
||||||
/// 頂点モーフ配列
|
|
||||||
std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
|
std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
|
||||||
/// UVモーフ配列
|
|
||||||
std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
|
std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
|
||||||
/// ボーンモーフ配列
|
|
||||||
std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
|
std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
|
||||||
/// マテリアルモーフ配列
|
|
||||||
std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
|
std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
|
||||||
/// グループモーフ配列
|
|
||||||
std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
|
std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
|
||||||
/// フリップモーフ配列
|
|
||||||
std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
|
std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
|
||||||
/// インパルスモーフ配列
|
|
||||||
std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
|
std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 枠内要素
|
|
||||||
class PmxFrameElement
|
class PmxFrameElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -587,14 +512,11 @@ namespace pmx
|
||||||
, index(0)
|
, index(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/// 要素対象
|
|
||||||
uint8_t element_target;
|
uint8_t element_target;
|
||||||
/// 要素対象インデックス
|
|
||||||
int index;
|
int index;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 表示枠
|
|
||||||
class PmxFrame
|
class PmxFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -603,15 +525,10 @@ namespace pmx
|
||||||
, element_count(0)
|
, element_count(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
/// 枠名
|
|
||||||
std::string frame_name;
|
std::string frame_name;
|
||||||
/// 枠英名
|
|
||||||
std::string frame_english_name;
|
std::string frame_english_name;
|
||||||
/// 特殊枠フラグ
|
|
||||||
uint8_t frame_flag;
|
uint8_t frame_flag;
|
||||||
/// 枠内要素数
|
|
||||||
int element_count;
|
int element_count;
|
||||||
/// 枠内要素配列
|
|
||||||
std::unique_ptr<PmxFrameElement []> elements;
|
std::unique_ptr<PmxFrameElement []> elements;
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
@ -637,17 +554,11 @@ namespace pmx
|
||||||
orientation[i] = 0.0f;
|
orientation[i] = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// 剛体名
|
|
||||||
std::string girid_body_name;
|
std::string girid_body_name;
|
||||||
/// 剛体英名
|
|
||||||
std::string girid_body_english_name;
|
std::string girid_body_english_name;
|
||||||
/// 関連ボーンインデックス
|
|
||||||
int target_bone;
|
int target_bone;
|
||||||
/// グループ
|
|
||||||
uint8_t group;
|
uint8_t group;
|
||||||
/// マスク
|
|
||||||
uint16_t mask;
|
uint16_t mask;
|
||||||
/// 形状
|
|
||||||
uint8_t shape;
|
uint8_t shape;
|
||||||
float size[3];
|
float size[3];
|
||||||
float position[3];
|
float position[3];
|
||||||
|
@ -818,7 +729,6 @@ namespace pmx
|
||||||
void Read(std::istream *stream, PmxSetting *setting);
|
void Read(std::istream *stream, PmxSetting *setting);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// PMXモデル
|
|
||||||
class PmxModel
|
class PmxModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -836,65 +746,35 @@ namespace pmx
|
||||||
, soft_body_count(0)
|
, soft_body_count(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// バージョン
|
|
||||||
float version;
|
float version;
|
||||||
/// 設定
|
|
||||||
PmxSetting setting;
|
PmxSetting setting;
|
||||||
/// モデル名
|
|
||||||
std::string model_name;
|
std::string model_name;
|
||||||
/// モデル英名
|
|
||||||
std::string model_english_name;
|
std::string model_english_name;
|
||||||
/// コメント
|
|
||||||
std::string model_comment;
|
std::string model_comment;
|
||||||
/// 英語コメント
|
|
||||||
std::string model_english_comment;
|
std::string model_english_comment;
|
||||||
/// 頂点数
|
|
||||||
int vertex_count;
|
int vertex_count;
|
||||||
/// 頂点配列
|
|
||||||
std::unique_ptr<PmxVertex []> vertices;
|
std::unique_ptr<PmxVertex []> vertices;
|
||||||
/// インデックス数
|
|
||||||
int index_count;
|
int index_count;
|
||||||
/// インデックス配列
|
|
||||||
std::unique_ptr<int []> indices;
|
std::unique_ptr<int []> indices;
|
||||||
/// テクスチャ数
|
|
||||||
int texture_count;
|
int texture_count;
|
||||||
/// テクスチャ配列
|
|
||||||
std::unique_ptr< std::string []> textures;
|
std::unique_ptr< std::string []> textures;
|
||||||
/// マテリアル数
|
|
||||||
int material_count;
|
int material_count;
|
||||||
/// マテリアル
|
|
||||||
std::unique_ptr<PmxMaterial []> materials;
|
std::unique_ptr<PmxMaterial []> materials;
|
||||||
/// ボーン数
|
|
||||||
int bone_count;
|
int bone_count;
|
||||||
/// ボーン配列
|
|
||||||
std::unique_ptr<PmxBone []> bones;
|
std::unique_ptr<PmxBone []> bones;
|
||||||
/// モーフ数
|
|
||||||
int morph_count;
|
int morph_count;
|
||||||
/// モーフ配列
|
|
||||||
std::unique_ptr<PmxMorph []> morphs;
|
std::unique_ptr<PmxMorph []> morphs;
|
||||||
/// 表示枠数
|
|
||||||
int frame_count;
|
int frame_count;
|
||||||
/// 表示枠配列
|
|
||||||
std::unique_ptr<PmxFrame [] > frames;
|
std::unique_ptr<PmxFrame [] > frames;
|
||||||
/// 剛体数
|
|
||||||
int rigid_body_count;
|
int rigid_body_count;
|
||||||
/// 剛体配列
|
|
||||||
std::unique_ptr<PmxRigidBody []> rigid_bodies;
|
std::unique_ptr<PmxRigidBody []> rigid_bodies;
|
||||||
/// ジョイント数
|
|
||||||
int joint_count;
|
int joint_count;
|
||||||
/// ジョイント配列
|
|
||||||
std::unique_ptr<PmxJoint []> joints;
|
std::unique_ptr<PmxJoint []> joints;
|
||||||
/// ソフトボディ数
|
|
||||||
int soft_body_count;
|
int soft_body_count;
|
||||||
/// ソフトボディ配列
|
|
||||||
std::unique_ptr<PmxSoftBody []> soft_bodies;
|
std::unique_ptr<PmxSoftBody []> soft_bodies;
|
||||||
/// モデル初期化
|
|
||||||
void Init();
|
void Init();
|
||||||
/// モデル読み込み
|
|
||||||
void Read(std::istream *stream);
|
void Read(std::istream *stream);
|
||||||
///// ファイルからモデルの読み込み
|
|
||||||
//static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
|
//static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
|
||||||
///// 入力ストリームからモデルの読み込み
|
|
||||||
//static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
|
//static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,19 +50,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace vmd
|
namespace vmd
|
||||||
{
|
{
|
||||||
/// ボーンフレーム
|
|
||||||
class VmdBoneFrame
|
class VmdBoneFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// ボーン名
|
|
||||||
std::string name;
|
std::string name;
|
||||||
/// フレーム番号
|
|
||||||
int frame;
|
int frame;
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
/// 回転
|
|
||||||
float orientation[4];
|
float orientation[4];
|
||||||
/// 補間曲線
|
|
||||||
char interpolation[4][4][4];
|
char interpolation[4][4][4];
|
||||||
|
|
||||||
void Read(std::istream* stream)
|
void Read(std::istream* stream)
|
||||||
|
@ -86,15 +80,11 @@ namespace vmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 表情フレーム
|
|
||||||
class VmdFaceFrame
|
class VmdFaceFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// 表情名
|
|
||||||
std::string face_name;
|
std::string face_name;
|
||||||
/// 表情の重み
|
|
||||||
float weight;
|
float weight;
|
||||||
/// フレーム番号
|
|
||||||
uint32_t frame;
|
uint32_t frame;
|
||||||
|
|
||||||
void Read(std::istream* stream)
|
void Read(std::istream* stream)
|
||||||
|
@ -114,23 +104,15 @@ namespace vmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// カメラフレーム
|
|
||||||
class VmdCameraFrame
|
class VmdCameraFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// フレーム番号
|
|
||||||
int frame;
|
int frame;
|
||||||
/// 距離
|
|
||||||
float distance;
|
float distance;
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
/// 回転
|
|
||||||
float orientation[3];
|
float orientation[3];
|
||||||
/// 補間曲線
|
|
||||||
char interpolation[6][4];
|
char interpolation[6][4];
|
||||||
/// 視野角
|
|
||||||
float angle;
|
float angle;
|
||||||
/// 不明データ
|
|
||||||
char unknown[3];
|
char unknown[3];
|
||||||
|
|
||||||
void Read(std::istream *stream)
|
void Read(std::istream *stream)
|
||||||
|
@ -156,15 +138,11 @@ namespace vmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ライトフレーム
|
|
||||||
class VmdLightFrame
|
class VmdLightFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// フレーム番号
|
|
||||||
int frame;
|
int frame;
|
||||||
/// 色
|
|
||||||
float color[3];
|
float color[3];
|
||||||
/// 位置
|
|
||||||
float position[3];
|
float position[3];
|
||||||
|
|
||||||
void Read(std::istream* stream)
|
void Read(std::istream* stream)
|
||||||
|
@ -182,7 +160,6 @@ namespace vmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// IKの有効無効
|
|
||||||
class VmdIkEnable
|
class VmdIkEnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -190,7 +167,6 @@ namespace vmd
|
||||||
bool enable;
|
bool enable;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// IKフレーム
|
|
||||||
class VmdIkFrame
|
class VmdIkFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -229,23 +205,15 @@ namespace vmd
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// VMDモーション
|
|
||||||
class VmdMotion
|
class VmdMotion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// モデル名
|
|
||||||
std::string model_name;
|
std::string model_name;
|
||||||
/// バージョン
|
|
||||||
int version;
|
int version;
|
||||||
/// ボーンフレーム
|
|
||||||
std::vector<VmdBoneFrame> bone_frames;
|
std::vector<VmdBoneFrame> bone_frames;
|
||||||
/// 表情フレーム
|
|
||||||
std::vector<VmdFaceFrame> face_frames;
|
std::vector<VmdFaceFrame> face_frames;
|
||||||
/// カメラフレーム
|
|
||||||
std::vector<VmdCameraFrame> camera_frames;
|
std::vector<VmdCameraFrame> camera_frames;
|
||||||
/// ライトフレーム
|
|
||||||
std::vector<VmdLightFrame> light_frames;
|
std::vector<VmdLightFrame> light_frames;
|
||||||
/// IKフレーム
|
|
||||||
std::vector<VmdIkFrame> ik_frames;
|
std::vector<VmdIkFrame> ik_frames;
|
||||||
|
|
||||||
static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
|
static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
|
||||||
|
|
|
@ -193,14 +193,14 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
||||||
p = 0;
|
p = 0;
|
||||||
while (pcMesh->HasTextureCoords(p))
|
while (pcMesh->HasTextureCoords(p))
|
||||||
{
|
{
|
||||||
delete pcMesh->mTextureCoords[p];
|
delete[] pcMesh->mTextureCoords[p];
|
||||||
pcMesh->mTextureCoords[p] = apvTextureCoords[p];
|
pcMesh->mTextureCoords[p] = apvTextureCoords[p];
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
p = 0;
|
p = 0;
|
||||||
while (pcMesh->HasVertexColors(p))
|
while (pcMesh->HasVertexColors(p))
|
||||||
{
|
{
|
||||||
delete pcMesh->mColors[p];
|
delete[] pcMesh->mColors[p];
|
||||||
pcMesh->mColors[p] = apvColorSets[p];
|
pcMesh->mColors[p] = apvColorSets[p];
|
||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
||||||
{
|
{
|
||||||
if (!pIOHandler)return true;
|
if (!pIOHandler)return true;
|
||||||
const char* tokens[] = {"off"};
|
const char* tokens[] = {"off"};
|
||||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,3);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,11 +91,11 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene)
|
||||||
, vn()
|
, vn()
|
||||||
, vt()
|
, vt()
|
||||||
, vc()
|
, vc()
|
||||||
, vpMap()
|
, mVpMap()
|
||||||
, vnMap()
|
, mVnMap()
|
||||||
, vtMap()
|
, mVtMap()
|
||||||
, vcMap()
|
, mVcMap()
|
||||||
, meshes()
|
, mMeshes()
|
||||||
, endl("\n") {
|
, endl("\n") {
|
||||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||||
const std::locale& l = std::locale("C");
|
const std::locale& l = std::locale("C");
|
||||||
|
@ -137,15 +137,21 @@ std::string ObjExporter::GetMaterialLibFileName() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ObjExporter :: WriteHeader(std::ostringstream& out) {
|
void ObjExporter::WriteHeader(std::ostringstream& out) {
|
||||||
out << "# File produced by Open Asset Import Library (http://www.assimp.sf.net)" << endl;
|
out << "# File produced by Open Asset Import Library (http://www.assimp.sf.net)" << endl;
|
||||||
out << "# (assimp v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.' << aiGetVersionRevision() << ")" << endl << endl;
|
out << "# (assimp v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
|
||||||
|
<< aiGetVersionRevision() << ")" << endl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
std::string ObjExporter :: GetMaterialName(unsigned int index)
|
std::string ObjExporter::GetMaterialName(unsigned int index)
|
||||||
{
|
{
|
||||||
const aiMaterial* const mat = pScene->mMaterials[index];
|
const aiMaterial* const mat = pScene->mMaterials[index];
|
||||||
|
if ( nullptr == mat ) {
|
||||||
|
static const std::string EmptyStr;
|
||||||
|
return EmptyStr;
|
||||||
|
}
|
||||||
|
|
||||||
aiString s;
|
aiString s;
|
||||||
if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) {
|
if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) {
|
||||||
return std::string(s.data,s.length);
|
return std::string(s.data,s.length);
|
||||||
|
@ -235,8 +241,8 @@ void ObjExporter::WriteGeometryFile() {
|
||||||
AddNode(pScene->mRootNode, mBase);
|
AddNode(pScene->mRootNode, mBase);
|
||||||
|
|
||||||
// write vertex positions with colors, if any
|
// write vertex positions with colors, if any
|
||||||
vpMap.getVectors( vp );
|
mVpMap.getVectors( vp );
|
||||||
vcMap.getColors( vc );
|
mVcMap.getColors( vc );
|
||||||
if ( vc.empty() ) {
|
if ( vc.empty() ) {
|
||||||
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
||||||
for ( const aiVector3D& v : vp ) {
|
for ( const aiVector3D& v : vp ) {
|
||||||
|
@ -253,7 +259,7 @@ void ObjExporter::WriteGeometryFile() {
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write uv coordinates
|
// write uv coordinates
|
||||||
vtMap.getVectors(vt);
|
mVtMap.getVectors(vt);
|
||||||
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
||||||
for(const aiVector3D& v : vt) {
|
for(const aiVector3D& v : vt) {
|
||||||
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -261,7 +267,7 @@ void ObjExporter::WriteGeometryFile() {
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write vertex normals
|
// write vertex normals
|
||||||
vnMap.getVectors(vn);
|
mVnMap.getVectors(vn);
|
||||||
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
||||||
for(const aiVector3D& v : vn) {
|
for(const aiVector3D& v : vn) {
|
||||||
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -269,7 +275,7 @@ void ObjExporter::WriteGeometryFile() {
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// now write all mesh instances
|
// now write all mesh instances
|
||||||
for(const MeshInstance& m : meshes) {
|
for(const MeshInstance& m : mMeshes) {
|
||||||
mOutput << "# Mesh \'" << m.name << "\' with " << m.faces.size() << " faces" << endl;
|
mOutput << "# Mesh \'" << m.name << "\' with " << m.faces.size() << " faces" << endl;
|
||||||
if (!m.name.empty()) {
|
if (!m.name.empty()) {
|
||||||
mOutput << "g " << m.name << endl;
|
mOutput << "g " << m.name << endl;
|
||||||
|
@ -345,8 +351,8 @@ void ObjExporter::colIndexMap::getColors( std::vector<aiColor4D> &colors ) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
|
void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
|
||||||
meshes.push_back(MeshInstance());
|
mMeshes.push_back(MeshInstance());
|
||||||
MeshInstance& mesh = meshes.back();
|
MeshInstance& mesh = mMeshes.back();
|
||||||
|
|
||||||
mesh.name = std::string(name.data,name.length) + (m->mName.length ? "_" + std::string(m->mName.data,m->mName.length) : "");
|
mesh.name = std::string(name.data,name.length) + (m->mName.length ? "_" + std::string(m->mName.data,m->mName.length) : "");
|
||||||
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
||||||
|
@ -373,24 +379,24 @@ void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4
|
||||||
const unsigned int idx = f.mIndices[a];
|
const unsigned int idx = f.mIndices[a];
|
||||||
|
|
||||||
aiVector3D vert = mat * m->mVertices[idx];
|
aiVector3D vert = mat * m->mVertices[idx];
|
||||||
face.indices[a].vp = vpMap.getIndex(vert);
|
face.indices[a].vp = mVpMap.getIndex(vert);
|
||||||
|
|
||||||
if (m->mNormals) {
|
if (m->mNormals) {
|
||||||
aiVector3D norm = aiMatrix3x3(mat) * m->mNormals[idx];
|
aiVector3D norm = aiMatrix3x3(mat) * m->mNormals[idx];
|
||||||
face.indices[a].vn = vnMap.getIndex(norm);
|
face.indices[a].vn = mVnMap.getIndex(norm);
|
||||||
} else {
|
} else {
|
||||||
face.indices[a].vn = 0;
|
face.indices[a].vn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( nullptr != m->mColors[ 0 ] ) {
|
if ( nullptr != m->mColors[ 0 ] ) {
|
||||||
aiColor4D col4 = m->mColors[ 0 ][ idx ];
|
aiColor4D col4 = m->mColors[ 0 ][ idx ];
|
||||||
face.indices[ a ].vc = vcMap.getIndex( col4 );
|
face.indices[ a ].vc = mVcMap.getIndex( col4 );
|
||||||
} else {
|
} else {
|
||||||
face.indices[ a ].vc = 0;
|
face.indices[ a ].vc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m->mTextureCoords[ 0 ] ) {
|
if ( m->mTextureCoords[ 0 ] ) {
|
||||||
face.indices[a].vt = vtMap.getIndex(m->mTextureCoords[0][idx]);
|
face.indices[a].vt = mVtMap.getIndex(m->mTextureCoords[0][idx]);
|
||||||
} else {
|
} else {
|
||||||
face.indices[a].vt = 0;
|
face.indices[a].vt = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,9 +163,9 @@ private:
|
||||||
void getColors( std::vector<aiColor4D> &colors );
|
void getColors( std::vector<aiColor4D> &colors );
|
||||||
};
|
};
|
||||||
|
|
||||||
vecIndexMap vpMap, vnMap, vtMap;
|
vecIndexMap mVpMap, mVnMap, mVtMap;
|
||||||
colIndexMap vcMap;
|
colIndexMap mVcMap;
|
||||||
std::vector<MeshInstance> meshes;
|
std::vector<MeshInstance> mMeshes;
|
||||||
|
|
||||||
// this endl() doesn't flush() the stream
|
// this endl() doesn't flush() the stream
|
||||||
const std::string endl;
|
const std::string endl;
|
||||||
|
|
|
@ -55,19 +55,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// Material specific token
|
// Material specific token (case insensitive compare)
|
||||||
static const std::string DiffuseTexture = "map_Kd";
|
static const std::string DiffuseTexture = "map_Kd";
|
||||||
static const std::string AmbientTexture = "map_Ka";
|
static const std::string AmbientTexture = "map_Ka";
|
||||||
static const std::string SpecularTexture = "map_Ks";
|
static const std::string SpecularTexture = "map_Ks";
|
||||||
static const std::string OpacityTexture = "map_d";
|
static const std::string OpacityTexture = "map_d";
|
||||||
static const std::string EmissiveTexture = "map_emissive";
|
static const std::string EmissiveTexture1 = "map_emissive";
|
||||||
static const std::string EmissiveTexture_1 = "map_Ke";
|
static const std::string EmissiveTexture2 = "map_Ke";
|
||||||
static const std::string BumpTexture1 = "map_bump";
|
static const std::string BumpTexture1 = "map_bump";
|
||||||
static const std::string BumpTexture2 = "map_Bump";
|
static const std::string BumpTexture2 = "bump";
|
||||||
static const std::string BumpTexture3 = "bump";
|
|
||||||
static const std::string NormalTexture = "map_Kn";
|
static const std::string NormalTexture = "map_Kn";
|
||||||
static const std::string ReflectionTexture = "refl";
|
static const std::string ReflectionTexture = "refl";
|
||||||
static const std::string DisplacementTexture = "disp";
|
static const std::string DisplacementTexture1 = "map_disp";
|
||||||
|
static const std::string DisplacementTexture2 = "disp";
|
||||||
static const std::string SpecularityTexture = "map_ns";
|
static const std::string SpecularityTexture = "map_ns";
|
||||||
|
|
||||||
// texture option specific token
|
// texture option specific token
|
||||||
|
@ -304,7 +304,7 @@ void ObjFileMtlImporter::createMaterial()
|
||||||
m_pModel->m_pCurrentMaterial = new ObjFile::Material();
|
m_pModel->m_pCurrentMaterial = new ObjFile::Material();
|
||||||
m_pModel->m_pCurrentMaterial->MaterialName.Set( name );
|
m_pModel->m_pCurrentMaterial->MaterialName.Set( name );
|
||||||
if (m_pModel->m_pCurrentMesh) {
|
if (m_pModel->m_pCurrentMesh) {
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = m_pModel->m_MaterialLib.size() - 1;
|
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->m_MaterialLib.size() - 1);
|
||||||
}
|
}
|
||||||
m_pModel->m_MaterialLib.push_back( name );
|
m_pModel->m_MaterialLib.push_back( name );
|
||||||
m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial;
|
m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial;
|
||||||
|
@ -329,7 +329,7 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
// Ambient texture
|
// Ambient texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureAmbient;
|
out = & m_pModel->m_pCurrentMaterial->textureAmbient;
|
||||||
clampIndex = ObjFile::Material::TextureAmbientType;
|
clampIndex = ObjFile::Material::TextureAmbientType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()) ) ) {
|
||||||
// Specular texture
|
// Specular texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureSpecular;
|
out = & m_pModel->m_pCurrentMaterial->textureSpecular;
|
||||||
clampIndex = ObjFile::Material::TextureSpecularType;
|
clampIndex = ObjFile::Material::TextureSpecularType;
|
||||||
|
@ -337,33 +337,30 @@ void ObjFileMtlImporter::getTexture() {
|
||||||
// Opacity texture
|
// Opacity texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
||||||
clampIndex = ObjFile::Material::TextureOpacityType;
|
clampIndex = ObjFile::Material::TextureOpacityType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr, EmissiveTexture.c_str(), static_cast<unsigned int>(EmissiveTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size()) ) ||
|
||||||
|
!ASSIMP_strincmp( pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()) ) ) {
|
||||||
// Emissive texture
|
// Emissive texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureEmissive;
|
out = & m_pModel->m_pCurrentMaterial->textureEmissive;
|
||||||
clampIndex = ObjFile::Material::TextureEmissiveType;
|
clampIndex = ObjFile::Material::TextureEmissiveType;
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, EmissiveTexture_1.c_str(), static_cast<unsigned int>(EmissiveTexture_1.size()) ) ) {
|
|
||||||
// Emissive texture
|
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureEmissive;
|
|
||||||
clampIndex = ObjFile::Material::TextureEmissiveType;
|
|
||||||
} else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size()) ) ||
|
} else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size()) ) ||
|
||||||
!ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()) ) ||
|
!ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()) ) ) {
|
||||||
!ASSIMP_strincmp( pPtr, BumpTexture3.c_str(), static_cast<unsigned int>(BumpTexture3.size()) ) ) {
|
|
||||||
// Bump texture
|
// Bump texture
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureBump;
|
out = & m_pModel->m_pCurrentMaterial->textureBump;
|
||||||
clampIndex = ObjFile::Material::TextureBumpType;
|
clampIndex = ObjFile::Material::TextureBumpType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr,NormalTexture.c_str(), static_cast<unsigned int>(NormalTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr,NormalTexture.c_str(), static_cast<unsigned int>(NormalTexture.size()) ) ) {
|
||||||
// Normal map
|
// Normal map
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureNormal;
|
out = & m_pModel->m_pCurrentMaterial->textureNormal;
|
||||||
clampIndex = ObjFile::Material::TextureNormalType;
|
clampIndex = ObjFile::Material::TextureNormalType;
|
||||||
} else if(!ASSIMP_strincmp( pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()) ) ) {
|
} else if( !ASSIMP_strincmp( pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()) ) ) {
|
||||||
// Reflection texture(s)
|
// Reflection texture(s)
|
||||||
//Do nothing here
|
//Do nothing here
|
||||||
return;
|
return;
|
||||||
} else if (!ASSIMP_strincmp( pPtr, DisplacementTexture.c_str(), static_cast<unsigned int>(DisplacementTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
|
||||||
|
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
|
||||||
// Displacement texture
|
// Displacement texture
|
||||||
out = &m_pModel->m_pCurrentMaterial->textureDisp;
|
out = &m_pModel->m_pCurrentMaterial->textureDisp;
|
||||||
clampIndex = ObjFile::Material::TextureDispType;
|
clampIndex = ObjFile::Material::TextureDispType;
|
||||||
} else if (!ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
|
} else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
|
||||||
// Specularity scaling (glossiness)
|
// Specularity scaling (glossiness)
|
||||||
out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
|
out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
|
||||||
clampIndex = ObjFile::Material::TextureSpecularityType;
|
clampIndex = ObjFile::Material::TextureSpecularityType;
|
||||||
|
|
|
@ -359,8 +359,6 @@ void ObjFileParser::getHomogeneousVector3( std::vector<aiVector3D> &point3d_arra
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Get values for two 3D vectors on the same line
|
|
||||||
void ObjFileParser::getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, std::vector<aiVector3D> &point3d_array_b ) {
|
void ObjFileParser::getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, std::vector<aiVector3D> &point3d_array_b ) {
|
||||||
ai_real x, y, z;
|
ai_real x, y, z;
|
||||||
copyNextWord(m_buffer, Buffersize);
|
copyNextWord(m_buffer, Buffersize);
|
||||||
|
@ -388,8 +386,6 @@ void ObjFileParser::getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, st
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Get values for a new 2D vector instance
|
|
||||||
void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
||||||
ai_real x, y;
|
ai_real x, y;
|
||||||
copyNextWord(m_buffer, Buffersize);
|
copyNextWord(m_buffer, Buffersize);
|
||||||
|
@ -405,8 +401,6 @@ void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
||||||
|
|
||||||
static const std::string DefaultObjName = "defaultobject";
|
static const std::string DefaultObjName = "defaultobject";
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Get values for a new face instance
|
|
||||||
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
||||||
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
||||||
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
|
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
|
||||||
|
@ -522,8 +516,6 @@ void ObjFileParser::getFace( aiPrimitiveType type ) {
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Get values for a new material description
|
|
||||||
void ObjFileParser::getMaterialDesc() {
|
void ObjFileParser::getMaterialDesc() {
|
||||||
// Get next data for material data
|
// Get next data for material data
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
|
@ -555,10 +547,15 @@ void ObjFileParser::getMaterialDesc() {
|
||||||
// Search for material
|
// Search for material
|
||||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
|
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
|
||||||
if (it == m_pModel->m_MaterialMap.end()) {
|
if (it == m_pModel->m_MaterialMap.end()) {
|
||||||
// Not found, use default material
|
// Not found, so we don't know anything about the material except for its name.
|
||||||
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
// This may be the case if the material library is missing. We don't want to lose all
|
||||||
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
|
// materials if that happens, so create a new named material instead of discarding it
|
||||||
strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
|
// completely.
|
||||||
|
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", creating new material");
|
||||||
|
m_pModel->m_pCurrentMaterial = new ObjFile::Material();
|
||||||
|
m_pModel->m_pCurrentMaterial->MaterialName.Set(strName);
|
||||||
|
m_pModel->m_MaterialLib.push_back(strName);
|
||||||
|
m_pModel->m_MaterialMap[strName] = m_pModel->m_pCurrentMaterial;
|
||||||
} else {
|
} else {
|
||||||
// Found, using detected material
|
// Found, using detected material
|
||||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
m_pModel->m_pCurrentMaterial = (*it).second;
|
||||||
|
|
|
@ -261,6 +261,7 @@ OpenGEXImporter::OpenGEXImporter()
|
||||||
, m_nodeChildMap()
|
, m_nodeChildMap()
|
||||||
, m_meshCache()
|
, m_meshCache()
|
||||||
, m_mesh2refMap()
|
, m_mesh2refMap()
|
||||||
|
, m_material2refMap()
|
||||||
, m_ctx( nullptr )
|
, m_ctx( nullptr )
|
||||||
, m_metrics()
|
, m_metrics()
|
||||||
, m_currentNode( nullptr )
|
, m_currentNode( nullptr )
|
||||||
|
@ -306,6 +307,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce
|
||||||
|
|
||||||
std::vector<char> buffer;
|
std::vector<char> buffer;
|
||||||
TextFileToBuffer( file, buffer );
|
TextFileToBuffer( file, buffer );
|
||||||
|
pIOHandler->Close( file );
|
||||||
|
|
||||||
OpenDDLParser myParser;
|
OpenDDLParser myParser;
|
||||||
myParser.setBuffer( &buffer[ 0 ], buffer.size() );
|
myParser.setBuffer( &buffer[ 0 ], buffer.size() );
|
||||||
|
@ -320,6 +322,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce
|
||||||
copyMeshes( pScene );
|
copyMeshes( pScene );
|
||||||
copyCameras( pScene );
|
copyCameras( pScene );
|
||||||
copyLights( pScene );
|
copyLights( pScene );
|
||||||
|
copyMaterials( pScene );
|
||||||
resolveReferences();
|
resolveReferences();
|
||||||
createNodeTree( pScene );
|
createNodeTree( pScene );
|
||||||
}
|
}
|
||||||
|
@ -482,7 +485,10 @@ void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) {
|
||||||
|| m_tokenType == Grammar::CameraNodeToken ) {
|
|| m_tokenType == Grammar::CameraNodeToken ) {
|
||||||
m_currentNode->mName.Set( name.c_str() );
|
m_currentNode->mName.Set( name.c_str() );
|
||||||
} else if( m_tokenType == Grammar::MaterialToken ) {
|
} else if( m_tokenType == Grammar::MaterialToken ) {
|
||||||
|
aiString aiName;
|
||||||
|
aiName.Set( name );
|
||||||
|
m_currentMaterial->AddProperty( &aiName, AI_MATKEY_NAME );
|
||||||
|
m_material2refMap[ name ] = m_materialCache.size() - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,7 +526,7 @@ void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
|
||||||
m_currentNode->mNumMeshes = static_cast<unsigned int>(objRefNames.size());
|
m_currentNode->mNumMeshes = static_cast<unsigned int>(objRefNames.size());
|
||||||
m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
|
m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
|
||||||
if ( !objRefNames.empty() ) {
|
if ( !objRefNames.empty() ) {
|
||||||
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) );
|
m_unresolvedRefStack.push_back( std::unique_ptr<RefInfo>( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) ) );
|
||||||
}
|
}
|
||||||
} else if ( m_tokenType == Grammar::LightNodeToken ) {
|
} else if ( m_tokenType == Grammar::LightNodeToken ) {
|
||||||
// TODO!
|
// TODO!
|
||||||
|
@ -539,7 +545,7 @@ void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene
|
||||||
std::vector<std::string> matRefNames;
|
std::vector<std::string> matRefNames;
|
||||||
getRefNames( node, matRefNames );
|
getRefNames( node, matRefNames );
|
||||||
if( !matRefNames.empty() ) {
|
if( !matRefNames.empty() ) {
|
||||||
m_unresolvedRefStack.push_back( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) );
|
m_unresolvedRefStack.push_back( std::unique_ptr<RefInfo>( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1050,7 +1056,6 @@ void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene *pSc
|
||||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
|
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
|
||||||
} else if( prop->m_value->getString() == Grammar::SpecularPowerTextureToken ) {
|
} else if( prop->m_value->getString() == Grammar::SpecularPowerTextureToken ) {
|
||||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR( 0 ) );
|
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR( 0 ) );
|
||||||
|
|
||||||
} else if( prop->m_value->getString() == Grammar::EmissionTextureToken ) {
|
} else if( prop->m_value->getString() == Grammar::EmissionTextureToken ) {
|
||||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE( 0 ) );
|
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE( 0 ) );
|
||||||
} else if( prop->m_value->getString() == Grammar::OpacyTextureToken ) {
|
} else if( prop->m_value->getString() == Grammar::OpacyTextureToken ) {
|
||||||
|
@ -1154,6 +1159,19 @@ void OpenGEXImporter::copyLights( aiScene *pScene ) {
|
||||||
std::copy( m_lightCache.begin(), m_lightCache.end(), pScene->mLights );
|
std::copy( m_lightCache.begin(), m_lightCache.end(), pScene->mLights );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
void OpenGEXImporter::copyMaterials( aiScene *pScene ) {
|
||||||
|
ai_assert( nullptr != pScene );
|
||||||
|
|
||||||
|
if ( m_materialCache.empty() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pScene->mNumMaterials = static_cast<unsigned int>(m_materialCache.size());
|
||||||
|
pScene->mMaterials = new aiMaterial*[ pScene->mNumMaterials ];
|
||||||
|
std::copy( m_materialCache.begin(), m_materialCache.end(), pScene->mMaterials );
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
void OpenGEXImporter::resolveReferences() {
|
void OpenGEXImporter::resolveReferences() {
|
||||||
if( m_unresolvedRefStack.empty() ) {
|
if( m_unresolvedRefStack.empty() ) {
|
||||||
|
@ -1161,12 +1179,12 @@ void OpenGEXImporter::resolveReferences() {
|
||||||
}
|
}
|
||||||
|
|
||||||
RefInfo *currentRefInfo( nullptr );
|
RefInfo *currentRefInfo( nullptr );
|
||||||
for( std::vector<RefInfo*>::iterator it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
|
for( auto it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
|
||||||
currentRefInfo = *it;
|
currentRefInfo = it->get();
|
||||||
if( nullptr != currentRefInfo ) {
|
if( nullptr != currentRefInfo ) {
|
||||||
aiNode *node( currentRefInfo->m_node );
|
aiNode *node( currentRefInfo->m_node );
|
||||||
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
|
if( RefInfo::MeshRef == currentRefInfo->m_type ) {
|
||||||
for( size_t i = 0; i < currentRefInfo->m_Names.size(); i++ ) {
|
for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
|
||||||
const std::string &name( currentRefInfo->m_Names[ i ] );
|
const std::string &name( currentRefInfo->m_Names[ i ] );
|
||||||
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
|
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
|
||||||
if( m_mesh2refMap.end() != it ) {
|
if( m_mesh2refMap.end() != it ) {
|
||||||
|
@ -1175,7 +1193,22 @@ void OpenGEXImporter::resolveReferences() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
|
} else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
|
||||||
// ToDo!
|
for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
|
||||||
|
const std::string name( currentRefInfo->m_Names[ i ] );
|
||||||
|
ReferenceMap::const_iterator it( m_material2refMap.find( name ) );
|
||||||
|
if ( m_material2refMap.end() != it ) {
|
||||||
|
if ( nullptr != m_currentMesh ) {
|
||||||
|
unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] );
|
||||||
|
if ( m_currentMesh->mMaterialIndex != 0 ) {
|
||||||
|
DefaultLogger::get()->warn( "Override of material reference in current mesh by material reference." );
|
||||||
|
}
|
||||||
|
m_currentMesh->mMaterialIndex = matIdx;
|
||||||
|
} else {
|
||||||
|
DefaultLogger::get()->warn( "Cannot resolve material reference, because no current mesh is there." );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw DeadlyImportError( "Unknown reference info to resolve." );
|
throw DeadlyImportError( "Unknown reference info to resolve." );
|
||||||
}
|
}
|
||||||
|
@ -1213,9 +1246,9 @@ void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
||||||
if( m_nodeChildMap.end() == it ) {
|
if( m_nodeChildMap.end() == it ) {
|
||||||
info = new ChildInfo;
|
info = new ChildInfo;
|
||||||
m_root = info;
|
m_root = info;
|
||||||
m_nodeChildMap[ node->mParent ] = info;
|
m_nodeChildMap[ node->mParent ] = std::unique_ptr<ChildInfo>(info);
|
||||||
} else {
|
} else {
|
||||||
info = it->second;
|
info = it->second.get();
|
||||||
}
|
}
|
||||||
info->m_children.push_back( node );
|
info->m_children.push_back( node );
|
||||||
} else {
|
} else {
|
||||||
|
@ -1225,9 +1258,9 @@ void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
||||||
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||||
if( m_nodeChildMap.end() == it ) {
|
if( m_nodeChildMap.end() == it ) {
|
||||||
info = new ChildInfo;
|
info = new ChildInfo;
|
||||||
m_nodeChildMap[ node->mParent ] = info;
|
m_nodeChildMap[ node->mParent ] = std::unique_ptr<ChildInfo>(info);
|
||||||
} else {
|
} else {
|
||||||
info = it->second;
|
info = it->second.get();
|
||||||
}
|
}
|
||||||
info->m_children.push_back( node );
|
info->m_children.push_back( node );
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace ODDLParser {
|
namespace ODDLParser {
|
||||||
class DDLNode;
|
class DDLNode;
|
||||||
|
@ -132,6 +133,7 @@ protected:
|
||||||
void copyMeshes( aiScene *pScene );
|
void copyMeshes( aiScene *pScene );
|
||||||
void copyCameras( aiScene *pScene );
|
void copyCameras( aiScene *pScene );
|
||||||
void copyLights( aiScene *pScene );
|
void copyLights( aiScene *pScene );
|
||||||
|
void copyMaterials( aiScene *pScene );
|
||||||
void resolveReferences();
|
void resolveReferences();
|
||||||
void pushNode( aiNode *node, aiScene *pScene );
|
void pushNode( aiNode *node, aiScene *pScene );
|
||||||
aiNode *popNode();
|
aiNode *popNode();
|
||||||
|
@ -179,12 +181,13 @@ private:
|
||||||
std::list<aiNode*> m_children;
|
std::list<aiNode*> m_children;
|
||||||
};
|
};
|
||||||
ChildInfo *m_root;
|
ChildInfo *m_root;
|
||||||
typedef std::map<aiNode*, ChildInfo*> NodeChildMap;
|
typedef std::map<aiNode*, std::unique_ptr<ChildInfo> > NodeChildMap;
|
||||||
NodeChildMap m_nodeChildMap;
|
NodeChildMap m_nodeChildMap;
|
||||||
|
|
||||||
std::vector<aiMesh*> m_meshCache;
|
std::vector<aiMesh*> m_meshCache;
|
||||||
typedef std::map<std::string, size_t> ReferenceMap;
|
typedef std::map<std::string, size_t> ReferenceMap;
|
||||||
std::map<std::string, size_t> m_mesh2refMap;
|
std::map<std::string, size_t> m_mesh2refMap;
|
||||||
|
std::map<std::string, size_t> m_material2refMap;
|
||||||
|
|
||||||
ODDLParser::Context *m_ctx;
|
ODDLParser::Context *m_ctx;
|
||||||
MetricInfo m_metrics[ MetricInfo::Max ];
|
MetricInfo m_metrics[ MetricInfo::Max ];
|
||||||
|
@ -199,7 +202,7 @@ private:
|
||||||
std::vector<aiCamera*> m_cameraCache;
|
std::vector<aiCamera*> m_cameraCache;
|
||||||
std::vector<aiLight*> m_lightCache;
|
std::vector<aiLight*> m_lightCache;
|
||||||
std::vector<aiNode*> m_nodeStack;
|
std::vector<aiNode*> m_nodeStack;
|
||||||
std::vector<RefInfo*> m_unresolvedRefStack;
|
std::vector<std::unique_ptr<RefInfo> > m_unresolvedRefStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Namespace OpenGEX
|
} // Namespace OpenGEX
|
||||||
|
|
|
@ -181,11 +181,8 @@ void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
|
||||||
verts += mScene->mMeshes[am]->mNumVertices;
|
verts += mScene->mMeshes[am]->mNumVertices;
|
||||||
faces += mScene->mMeshes[am]->mNumFaces;
|
faces += mScene->mMeshes[am]->mNumFaces;
|
||||||
|
|
||||||
|
pNode->mMeshes[a] = pNode->mMeshes[pNode->mNumMeshes - 1];
|
||||||
--pNode->mNumMeshes;
|
--pNode->mNumMeshes;
|
||||||
for( unsigned int n = a; n < pNode->mNumMeshes; ++n ) {
|
|
||||||
pNode->mMeshes[ n ] = pNode->mMeshes[ n + 1 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
--a;
|
--a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,9 +170,10 @@ void PLYImporter::InternReadFile(const std::string& pFile,
|
||||||
std::vector<char> headerCheck;
|
std::vector<char> headerCheck;
|
||||||
streamedBuffer.getNextLine(headerCheck);
|
streamedBuffer.getNextLine(headerCheck);
|
||||||
|
|
||||||
if ((headerCheck.size() >= 3) && (headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
|
if ((headerCheck.size() < 3) ||
|
||||||
|
(headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
|
||||||
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
|
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
|
||||||
(headerCheck[2] != 'Y' && headerCheck[2] != 'y'))
|
(headerCheck[2] != 'Y' && headerCheck[2] != 'y') )
|
||||||
{
|
{
|
||||||
streamedBuffer.close();
|
streamedBuffer.close();
|
||||||
throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
|
throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
|
||||||
|
@ -299,8 +300,7 @@ void PLYImporter::InternReadFile(const std::string& pFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
|
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
|
||||||
{
|
|
||||||
ai_assert(NULL != pcElement);
|
ai_assert(NULL != pcElement);
|
||||||
ai_assert(NULL != instElement);
|
ai_assert(NULL != instElement);
|
||||||
|
|
||||||
|
@ -316,113 +316,84 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||||
unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
|
unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
|
||||||
PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
|
PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
|
||||||
|
|
||||||
unsigned int cnt = 0;
|
|
||||||
|
|
||||||
// now check whether which normal components are available
|
// now check whether which normal components are available
|
||||||
unsigned int _a = 0;
|
unsigned int _a( 0 ), cnt( 0 );
|
||||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
for ( std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||||
{
|
if ((*a).bIsList) {
|
||||||
if ((*a).bIsList)continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Positions
|
// Positions
|
||||||
if (PLY::EST_XCoord == (*a).Semantic)
|
if (PLY::EST_XCoord == (*a).Semantic) {
|
||||||
{
|
++cnt;
|
||||||
cnt++;
|
|
||||||
aiPositions[0] = _a;
|
aiPositions[0] = _a;
|
||||||
aiTypes[0] = (*a).eType;
|
aiTypes[0] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_YCoord == (*a).Semantic) {
|
||||||
else if (PLY::EST_YCoord == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiPositions[1] = _a;
|
aiPositions[1] = _a;
|
||||||
aiTypes[1] = (*a).eType;
|
aiTypes[1] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_ZCoord == (*a).Semantic) {
|
||||||
else if (PLY::EST_ZCoord == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiPositions[2] = _a;
|
aiPositions[2] = _a;
|
||||||
aiTypes[2] = (*a).eType;
|
aiTypes[2] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_XNormal == (*a).Semantic) {
|
||||||
|
|
||||||
// Normals
|
// Normals
|
||||||
else if (PLY::EST_XNormal == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiNormal[0] = _a;
|
aiNormal[0] = _a;
|
||||||
aiNormalTypes[0] = (*a).eType;
|
aiNormalTypes[0] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_YNormal == (*a).Semantic) {
|
||||||
else if (PLY::EST_YNormal == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiNormal[1] = _a;
|
aiNormal[1] = _a;
|
||||||
aiNormalTypes[1] = (*a).eType;
|
aiNormalTypes[1] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_ZNormal == (*a).Semantic) {
|
||||||
else if (PLY::EST_ZNormal == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiNormal[2] = _a;
|
aiNormal[2] = _a;
|
||||||
aiNormalTypes[2] = (*a).eType;
|
aiNormalTypes[2] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_Red == (*a).Semantic) {
|
||||||
// Colors
|
// Colors
|
||||||
else if (PLY::EST_Red == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiColors[0] = _a;
|
aiColors[0] = _a;
|
||||||
aiColorsTypes[0] = (*a).eType;
|
aiColorsTypes[0] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_Green == (*a).Semantic) {
|
||||||
else if (PLY::EST_Green == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiColors[1] = _a;
|
aiColors[1] = _a;
|
||||||
aiColorsTypes[1] = (*a).eType;
|
aiColorsTypes[1] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_Blue == (*a).Semantic) {
|
||||||
else if (PLY::EST_Blue == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiColors[2] = _a;
|
aiColors[2] = _a;
|
||||||
aiColorsTypes[2] = (*a).eType;
|
aiColorsTypes[2] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_Alpha == (*a).Semantic) {
|
||||||
else if (PLY::EST_Alpha == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiColors[3] = _a;
|
aiColors[3] = _a;
|
||||||
aiColorsTypes[3] = (*a).eType;
|
aiColorsTypes[3] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_UTextureCoord == (*a).Semantic) {
|
||||||
// Texture coordinates
|
// Texture coordinates
|
||||||
else if (PLY::EST_UTextureCoord == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiTexcoord[0] = _a;
|
aiTexcoord[0] = _a;
|
||||||
aiTexcoordTypes[0] = (*a).eType;
|
aiTexcoordTypes[0] = (*a).eType;
|
||||||
}
|
} else if (PLY::EST_VTextureCoord == (*a).Semantic) {
|
||||||
else if (PLY::EST_VTextureCoord == (*a).Semantic)
|
++cnt;
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
aiTexcoord[1] = _a;
|
aiTexcoord[1] = _a;
|
||||||
aiTexcoordTypes[1] = (*a).eType;
|
aiTexcoordTypes[1] = (*a).eType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether we have a valid source for the vertex data
|
// check whether we have a valid source for the vertex data
|
||||||
if (0 != cnt)
|
if (0 != cnt) {
|
||||||
{
|
|
||||||
// Position
|
// Position
|
||||||
aiVector3D vOut;
|
aiVector3D vOut;
|
||||||
if (0xFFFFFFFF != aiPositions[0])
|
if (0xFFFFFFFF != aiPositions[0]) {
|
||||||
{
|
|
||||||
vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
|
GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[1])
|
if (0xFFFFFFFF != aiPositions[1]) {
|
||||||
{
|
|
||||||
vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
|
GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiPositions[2])
|
if (0xFFFFFFFF != aiPositions[2]) {
|
||||||
{
|
|
||||||
vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
|
GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
|
||||||
}
|
}
|
||||||
|
@ -430,22 +401,19 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||||
// Normals
|
// Normals
|
||||||
aiVector3D nOut;
|
aiVector3D nOut;
|
||||||
bool haveNormal = false;
|
bool haveNormal = false;
|
||||||
if (0xFFFFFFFF != aiNormal[0])
|
if (0xFFFFFFFF != aiNormal[0]) {
|
||||||
{
|
|
||||||
nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
|
GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
|
||||||
haveNormal = true;
|
haveNormal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiNormal[1])
|
if (0xFFFFFFFF != aiNormal[1]) {
|
||||||
{
|
|
||||||
nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
|
GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
|
||||||
haveNormal = true;
|
haveNormal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiNormal[2])
|
if (0xFFFFFFFF != aiNormal[2]) {
|
||||||
{
|
|
||||||
nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
|
GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
|
||||||
haveNormal = true;
|
haveNormal = true;
|
||||||
|
@ -454,34 +422,28 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||||
//Colors
|
//Colors
|
||||||
aiColor4D cOut;
|
aiColor4D cOut;
|
||||||
bool haveColor = false;
|
bool haveColor = false;
|
||||||
if (0xFFFFFFFF != aiColors[0])
|
if (0xFFFFFFFF != aiColors[0]) {
|
||||||
{
|
|
||||||
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
|
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||||
aiColors[0]).avList.front(), aiColorsTypes[0]);
|
aiColors[0]).avList.front(), aiColorsTypes[0]);
|
||||||
haveColor = true;
|
haveColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiColors[1])
|
if (0xFFFFFFFF != aiColors[1]) {
|
||||||
{
|
|
||||||
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
|
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||||
aiColors[1]).avList.front(), aiColorsTypes[1]);
|
aiColors[1]).avList.front(), aiColorsTypes[1]);
|
||||||
haveColor = true;
|
haveColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiColors[2])
|
if (0xFFFFFFFF != aiColors[2]) {
|
||||||
{
|
|
||||||
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
|
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||||
aiColors[2]).avList.front(), aiColorsTypes[2]);
|
aiColors[2]).avList.front(), aiColorsTypes[2]);
|
||||||
haveColor = true;
|
haveColor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume 1.0 for the alpha channel ifit is not set
|
// assume 1.0 for the alpha channel ifit is not set
|
||||||
if (0xFFFFFFFF == aiColors[3])
|
if (0xFFFFFFFF == aiColors[3]) {
|
||||||
{
|
|
||||||
cOut.a = 1.0;
|
cOut.a = 1.0;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
|
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||||
aiColors[3]).avList.front(), aiColorsTypes[3]);
|
aiColors[3]).avList.front(), aiColorsTypes[3]);
|
||||||
|
|
||||||
|
@ -492,53 +454,45 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
|
||||||
aiVector3D tOut;
|
aiVector3D tOut;
|
||||||
tOut.z = 0;
|
tOut.z = 0;
|
||||||
bool haveTextureCoords = false;
|
bool haveTextureCoords = false;
|
||||||
if (0xFFFFFFFF != aiTexcoord[0])
|
if (0xFFFFFFFF != aiTexcoord[0]) {
|
||||||
{
|
|
||||||
tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
|
GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
|
||||||
haveTextureCoords = true;
|
haveTextureCoords = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0xFFFFFFFF != aiTexcoord[1])
|
if (0xFFFFFFFF != aiTexcoord[1]) {
|
||||||
{
|
|
||||||
tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||||
GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
|
GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
|
||||||
haveTextureCoords = true;
|
haveTextureCoords = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//create aiMesh if needed
|
//create aiMesh if needed
|
||||||
if (mGeneratedMesh == NULL)
|
if ( nullptr == mGeneratedMesh ) {
|
||||||
{
|
|
||||||
mGeneratedMesh = new aiMesh();
|
mGeneratedMesh = new aiMesh();
|
||||||
mGeneratedMesh->mMaterialIndex = 0;
|
mGeneratedMesh->mMaterialIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mGeneratedMesh->mVertices == NULL)
|
if (nullptr == mGeneratedMesh->mVertices) {
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumVertices = pcElement->NumOccur;
|
mGeneratedMesh->mNumVertices = pcElement->NumOccur;
|
||||||
mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
|
mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
|
|
||||||
mGeneratedMesh->mVertices[pos] = vOut;
|
mGeneratedMesh->mVertices[pos] = vOut;
|
||||||
|
|
||||||
if (haveNormal)
|
if (haveNormal) {
|
||||||
{
|
if (nullptr == mGeneratedMesh->mNormals)
|
||||||
if (mGeneratedMesh->mNormals == NULL)
|
|
||||||
mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
|
mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||||
mGeneratedMesh->mNormals[pos] = nOut;
|
mGeneratedMesh->mNormals[pos] = nOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (haveColor)
|
if (haveColor) {
|
||||||
{
|
if (nullptr == mGeneratedMesh->mColors[0])
|
||||||
if (mGeneratedMesh->mColors[0] == NULL)
|
|
||||||
mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
|
mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
|
||||||
mGeneratedMesh->mColors[0][pos] = cOut;
|
mGeneratedMesh->mColors[0][pos] = cOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (haveTextureCoords)
|
if (haveTextureCoords) {
|
||||||
{
|
if (nullptr == mGeneratedMesh->mTextureCoords[0]) {
|
||||||
if (mGeneratedMesh->mTextureCoords[0] == NULL)
|
|
||||||
{
|
|
||||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||||
}
|
}
|
||||||
|
@ -585,7 +539,7 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
||||||
ai_assert(NULL != instElement);
|
ai_assert(NULL != instElement);
|
||||||
|
|
||||||
if (mGeneratedMesh == NULL)
|
if (mGeneratedMesh == NULL)
|
||||||
throw DeadlyImportError("Invalid .ply file: Vertices shoud be declared before faces");
|
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
|
||||||
|
|
||||||
bool bOne = false;
|
bool bOne = false;
|
||||||
|
|
||||||
|
|
|
@ -618,7 +618,7 @@ bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pc
|
||||||
}
|
}
|
||||||
|
|
||||||
streamBuffer.getNextBlock(buffer);
|
streamBuffer.getNextBlock(buffer);
|
||||||
unsigned int bufferSize = buffer.size();
|
unsigned int bufferSize = static_cast<unsigned int>(buffer.size());
|
||||||
const char* pCur = (char*)&buffer[0];
|
const char* pCur = (char*)&buffer[0];
|
||||||
if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE))
|
if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE))
|
||||||
{
|
{
|
||||||
|
@ -1025,7 +1025,7 @@ bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
|
||||||
buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end());
|
buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end());
|
||||||
buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
|
buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
|
||||||
nbuffer.clear();
|
nbuffer.clear();
|
||||||
bufferSize = buffer.size();
|
bufferSize = static_cast<unsigned int>(buffer.size());
|
||||||
pCur = (char*)&buffer[0];
|
pCur = (char*)&buffer[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -104,7 +104,7 @@ unsigned int PretransformVertices::CountNodes( aiNode* pcNode )
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a bitwise combination identifying the vertex format of a mesh
|
// Get a bitwise combination identifying the vertex format of a mesh
|
||||||
unsigned int PretransformVertices::GetMeshVFormat(aiMesh* pcMesh)
|
unsigned int PretransformVertices::GetMeshVFormat( aiMesh* pcMesh )
|
||||||
{
|
{
|
||||||
// the vertex format is stored in aiMesh::mBones for later retrieval.
|
// the vertex format is stored in aiMesh::mBones for later retrieval.
|
||||||
// there isn't a good reason to compute it a few hundred times
|
// there isn't a good reason to compute it a few hundred times
|
||||||
|
@ -160,6 +160,11 @@ void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsign
|
||||||
unsigned int& num_ref = num_refs[pcNode->mMeshes[i]];
|
unsigned int& num_ref = num_refs[pcNode->mMeshes[i]];
|
||||||
ai_assert(0 != num_ref);
|
ai_assert(0 != num_ref);
|
||||||
--num_ref;
|
--num_ref;
|
||||||
|
// Save the name of the last mesh
|
||||||
|
if (num_ref==0)
|
||||||
|
{
|
||||||
|
pcMeshOut->mName = pcMesh->mName;
|
||||||
|
}
|
||||||
|
|
||||||
if (identity) {
|
if (identity) {
|
||||||
// copy positions without modifying them
|
// copy positions without modifying them
|
||||||
|
@ -626,9 +631,10 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// now delete all nodes in the scene and build a new
|
// now delete all nodes in the scene and build a new
|
||||||
// flat node graph with a root node and some level 1 children
|
// flat node graph with a root node and some level 1 children
|
||||||
|
aiNode* newRoot = new aiNode();
|
||||||
|
newRoot->mName = pScene->mRootNode->mName;
|
||||||
delete pScene->mRootNode;
|
delete pScene->mRootNode;
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = newRoot;
|
||||||
pScene->mRootNode->mName.Set("<dummy_root>");
|
|
||||||
|
|
||||||
if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
|
if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
|
||||||
{
|
{
|
||||||
|
@ -646,7 +652,7 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
aiNode* pcNode = *nodes = new aiNode();
|
aiNode* pcNode = *nodes = new aiNode();
|
||||||
pcNode->mParent = pScene->mRootNode;
|
pcNode->mParent = pScene->mRootNode;
|
||||||
pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"mesh_%u",i);
|
pcNode->mName = pScene->mMeshes[i]->mName;
|
||||||
|
|
||||||
// setup mesh indices
|
// setup mesh indices
|
||||||
pcNode->mNumMeshes = 1;
|
pcNode->mNumMeshes = 1;
|
||||||
|
|
|
@ -52,21 +52,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Profiling {
|
namespace Profiling {
|
||||||
|
|
||||||
using namespace Formatter;
|
|
||||||
|
|
||||||
|
using namespace Formatter;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically
|
/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically
|
||||||
* dumped to the log file.
|
* dumped to the log file.
|
||||||
*/
|
*/
|
||||||
class Profiler
|
class Profiler {
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Profiler() {
|
||||||
Profiler() {}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -84,17 +82,17 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto elapsedSeconds = std::chrono::system_clock::now() - regions[region];
|
std::chrono::duration<double> elapsedSeconds = std::chrono::system_clock::now() - regions[region];
|
||||||
DefaultLogger::get()->debug((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s"));
|
DefaultLogger::get()->debug((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef std::map<std::string,std::chrono::time_point<std::chrono::system_clock>> RegionMap;
|
typedef std::map<std::string,std::chrono::time_point<std::chrono::system_clock>> RegionMap;
|
||||||
RegionMap regions;
|
RegionMap regions;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -39,14 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||||
|
|
||||||
#include "Q3BSPZipArchive.h"
|
#include "Q3BSPZipArchive.h"
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -137,7 +133,6 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
ZipFile::ZipFile(size_t size) : m_Size(size) {
|
ZipFile::ZipFile(size_t size) : m_Size(size) {
|
||||||
ai_assert(m_Size != 0);
|
ai_assert(m_Size != 0);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <contrib/unzip/unzip.h>
|
#include <contrib/unzip/unzip.h>
|
||||||
#include <assimp/IOStream.hpp>
|
#include <assimp/IOStream.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
|
@ -176,36 +176,29 @@ static void UnknownChunk(StreamReaderLE* stream, const SIBChunk& chunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads a UTF-16LE string and returns it at UTF-8.
|
// Reads a UTF-16LE string and returns it at UTF-8.
|
||||||
static aiString ReadString(StreamReaderLE* stream, uint32_t numWChars)
|
static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) {
|
||||||
{
|
if ( nullptr == stream || 0 == numWChars ) {
|
||||||
if ( 0 == numWChars ) {
|
|
||||||
static const aiString empty;
|
static const aiString empty;
|
||||||
return empty;
|
return empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
|
// Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
|
||||||
//UTF16* temp = new UTF16[numWChars];
|
|
||||||
std::vector<unsigned char> str;
|
std::vector<unsigned char> str;
|
||||||
str.reserve(numWChars * 4 + 1);
|
str.reserve( numWChars * 4 + 1 );
|
||||||
//unsigned char* str = new unsigned char[numWChars * 4 + 1];
|
uint16_t *temp = new uint16_t[ numWChars ];
|
||||||
uint16_t *temp = new uint16_t[numWChars];
|
for ( uint32_t n = 0; n < numWChars; ++n ) {
|
||||||
for (uint32_t n=0;n<numWChars;n++)
|
temp[ n ] = stream->GetU2();
|
||||||
temp[n] = stream->GetU2();
|
}
|
||||||
|
|
||||||
// Convert it and NUL-terminate.
|
// Convert it and NUL-terminate.
|
||||||
//const UTF16 *start = temp, *end = temp + numWChars;
|
const uint16_t *start( temp ), *end( temp + numWChars );
|
||||||
|
utf8::utf16to8( start, end, back_inserter( str ) );
|
||||||
|
str[ str.size() - 1 ] = '\0';
|
||||||
|
|
||||||
const uint16_t *start = temp, *end = temp + numWChars;
|
|
||||||
utf8::utf16to8(start, end, back_inserter(str));
|
|
||||||
|
|
||||||
//UTF8 *dest = str, *limit = str + numWChars*4;
|
|
||||||
//ConvertUTF16toUTF8(&start, end, &dest, limit, lenientConversion);
|
|
||||||
//*dest = '\0';
|
|
||||||
|
|
||||||
str[str.size()-1] = '\0';
|
|
||||||
// Return the final string.
|
// Return the final string.
|
||||||
aiString result = aiString((const char *)&str[0]);
|
aiString result = aiString((const char *)&str[0]);
|
||||||
//delete[] str;
|
|
||||||
delete[] temp;
|
delete[] temp;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,26 +216,26 @@ SIBImporter::~SIBImporter() {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool SIBImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
|
bool SIBImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
|
||||||
{
|
|
||||||
return SimpleExtensionCheck(pFile, "sib");
|
return SimpleExtensionCheck(pFile, "sib");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiImporterDesc* SIBImporter::GetInfo () const
|
const aiImporterDesc* SIBImporter::GetInfo () const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count)
|
static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) {
|
||||||
{
|
if ( nullptr == mesh || nullptr == stream ) {
|
||||||
mesh->pos.resize(count);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t n=0;n<count;n++) {
|
mesh->pos.resize(count);
|
||||||
mesh->pos[n].x = stream->GetF4();
|
for ( uint32_t n=0; n<count; ++n ) {
|
||||||
mesh->pos[n].y = stream->GetF4();
|
mesh->pos[ n ].x = stream->GetF4();
|
||||||
mesh->pos[n].z = stream->GetF4();
|
mesh->pos[ n ].y = stream->GetF4();
|
||||||
|
mesh->pos[ n ].z = stream->GetF4();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -827,7 +820,7 @@ static void ReadInstance(SIB* sib, StreamReaderLE* stream)
|
||||||
static void CheckVersion(StreamReaderLE* stream)
|
static void CheckVersion(StreamReaderLE* stream)
|
||||||
{
|
{
|
||||||
uint32_t version = stream->GetU4();
|
uint32_t version = stream->GetU4();
|
||||||
if ( version != 1 ) {
|
if ( version < 1 || version > 2 ) {
|
||||||
throw DeadlyImportError( "SIB: Unsupported file version." );
|
throw DeadlyImportError( "SIB: Unsupported file version." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,7 +450,9 @@ void SMDImporter::CreateOutputMeshes()
|
||||||
// add bone child nodes
|
// add bone child nodes
|
||||||
void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
|
void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pcNode && 0 == pcNode->mNumChildren && NULL == pcNode->mChildren);
|
ai_assert( NULL != pcNode );
|
||||||
|
ai_assert( 0 == pcNode->mNumChildren );
|
||||||
|
ai_assert( NULL == pcNode->mChildren);
|
||||||
|
|
||||||
// first count ...
|
// first count ...
|
||||||
for (unsigned int i = 0; i < asBones.size();++i)
|
for (unsigned int i = 0; i < asBones.size();++i)
|
||||||
|
@ -648,12 +650,14 @@ void SMDImporter::ComputeAbsoluteBoneTransformations()
|
||||||
// create output materials
|
// create output materials
|
||||||
void SMDImporter::CreateOutputMaterials()
|
void SMDImporter::CreateOutputMaterials()
|
||||||
{
|
{
|
||||||
|
ai_assert( nullptr != pScene );
|
||||||
|
|
||||||
pScene->mNumMaterials = (unsigned int)aszTextures.size();
|
pScene->mNumMaterials = (unsigned int)aszTextures.size();
|
||||||
pScene->mMaterials = new aiMaterial*[std::max(1u, pScene->mNumMaterials)];
|
pScene->mMaterials = new aiMaterial*[std::max(1u, pScene->mNumMaterials)];
|
||||||
|
|
||||||
for (unsigned int iMat = 0; iMat < pScene->mNumMaterials;++iMat)
|
for (unsigned int iMat = 0; iMat < pScene->mNumMaterials; ++iMat) {
|
||||||
{
|
|
||||||
aiMaterial* pcMat = new aiMaterial();
|
aiMaterial* pcMat = new aiMaterial();
|
||||||
|
ai_assert( nullptr != pcMat );
|
||||||
pScene->mMaterials[iMat] = pcMat;
|
pScene->mMaterials[iMat] = pcMat;
|
||||||
|
|
||||||
aiString szName;
|
aiString szName;
|
||||||
|
|
|
@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/mesh.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "ScenePrivate.h"
|
#include "ScenePrivate.h"
|
||||||
|
|
||||||
|
@ -757,7 +758,7 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Merge a list of meshes
|
// Merge a list of meshes
|
||||||
void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
|
||||||
std::vector<aiMesh*>::const_iterator begin,
|
std::vector<aiMesh*>::const_iterator begin,
|
||||||
std::vector<aiMesh*>::const_iterator end)
|
std::vector<aiMesh*>::const_iterator end)
|
||||||
{
|
{
|
||||||
|
@ -772,8 +773,14 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
||||||
aiMesh* out = *_out = new aiMesh();
|
aiMesh* out = *_out = new aiMesh();
|
||||||
out->mMaterialIndex = (*begin)->mMaterialIndex;
|
out->mMaterialIndex = (*begin)->mMaterialIndex;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
// Find out how much output storage we'll need
|
// Find out how much output storage we'll need
|
||||||
for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
|
for (std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it) {
|
||||||
|
const char *meshName( (*it)->mName.C_Str() );
|
||||||
|
name += std::string( meshName );
|
||||||
|
if ( it != end - 1 ) {
|
||||||
|
name += ".";
|
||||||
|
}
|
||||||
out->mNumVertices += (*it)->mNumVertices;
|
out->mNumVertices += (*it)->mNumVertices;
|
||||||
out->mNumFaces += (*it)->mNumFaces;
|
out->mNumFaces += (*it)->mNumFaces;
|
||||||
out->mNumBones += (*it)->mNumBones;
|
out->mNumBones += (*it)->mNumBones;
|
||||||
|
@ -781,6 +788,7 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
||||||
// combine primitive type flags
|
// combine primitive type flags
|
||||||
out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
|
out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
|
||||||
}
|
}
|
||||||
|
out->mName.Set( name.c_str() );
|
||||||
|
|
||||||
if (out->mNumVertices) {
|
if (out->mNumVertices) {
|
||||||
aiVector3D* pv2;
|
aiVector3D* pv2;
|
||||||
|
@ -789,7 +797,7 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
||||||
if ((**begin).HasPositions()) {
|
if ((**begin).HasPositions()) {
|
||||||
|
|
||||||
pv2 = out->mVertices = new aiVector3D[out->mNumVertices];
|
pv2 = out->mVertices = new aiVector3D[out->mNumVertices];
|
||||||
for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
|
for (std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it) {
|
||||||
if ((*it)->mVertices) {
|
if ((*it)->mVertices) {
|
||||||
::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D));
|
::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D));
|
||||||
}
|
}
|
||||||
|
@ -809,7 +817,7 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
||||||
pv2 += (*it)->mNumVertices;
|
pv2 += (*it)->mNumVertices;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// copy tangents and bitangents
|
// copy tangents and bi-tangents
|
||||||
if ((**begin).HasTangentsAndBitangents()) {
|
if ((**begin).HasTangentsAndBitangents()) {
|
||||||
|
|
||||||
pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
|
pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
|
||||||
|
|
|
@ -291,15 +291,11 @@ private:
|
||||||
throw DeadlyImportError("End of file or stream limit was reached");
|
throw DeadlyImportError("End of file or stream limit was reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
///*#ifdef __arm__
|
|
||||||
T f;
|
T f;
|
||||||
::memcpy (&f, current, sizeof(T));
|
::memcpy (&f, current, sizeof(T));
|
||||||
//#else*/
|
Intern::Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
|
||||||
// T f = *((const T*)current);
|
|
||||||
//#endif
|
|
||||||
Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
|
|
||||||
|
|
||||||
current += sizeof(T);
|
current += sizeof(T);
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
DefaultLogger::get()->debug("UNREAL: uc file is " + uc_path);
|
DefaultLogger::get()->debug("UNREAL: uc file is " + uc_path);
|
||||||
|
|
||||||
// and open the files ... we can't live without them
|
// and open the files ... we can't live without them
|
||||||
IOStream* p = pIOHandler->Open(d_path);
|
std::unique_ptr<IOStream> p(pIOHandler->Open(d_path));
|
||||||
if (!p)
|
if (!p)
|
||||||
throw DeadlyImportError("UNREAL: Unable to open _d file");
|
throw DeadlyImportError("UNREAL: Unable to open _d file");
|
||||||
StreamReaderLE d_reader(pIOHandler->Open(d_path));
|
StreamReaderLE d_reader(pIOHandler->Open(d_path));
|
||||||
|
@ -203,7 +203,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
d_reader.IncPtr(1);
|
d_reader.IncPtr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = pIOHandler->Open(a_path);
|
p.reset(pIOHandler->Open(a_path));
|
||||||
if (!p)
|
if (!p)
|
||||||
throw DeadlyImportError("UNREAL: Unable to open _a file");
|
throw DeadlyImportError("UNREAL: Unable to open _a file");
|
||||||
StreamReaderLE a_reader(pIOHandler->Open(a_path));
|
StreamReaderLE a_reader(pIOHandler->Open(a_path));
|
||||||
|
|
|
@ -89,9 +89,7 @@ AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
|
||||||
ai_assert(iLen > 0);
|
ai_assert(iLen > 0);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
|
||||||
ai_assert( false );
|
|
||||||
#endif
|
|
||||||
throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));
|
throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -409,12 +407,12 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
||||||
// the MSB flag is temporarily used by the extra verbose
|
// the MSB flag is temporarily used by the extra verbose
|
||||||
// mode to tell us that the JoinVerticesProcess might have
|
// mode to tell us that the JoinVerticesProcess might have
|
||||||
// been executed already.
|
// been executed already.
|
||||||
if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) &&
|
/*if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) &&
|
||||||
abRefList[face.mIndices[a]])
|
abRefList[face.mIndices[a]])
|
||||||
{
|
{
|
||||||
ReportError("aiMesh::mVertices[%i] is referenced twice - second "
|
ReportError("aiMesh::mVertices[%i] is referenced twice - second "
|
||||||
"time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
|
"time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
|
||||||
}
|
}*/
|
||||||
abRefList[face.mIndices[a]] = true;
|
abRefList[face.mIndices[a]] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,8 +107,7 @@ ASSIMP_API unsigned int aiGetCompileFlags () {
|
||||||
#include "revision.h"
|
#include "revision.h"
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API unsigned int aiGetVersionRevision ()
|
ASSIMP_API unsigned int aiGetVersionRevision() {
|
||||||
{
|
|
||||||
return GitVersion;
|
return GitVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +132,7 @@ ASSIMP_API aiScene::aiScene()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiScene::~aiScene()
|
ASSIMP_API aiScene::~aiScene() {
|
||||||
{
|
|
||||||
// delete all sub-objects recursively
|
// delete all sub-objects recursively
|
||||||
delete mRootNode;
|
delete mRootNode;
|
||||||
|
|
||||||
|
@ -173,3 +171,4 @@ ASSIMP_API aiScene::~aiScene()
|
||||||
|
|
||||||
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
|
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,8 +95,8 @@ struct WordIterator: public std::iterator<std::input_iterator_tag, const char*>
|
||||||
end_ = other.end_;
|
end_ = other.end_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
bool operator==(WordIterator &other) const { return start_ == other.start_; }
|
bool operator==(const WordIterator &other) const { return start_ == other.start_; }
|
||||||
bool operator!=(WordIterator &other) const { return start_ != other.start_; }
|
bool operator!=(const WordIterator &other) const { return start_ != other.start_; }
|
||||||
WordIterator &operator++() {
|
WordIterator &operator++() {
|
||||||
start_ += strcspn(start_, whitespace);
|
start_ += strcspn(start_, whitespace);
|
||||||
start_ += strspn(start_, whitespace);
|
start_ += strspn(start_, whitespace);
|
||||||
|
@ -558,7 +558,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector
|
||||||
|
|
||||||
WordIterator wordItBegin(val, val + strlen(val));
|
WordIterator wordItBegin(val, val + strlen(val));
|
||||||
WordIterator wordItEnd;
|
WordIterator wordItEnd;
|
||||||
std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); });
|
std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return static_cast<float>(atof(match)); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,10 @@ protected:
|
||||||
void PushTag() { startstr.append( " "); }
|
void PushTag() { startstr.append( " "); }
|
||||||
|
|
||||||
/// Leaves an element, decreasing the indentation
|
/// Leaves an element, decreasing the indentation
|
||||||
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
|
void PopTag() {
|
||||||
|
ai_assert( startstr.length() > 1);
|
||||||
|
startstr.erase( startstr.length() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Stringstream to write all output into
|
/// Stringstream to write all output into
|
||||||
|
|
|
@ -83,8 +83,11 @@ struct free_it
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
|
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
|
||||||
template<> const std::string LogFunctions<XGLImporter>::log_prefix = "XGL: ";
|
template<> const char* LogFunctions<XGLImporter>::Prefix()
|
||||||
|
{
|
||||||
|
static auto prefix = "XGL: ";
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2017, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file glTFWriter.h
|
||||||
|
* Declares a class to write gltf/glb files
|
||||||
|
*
|
||||||
|
* glTF Extensions Support:
|
||||||
|
* KHR_materials_pbrSpecularGlossiness: full
|
||||||
|
*/
|
||||||
|
#ifndef GLTF2ASSETWRITER_H_INC
|
||||||
|
#define GLTF2ASSETWRITER_H_INC
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
||||||
|
#include "glTF2Asset.h"
|
||||||
|
|
||||||
|
namespace glTF2
|
||||||
|
{
|
||||||
|
|
||||||
|
using rapidjson::MemoryPoolAllocator;
|
||||||
|
|
||||||
|
class AssetWriter
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void WriteBinaryData(IOStream* outfile, size_t sceneLength);
|
||||||
|
|
||||||
|
void WriteMetadata();
|
||||||
|
void WriteExtensionsUsed();
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void WriteObjects(LazyDict<T>& d);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Document mDoc;
|
||||||
|
Asset& mAsset;
|
||||||
|
|
||||||
|
MemoryPoolAllocator<>& mAl;
|
||||||
|
|
||||||
|
AssetWriter(Asset& asset);
|
||||||
|
|
||||||
|
void WriteFile(const char* path);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include the implementation of the methods
|
||||||
|
#include "glTF2AssetWriter.inl"
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
||||||
|
#endif // GLTF2ASSETWRITER_H_INC
|
|
@ -0,0 +1,639 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2017, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <rapidjson/stringbuffer.h>
|
||||||
|
#include <rapidjson/writer.h>
|
||||||
|
#include <rapidjson/prettywriter.h>
|
||||||
|
|
||||||
|
namespace glTF2 {
|
||||||
|
|
||||||
|
using rapidjson::StringBuffer;
|
||||||
|
using rapidjson::PrettyWriter;
|
||||||
|
using rapidjson::Writer;
|
||||||
|
using rapidjson::StringRef;
|
||||||
|
using rapidjson::StringRef;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
|
||||||
|
val.SetArray();
|
||||||
|
val.Reserve(N, al);
|
||||||
|
for (decltype(N) i = 0; i < N; ++i) {
|
||||||
|
val.PushBack(r[i], al);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
|
||||||
|
val.SetArray();
|
||||||
|
val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
|
||||||
|
for (unsigned int i = 0; i < r.size(); ++i) {
|
||||||
|
val.PushBack(r[i], al);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Value& MakeValue(Value& val, float r, MemoryPoolAllocator<>& al) {
|
||||||
|
val.SetDouble(r);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref<T> >& v, MemoryPoolAllocator<>& al) {
|
||||||
|
if (v.empty()) return;
|
||||||
|
Value lst;
|
||||||
|
lst.SetArray();
|
||||||
|
lst.Reserve(unsigned(v.size()), al);
|
||||||
|
for (size_t i = 0; i < v.size(); ++i) {
|
||||||
|
lst.PushBack(v[i]->index, al);
|
||||||
|
}
|
||||||
|
obj.AddMember(StringRef(fieldId), lst, al);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Accessor& a, AssetWriter& w)
|
||||||
|
{
|
||||||
|
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
|
||||||
|
obj.AddMember("byteOffset", a.byteOffset, w.mAl);
|
||||||
|
|
||||||
|
if (a.byteStride != 0) {
|
||||||
|
obj.AddMember("byteStride", a.byteStride, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.AddMember("componentType", int(a.componentType), w.mAl);
|
||||||
|
obj.AddMember("count", a.count, w.mAl);
|
||||||
|
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
|
||||||
|
|
||||||
|
Value vTmpMax, vTmpMin;
|
||||||
|
obj.AddMember("max", MakeValue(vTmpMax, a.max, w.mAl), w.mAl);
|
||||||
|
obj.AddMember("min", MakeValue(vTmpMin, a.min, w.mAl), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Animation& a, AssetWriter& w)
|
||||||
|
{
|
||||||
|
/****************** Channels *******************/
|
||||||
|
Value channels;
|
||||||
|
channels.SetArray();
|
||||||
|
channels.Reserve(unsigned(a.Channels.size()), w.mAl);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < unsigned(a.Channels.size()); ++i) {
|
||||||
|
Animation::AnimChannel& c = a.Channels[i];
|
||||||
|
Value valChannel;
|
||||||
|
valChannel.SetObject();
|
||||||
|
{
|
||||||
|
valChannel.AddMember("sampler", c.sampler, w.mAl);
|
||||||
|
|
||||||
|
Value valTarget;
|
||||||
|
valTarget.SetObject();
|
||||||
|
{
|
||||||
|
valTarget.AddMember("node", c.target.node->index, w.mAl);
|
||||||
|
valTarget.AddMember("path", c.target.path, w.mAl);
|
||||||
|
}
|
||||||
|
valChannel.AddMember("target", valTarget, w.mAl);
|
||||||
|
}
|
||||||
|
channels.PushBack(valChannel, w.mAl);
|
||||||
|
}
|
||||||
|
obj.AddMember("channels", channels, w.mAl);
|
||||||
|
|
||||||
|
/****************** Samplers *******************/
|
||||||
|
Value valSamplers;
|
||||||
|
valSamplers.SetArray();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < unsigned(a.Samplers.size()); ++i) {
|
||||||
|
Animation::AnimSampler& s = a.Samplers[i];
|
||||||
|
Value valSampler;
|
||||||
|
valSampler.SetObject();
|
||||||
|
{
|
||||||
|
Ref<Accessor> inputAccessor = a.GetAccessor(s.input);
|
||||||
|
Ref<Accessor> outputAccessor = a.GetAccessor(s.output);
|
||||||
|
valSampler.AddMember("input", inputAccessor->index, w.mAl);
|
||||||
|
valSampler.AddMember("interpolation", s.interpolation, w.mAl);
|
||||||
|
valSampler.AddMember("output", outputAccessor->index, w.mAl);
|
||||||
|
}
|
||||||
|
valSamplers.PushBack(valSampler, w.mAl);
|
||||||
|
}
|
||||||
|
obj.AddMember("samplers", valSamplers, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Buffer& b, AssetWriter& w)
|
||||||
|
{
|
||||||
|
obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
|
||||||
|
obj.AddMember("uri", Value(b.GetURI(), w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, BufferView& bv, AssetWriter& w)
|
||||||
|
{
|
||||||
|
obj.AddMember("buffer", bv.buffer->index, w.mAl);
|
||||||
|
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
|
||||||
|
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
|
||||||
|
obj.AddMember("target", int(bv.target), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Camera& c, AssetWriter& w)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Image& img, AssetWriter& w)
|
||||||
|
{
|
||||||
|
std::string uri;
|
||||||
|
if (img.HasData()) {
|
||||||
|
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
|
||||||
|
uri += ";base64,";
|
||||||
|
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uri = img.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.AddMember("uri", Value(uri, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline void SetTexBasic(TextureInfo t, Value& tex, MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
tex.SetObject();
|
||||||
|
tex.AddMember("index", t.texture->index, al);
|
||||||
|
|
||||||
|
if (t.texCoord != 0) {
|
||||||
|
tex.AddMember("texCoord", t.texCoord, al);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteTex(Value& obj, TextureInfo t, const char* propName, MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (t.texture) {
|
||||||
|
Value tex;
|
||||||
|
|
||||||
|
SetTexBasic(t, tex, al);
|
||||||
|
|
||||||
|
obj.AddMember(StringRef(propName), tex, al);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteTex(Value& obj, NormalTextureInfo t, const char* propName, MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (t.texture) {
|
||||||
|
Value tex;
|
||||||
|
|
||||||
|
SetTexBasic(t, tex, al);
|
||||||
|
|
||||||
|
if (t.scale != 1) {
|
||||||
|
tex.AddMember("scale", t.scale, al);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.AddMember(StringRef(propName), tex, al);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteTex(Value& obj, OcclusionTextureInfo t, const char* propName, MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (t.texture) {
|
||||||
|
Value tex;
|
||||||
|
|
||||||
|
SetTexBasic(t, tex, al);
|
||||||
|
|
||||||
|
if (t.strength != 1) {
|
||||||
|
tex.AddMember("strength", t.strength, al);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.AddMember(StringRef(propName), tex, al);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
Value arr;
|
||||||
|
obj.AddMember(StringRef(propName), MakeValue(arr, prop, al), al);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, const float(&defaultVal)[N], MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
if (!std::equal(std::begin(prop), std::end(prop), std::begin(defaultVal))) {
|
||||||
|
WriteVec(obj, prop, propName, al);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WriteFloat(Value& obj, float prop, const char* propName, MemoryPoolAllocator<>& al)
|
||||||
|
{
|
||||||
|
Value num;
|
||||||
|
obj.AddMember(StringRef(propName), MakeValue(num, prop, al), al);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Material& m, AssetWriter& w)
|
||||||
|
{
|
||||||
|
Value pbrMetallicRoughness;
|
||||||
|
pbrMetallicRoughness.SetObject();
|
||||||
|
{
|
||||||
|
WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorTexture, "baseColorTexture", w.mAl);
|
||||||
|
WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicRoughnessTexture, "metallicRoughnessTexture", w.mAl);
|
||||||
|
WriteVec(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorFactor, "baseColorFactor", defaultBaseColor, w.mAl);
|
||||||
|
|
||||||
|
if (m.pbrMetallicRoughness.metallicFactor != 1) {
|
||||||
|
WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicFactor, "metallicFactor", w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.pbrMetallicRoughness.roughnessFactor != 1) {
|
||||||
|
WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.roughnessFactor, "roughnessFactor", w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pbrMetallicRoughness.ObjectEmpty()) {
|
||||||
|
obj.AddMember("pbrMetallicRoughness", pbrMetallicRoughness, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteTex(obj, m.normalTexture, "normalTexture", w.mAl);
|
||||||
|
WriteTex(obj, m.emissiveTexture, "emissiveTexture", w.mAl);
|
||||||
|
WriteTex(obj, m.occlusionTexture, "occlusionTexture", w.mAl);
|
||||||
|
WriteVec(obj, m.emissiveFactor, "emissiveFactor", defaultEmissiveFactor, w.mAl);
|
||||||
|
|
||||||
|
if (m.alphaCutoff != 0.5) {
|
||||||
|
WriteFloat(obj, m.alphaCutoff, "alphaCutoff", w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.alphaMode != "OPAQUE") {
|
||||||
|
obj.AddMember("alphaMode", Value(m.alphaMode, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m.doubleSided) {
|
||||||
|
obj.AddMember("doubleSided", m.doubleSided, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value exts;
|
||||||
|
exts.SetObject();
|
||||||
|
|
||||||
|
if (m.pbrSpecularGlossiness.isPresent) {
|
||||||
|
Value pbrSpecularGlossiness;
|
||||||
|
pbrSpecularGlossiness.SetObject();
|
||||||
|
|
||||||
|
PbrSpecularGlossiness &pbrSG = m.pbrSpecularGlossiness.value;
|
||||||
|
|
||||||
|
//pbrSpecularGlossiness
|
||||||
|
WriteVec(pbrSpecularGlossiness, pbrSG.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl);
|
||||||
|
WriteVec(pbrSpecularGlossiness, pbrSG.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl);
|
||||||
|
|
||||||
|
if (pbrSG.glossinessFactor != 1) {
|
||||||
|
WriteFloat(obj, pbrSG.glossinessFactor, "glossinessFactor", w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteTex(pbrSpecularGlossiness, pbrSG.diffuseTexture, "diffuseTexture", w.mAl);
|
||||||
|
WriteTex(pbrSpecularGlossiness, pbrSG.specularGlossinessTexture, "specularGlossinessTexture", w.mAl);
|
||||||
|
|
||||||
|
if (!pbrSpecularGlossiness.ObjectEmpty()) {
|
||||||
|
exts.AddMember("KHR_materials_pbrSpecularGlossiness", pbrSpecularGlossiness, w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exts.ObjectEmpty()) {
|
||||||
|
obj.AddMember("extensions", exts, w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
inline void WriteAttrs(AssetWriter& w, Value& attrs, Mesh::AccessorList& lst,
|
||||||
|
const char* semantic, bool forceNumber = false)
|
||||||
|
{
|
||||||
|
if (lst.empty()) return;
|
||||||
|
if (lst.size() == 1 && !forceNumber) {
|
||||||
|
attrs.AddMember(StringRef(semantic), lst[0]->index, w.mAl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (size_t i = 0; i < lst.size(); ++i) {
|
||||||
|
char buffer[32];
|
||||||
|
ai_snprintf(buffer, 32, "%s_%d", semantic, int(i));
|
||||||
|
attrs.AddMember(Value(buffer, w.mAl).Move(), lst[i]->index, w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Mesh& m, AssetWriter& w)
|
||||||
|
{
|
||||||
|
/****************** Primitives *******************/
|
||||||
|
Value primitives;
|
||||||
|
primitives.SetArray();
|
||||||
|
primitives.Reserve(unsigned(m.primitives.size()), w.mAl);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m.primitives.size(); ++i) {
|
||||||
|
Mesh::Primitive& p = m.primitives[i];
|
||||||
|
Value prim;
|
||||||
|
prim.SetObject();
|
||||||
|
{
|
||||||
|
prim.AddMember("mode", Value(int(p.mode)).Move(), w.mAl);
|
||||||
|
|
||||||
|
if (p.material)
|
||||||
|
prim.AddMember("material", p.material->index, w.mAl);
|
||||||
|
|
||||||
|
if (p.indices)
|
||||||
|
prim.AddMember("indices", p.indices->index, w.mAl);
|
||||||
|
|
||||||
|
Value attrs;
|
||||||
|
attrs.SetObject();
|
||||||
|
{
|
||||||
|
WriteAttrs(w, attrs, p.attributes.position, "POSITION");
|
||||||
|
WriteAttrs(w, attrs, p.attributes.normal, "NORMAL");
|
||||||
|
WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD", true);
|
||||||
|
WriteAttrs(w, attrs, p.attributes.color, "COLOR", true);
|
||||||
|
WriteAttrs(w, attrs, p.attributes.joint, "JOINTS", true);
|
||||||
|
WriteAttrs(w, attrs, p.attributes.weight, "WEIGHTS", true);
|
||||||
|
}
|
||||||
|
prim.AddMember("attributes", attrs, w.mAl);
|
||||||
|
}
|
||||||
|
primitives.PushBack(prim, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj.AddMember("primitives", primitives, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Node& n, AssetWriter& w)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (n.matrix.isPresent) {
|
||||||
|
Value val;
|
||||||
|
obj.AddMember("matrix", MakeValue(val, n.matrix.value, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.translation.isPresent) {
|
||||||
|
Value val;
|
||||||
|
obj.AddMember("translation", MakeValue(val, n.translation.value, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.scale.isPresent) {
|
||||||
|
Value val;
|
||||||
|
obj.AddMember("scale", MakeValue(val, n.scale.value, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
if (n.rotation.isPresent) {
|
||||||
|
Value val;
|
||||||
|
obj.AddMember("rotation", MakeValue(val, n.rotation.value, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddRefsVector(obj, "children", n.children, w.mAl);
|
||||||
|
|
||||||
|
if (!n.meshes.empty()) {
|
||||||
|
obj.AddMember("mesh", n.meshes[0]->index, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddRefsVector(obj, "skeletons", n.skeletons, w.mAl);
|
||||||
|
|
||||||
|
if (n.skin) {
|
||||||
|
obj.AddMember("skin", n.skin->index, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!n.jointName.empty()) {
|
||||||
|
obj.AddMember("jointName", n.jointName, w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Program& b, AssetWriter& w)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Sampler& b, AssetWriter& w)
|
||||||
|
{
|
||||||
|
if (!b.name.empty()) {
|
||||||
|
obj.AddMember("name", b.name, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.wrapS != SamplerWrap::UNSET && b.wrapS != SamplerWrap::Repeat) {
|
||||||
|
obj.AddMember("wrapS", static_cast<unsigned int>(b.wrapS), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.wrapT != SamplerWrap::UNSET && b.wrapT != SamplerWrap::Repeat) {
|
||||||
|
obj.AddMember("wrapT", static_cast<unsigned int>(b.wrapT), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.magFilter != SamplerMagFilter::UNSET) {
|
||||||
|
obj.AddMember("magFilter", static_cast<unsigned int>(b.magFilter), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.minFilter != SamplerMinFilter::UNSET) {
|
||||||
|
obj.AddMember("minFilter", static_cast<unsigned int>(b.minFilter), w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& scene, Scene& s, AssetWriter& w)
|
||||||
|
{
|
||||||
|
AddRefsVector(scene, "nodes", s.nodes, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Shader& b, AssetWriter& w)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Skin& b, AssetWriter& w)
|
||||||
|
{
|
||||||
|
/****************** jointNames *******************/
|
||||||
|
Value vJointNames;
|
||||||
|
vJointNames.SetArray();
|
||||||
|
vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
|
||||||
|
vJointNames.PushBack(b.jointNames[i]->index, w.mAl);
|
||||||
|
}
|
||||||
|
obj.AddMember("joints", vJointNames, w.mAl);
|
||||||
|
|
||||||
|
if (b.bindShapeMatrix.isPresent) {
|
||||||
|
Value val;
|
||||||
|
obj.AddMember("bindShapeMatrix", MakeValue(val, b.bindShapeMatrix.value, w.mAl).Move(), w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.inverseBindMatrices) {
|
||||||
|
obj.AddMember("inverseBindMatrices", b.inverseBindMatrices->index, w.mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Write(Value& obj, Texture& tex, AssetWriter& w)
|
||||||
|
{
|
||||||
|
if (tex.source) {
|
||||||
|
obj.AddMember("source", tex.source->index, w.mAl);
|
||||||
|
}
|
||||||
|
if (tex.sampler) {
|
||||||
|
obj.AddMember("sampler", tex.sampler->index, w.mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline AssetWriter::AssetWriter(Asset& a)
|
||||||
|
: mDoc()
|
||||||
|
, mAsset(a)
|
||||||
|
, mAl(mDoc.GetAllocator())
|
||||||
|
{
|
||||||
|
mDoc.SetObject();
|
||||||
|
|
||||||
|
WriteMetadata();
|
||||||
|
WriteExtensionsUsed();
|
||||||
|
|
||||||
|
// Dump the contents of the dictionaries
|
||||||
|
for (size_t i = 0; i < a.mDicts.size(); ++i) {
|
||||||
|
a.mDicts[i]->WriteObjects(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the target scene field
|
||||||
|
if (mAsset.scene) {
|
||||||
|
mDoc.AddMember("scene", mAsset.scene->index, mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AssetWriter::WriteFile(const char* path)
|
||||||
|
{
|
||||||
|
std::unique_ptr<IOStream> jsonOutFile(mAsset.OpenFile(path, "wt", true));
|
||||||
|
|
||||||
|
if (jsonOutFile == 0) {
|
||||||
|
throw DeadlyExportError("Could not open output file: " + std::string(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer docBuffer;
|
||||||
|
|
||||||
|
PrettyWriter<StringBuffer> writer(docBuffer);
|
||||||
|
mDoc.Accept(writer);
|
||||||
|
|
||||||
|
if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write buffer data to separate .bin files
|
||||||
|
for (unsigned int i = 0; i < mAsset.buffers.Size(); ++i) {
|
||||||
|
Ref<Buffer> b = mAsset.buffers.Get(i);
|
||||||
|
|
||||||
|
std::string binPath = b->GetURI();
|
||||||
|
|
||||||
|
std::unique_ptr<IOStream> binOutFile(mAsset.OpenFile(binPath, "wb", true));
|
||||||
|
|
||||||
|
if (binOutFile == 0) {
|
||||||
|
throw DeadlyExportError("Could not open output file: " + binPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b->byteLength > 0) {
|
||||||
|
if (binOutFile->Write(b->GetPointer(), b->byteLength, 1) != 1) {
|
||||||
|
throw DeadlyExportError("Failed to write binary file: " + binPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AssetWriter::WriteMetadata()
|
||||||
|
{
|
||||||
|
Value asset;
|
||||||
|
asset.SetObject();
|
||||||
|
asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl);
|
||||||
|
asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
|
||||||
|
mDoc.AddMember("asset", asset, mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void AssetWriter::WriteExtensionsUsed()
|
||||||
|
{
|
||||||
|
Value exts;
|
||||||
|
exts.SetArray();
|
||||||
|
{
|
||||||
|
// This is used to export pbrSpecularGlossiness materials with GLTF 2.
|
||||||
|
if (this->mAsset.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
|
||||||
|
exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exts.Empty())
|
||||||
|
mDoc.AddMember("extensionsUsed", exts, mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void AssetWriter::WriteObjects(LazyDict<T>& d)
|
||||||
|
{
|
||||||
|
if (d.mObjs.empty()) return;
|
||||||
|
|
||||||
|
Value* container = &mDoc;
|
||||||
|
|
||||||
|
if (d.mExtId) {
|
||||||
|
Value* exts = FindObject(mDoc, "extensions");
|
||||||
|
if (!exts) {
|
||||||
|
mDoc.AddMember("extensions", Value().SetObject().Move(), mDoc.GetAllocator());
|
||||||
|
exts = FindObject(mDoc, "extensions");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(container = FindObject(*exts, d.mExtId))) {
|
||||||
|
exts->AddMember(StringRef(d.mExtId), Value().SetObject().Move(), mDoc.GetAllocator());
|
||||||
|
container = FindObject(*exts, d.mExtId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* dict;
|
||||||
|
if (!(dict = FindArray(*container, d.mDictId))) {
|
||||||
|
container->AddMember(StringRef(d.mDictId), Value().SetArray().Move(), mDoc.GetAllocator());
|
||||||
|
dict = FindArray(*container, d.mDictId);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < d.mObjs.size(); ++i) {
|
||||||
|
if (d.mObjs[i]->IsSpecial()) continue;
|
||||||
|
|
||||||
|
Value obj;
|
||||||
|
obj.SetObject();
|
||||||
|
|
||||||
|
if (!d.mObjs[i]->name.empty()) {
|
||||||
|
obj.AddMember("name", StringRef(d.mObjs[i]->name.c_str()), mAl);
|
||||||
|
}
|
||||||
|
|
||||||
|
Write(obj, *d.mObjs[i], *this);
|
||||||
|
|
||||||
|
dict->PushBack(obj, mAl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void WriteLazyDict(LazyDict<T>& d, AssetWriter& w)
|
||||||
|
{
|
||||||
|
w.WriteObjects(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2017, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file GltfExporter.h
|
||||||
|
* Declares the exporter class to write a scene to a gltf/glb file
|
||||||
|
*/
|
||||||
|
#ifndef AI_GLTF2EXPORTER_H_INC
|
||||||
|
#define AI_GLTF2EXPORTER_H_INC
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
||||||
|
#include <assimp/types.h>
|
||||||
|
#include <assimp/material.h>
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct aiScene;
|
||||||
|
struct aiNode;
|
||||||
|
struct aiMaterial;
|
||||||
|
|
||||||
|
namespace glTF2
|
||||||
|
{
|
||||||
|
template<class T>
|
||||||
|
class Ref;
|
||||||
|
|
||||||
|
class Asset;
|
||||||
|
struct TexProperty;
|
||||||
|
struct TextureInfo;
|
||||||
|
struct NormalTextureInfo;
|
||||||
|
struct OcclusionTextureInfo;
|
||||||
|
struct Node;
|
||||||
|
struct Texture;
|
||||||
|
|
||||||
|
// Vec/matrix types, as raw float arrays
|
||||||
|
typedef float (vec3)[3];
|
||||||
|
typedef float (vec4)[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
class IOSystem;
|
||||||
|
class IOStream;
|
||||||
|
class ExportProperties;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
/** Helper class to export a given scene to an glTF file. */
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
class glTF2Exporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Constructor for a specific scene to export
|
||||||
|
glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
|
||||||
|
const ExportProperties* pProperties, bool binary);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
const char* mFilename;
|
||||||
|
IOSystem* mIOSystem;
|
||||||
|
const aiScene* mScene;
|
||||||
|
const ExportProperties* mProperties;
|
||||||
|
|
||||||
|
std::map<std::string, unsigned int> mTexturesByPath;
|
||||||
|
|
||||||
|
std::shared_ptr<glTF2::Asset> mAsset;
|
||||||
|
|
||||||
|
std::vector<unsigned char> mBodyData;
|
||||||
|
|
||||||
|
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
|
||||||
|
|
||||||
|
void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
|
||||||
|
void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||||
|
void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||||
|
void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);
|
||||||
|
void GetMatTex(const aiMaterial* mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||||
|
void GetMatTex(const aiMaterial* mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||||
|
void GetMatTex(const aiMaterial* mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||||
|
void GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx);
|
||||||
|
void GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx);
|
||||||
|
void ExportMetadata();
|
||||||
|
void ExportMaterials();
|
||||||
|
void ExportMeshes();
|
||||||
|
void MergeMeshes();
|
||||||
|
unsigned int ExportNodeHierarchy(const aiNode* n);
|
||||||
|
unsigned int ExportNode(const aiNode* node, glTF2::Ref<glTF2::Node>& parent);
|
||||||
|
void ExportScene();
|
||||||
|
void ExportAnimations();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
||||||
|
#endif // AI_GLTF2EXPORTER_H_INC
|
|
@ -0,0 +1,654 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2017, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
||||||
|
#include "glTF2Importer.h"
|
||||||
|
#include "StringComparison.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/importerdesc.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "MakeVerboseFormat.h"
|
||||||
|
|
||||||
|
#include "glTF2Asset.h"
|
||||||
|
// This is included here so WriteLazyDict<T>'s definition is found.
|
||||||
|
#include "glTF2AssetWriter.h"
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
#include <rapidjson/rapidjson.h>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace glTF2;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// glTF2Importer
|
||||||
|
//
|
||||||
|
|
||||||
|
static const aiImporterDesc desc = {
|
||||||
|
"glTF2 Importer",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"gltf glb"
|
||||||
|
};
|
||||||
|
|
||||||
|
glTF2Importer::glTF2Importer()
|
||||||
|
: BaseImporter()
|
||||||
|
, meshOffsets()
|
||||||
|
, embeddedTexIdxs()
|
||||||
|
, mScene( NULL ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
glTF2Importer::~glTF2Importer() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiImporterDesc* glTF2Importer::GetInfo() const
|
||||||
|
{
|
||||||
|
return &desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||||
|
{
|
||||||
|
const std::string &extension = GetExtension(pFile);
|
||||||
|
|
||||||
|
if (extension != "gltf") // We currently can't read glTF2 binary files (.glb), yet
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (checkSig && pIOHandler) {
|
||||||
|
glTF2::Asset asset(pIOHandler);
|
||||||
|
try {
|
||||||
|
asset.Load(pFile);
|
||||||
|
std::string version = asset.asset.version;
|
||||||
|
return !version.empty() && version[0] == '2';
|
||||||
|
} catch (...) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
|
||||||
|
//{
|
||||||
|
// out.r = v[0]; out.g = v[1]; out.b = v[2];
|
||||||
|
//}
|
||||||
|
|
||||||
|
static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
|
||||||
|
{
|
||||||
|
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
|
||||||
|
{
|
||||||
|
out.r = v[0]; out.g = v[1]; out.b = v[2];
|
||||||
|
}*/
|
||||||
|
|
||||||
|
static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
|
||||||
|
{
|
||||||
|
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
|
||||||
|
{
|
||||||
|
out.x = v[0]; out.y = v[1]; out.z = v[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
|
||||||
|
{
|
||||||
|
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
|
||||||
|
{
|
||||||
|
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
|
||||||
|
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
|
||||||
|
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
|
||||||
|
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetMaterialColorProperty(Asset& r, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
|
||||||
|
{
|
||||||
|
aiColor4D col;
|
||||||
|
CopyValue(prop, col);
|
||||||
|
mat->AddProperty(&col, 1, pKey, type, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetMaterialColorProperty(Asset& r, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
|
||||||
|
{
|
||||||
|
aiColor4D col;
|
||||||
|
CopyValue(prop, col);
|
||||||
|
mat->AddProperty(&col, 1, pKey, type, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset& r, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0)
|
||||||
|
{
|
||||||
|
if (prop.texture && prop.texture->source) {
|
||||||
|
aiString uri(prop.texture->source->uri);
|
||||||
|
|
||||||
|
int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()];
|
||||||
|
if (texIdx != -1) { // embedded
|
||||||
|
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
|
||||||
|
uri.data[0] = '*';
|
||||||
|
uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot));
|
||||||
|
mat->AddProperty(&prop.texCoord, 1, _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, texType, texSlot);
|
||||||
|
|
||||||
|
if (prop.texture->sampler) {
|
||||||
|
Ref<Sampler> sampler = prop.texture->sampler;
|
||||||
|
|
||||||
|
aiString name(sampler->name);
|
||||||
|
aiString id(sampler->id);
|
||||||
|
|
||||||
|
mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot));
|
||||||
|
mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot));
|
||||||
|
|
||||||
|
mat->AddProperty(&sampler->wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
|
||||||
|
mat->AddProperty(&sampler->wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
|
||||||
|
|
||||||
|
if (sampler->magFilter != SamplerMagFilter::UNSET) {
|
||||||
|
mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sampler->minFilter != SamplerMinFilter::UNSET) {
|
||||||
|
mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTF2Importer::ImportMaterials(glTF2::Asset& r)
|
||||||
|
{
|
||||||
|
mScene->mNumMaterials = unsigned(r.materials.Size());
|
||||||
|
mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
||||||
|
aiMaterial* aimat = mScene->mMaterials[i] = new aiMaterial();
|
||||||
|
|
||||||
|
Material& mat = r.materials[i];
|
||||||
|
|
||||||
|
if (!mat.name.empty()) {
|
||||||
|
aiString str(mat.name);
|
||||||
|
|
||||||
|
aimat->AddProperty(&str, AI_MATKEY_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
|
||||||
|
aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR);
|
||||||
|
aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR);
|
||||||
|
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE);
|
||||||
|
SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE);
|
||||||
|
|
||||||
|
aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED);
|
||||||
|
|
||||||
|
aiString alphaMode(mat.alphaMode);
|
||||||
|
aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
|
||||||
|
aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF);
|
||||||
|
|
||||||
|
//pbrSpecularGlossiness
|
||||||
|
if (mat.pbrSpecularGlossiness.isPresent) {
|
||||||
|
PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
|
||||||
|
|
||||||
|
aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS);
|
||||||
|
SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_FACTOR);
|
||||||
|
SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULAR_FACTOR);
|
||||||
|
aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_DIFFUSE_TEXTURE);
|
||||||
|
SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_SPECULARGLOSSINESS_TEXTURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void SetFace(aiFace& face, int a)
|
||||||
|
{
|
||||||
|
face.mNumIndices = 1;
|
||||||
|
face.mIndices = new unsigned int[1];
|
||||||
|
face.mIndices[0] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void SetFace(aiFace& face, int a, int b)
|
||||||
|
{
|
||||||
|
face.mNumIndices = 2;
|
||||||
|
face.mIndices = new unsigned int[2];
|
||||||
|
face.mIndices[0] = a;
|
||||||
|
face.mIndices[1] = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void SetFace(aiFace& face, int a, int b, int c)
|
||||||
|
{
|
||||||
|
face.mNumIndices = 3;
|
||||||
|
face.mIndices = new unsigned int[3];
|
||||||
|
face.mIndices[0] = a;
|
||||||
|
face.mIndices[1] = b;
|
||||||
|
face.mIndices[2] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < nFaces; ++i) {
|
||||||
|
for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
|
||||||
|
unsigned idx = faces[i].mIndices[j];
|
||||||
|
if (idx >= nVerts)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
||||||
|
{
|
||||||
|
std::vector<aiMesh*> meshes;
|
||||||
|
|
||||||
|
unsigned int k = 0;
|
||||||
|
|
||||||
|
for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
|
||||||
|
Mesh& mesh = r.meshes[m];
|
||||||
|
|
||||||
|
meshOffsets.push_back(k);
|
||||||
|
k += unsigned(mesh.primitives.size());
|
||||||
|
|
||||||
|
for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
|
||||||
|
Mesh::Primitive& prim = mesh.primitives[p];
|
||||||
|
|
||||||
|
aiMesh* aim = new aiMesh();
|
||||||
|
meshes.push_back(aim);
|
||||||
|
|
||||||
|
aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
|
||||||
|
|
||||||
|
if (mesh.primitives.size() > 1) {
|
||||||
|
size_t& len = aim->mName.length;
|
||||||
|
aim->mName.data[len] = '-';
|
||||||
|
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (prim.mode) {
|
||||||
|
case PrimitiveMode_POINTS:
|
||||||
|
aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PrimitiveMode_LINES:
|
||||||
|
case PrimitiveMode_LINE_LOOP:
|
||||||
|
case PrimitiveMode_LINE_STRIP:
|
||||||
|
aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PrimitiveMode_TRIANGLES:
|
||||||
|
case PrimitiveMode_TRIANGLE_STRIP:
|
||||||
|
case PrimitiveMode_TRIANGLE_FAN:
|
||||||
|
aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::Primitive::Attributes& attr = prim.attributes;
|
||||||
|
|
||||||
|
if (attr.position.size() > 0 && attr.position[0]) {
|
||||||
|
aim->mNumVertices = attr.position[0]->count;
|
||||||
|
attr.position[0]->ExtractData(aim->mVertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals);
|
||||||
|
|
||||||
|
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||||
|
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
|
||||||
|
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
||||||
|
|
||||||
|
aiVector3D* values = aim->mTextureCoords[tc];
|
||||||
|
for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
|
||||||
|
values[i].y = 1 - values[i].y; // Flip Y coords
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (prim.indices) {
|
||||||
|
aiFace* faces = 0;
|
||||||
|
unsigned int nFaces = 0;
|
||||||
|
|
||||||
|
unsigned int count = prim.indices->count;
|
||||||
|
|
||||||
|
Accessor::Indexer data = prim.indices->GetIndexer();
|
||||||
|
ai_assert(data.IsValid());
|
||||||
|
|
||||||
|
switch (prim.mode) {
|
||||||
|
case PrimitiveMode_POINTS: {
|
||||||
|
nFaces = count;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; ++i) {
|
||||||
|
SetFace(faces[i], data.GetUInt(i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_LINES: {
|
||||||
|
nFaces = count / 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; i += 2) {
|
||||||
|
SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_LINE_LOOP:
|
||||||
|
case PrimitiveMode_LINE_STRIP: {
|
||||||
|
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
|
||||||
|
for (unsigned int i = 2; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
|
||||||
|
}
|
||||||
|
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
|
||||||
|
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PrimitiveMode_TRIANGLES: {
|
||||||
|
nFaces = count / 3;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
for (unsigned int i = 0; i < count; i += 3) {
|
||||||
|
SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrimitiveMode_TRIANGLE_STRIP: {
|
||||||
|
nFaces = count - 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
|
||||||
|
for (unsigned int i = 3; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PrimitiveMode_TRIANGLE_FAN:
|
||||||
|
nFaces = count - 2;
|
||||||
|
faces = new aiFace[nFaces];
|
||||||
|
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
|
||||||
|
for (unsigned int i = 3; i < count; ++i) {
|
||||||
|
SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (faces) {
|
||||||
|
aim->mFaces = faces;
|
||||||
|
aim->mNumFaces = nFaces;
|
||||||
|
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (prim.material) {
|
||||||
|
aim->mMaterialIndex = prim.material.GetIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
meshOffsets.push_back(k);
|
||||||
|
|
||||||
|
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTF2Importer::ImportCameras(glTF2::Asset& r)
|
||||||
|
{
|
||||||
|
if (!r.cameras.Size()) return;
|
||||||
|
|
||||||
|
mScene->mNumCameras = r.cameras.Size();
|
||||||
|
mScene->mCameras = new aiCamera*[r.cameras.Size()];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < r.cameras.Size(); ++i) {
|
||||||
|
Camera& cam = r.cameras[i];
|
||||||
|
|
||||||
|
aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
|
||||||
|
|
||||||
|
if (cam.type == Camera::Perspective) {
|
||||||
|
|
||||||
|
aicam->mAspect = cam.cameraProperties.perspective.aspectRatio;
|
||||||
|
aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect;
|
||||||
|
aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar;
|
||||||
|
aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// assimp does not support orthographic cameras
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>& meshOffsets, glTF2::Ref<glTF2::Node>& ptr)
|
||||||
|
{
|
||||||
|
Node& node = *ptr;
|
||||||
|
|
||||||
|
aiNode* ainode = new aiNode(node.id);
|
||||||
|
|
||||||
|
if (!node.children.empty()) {
|
||||||
|
ainode->mNumChildren = unsigned(node.children.size());
|
||||||
|
ainode->mChildren = new aiNode*[ainode->mNumChildren];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
|
||||||
|
aiNode* child = ImportNode(pScene, r, meshOffsets, node.children[i]);
|
||||||
|
child->mParent = ainode;
|
||||||
|
ainode->mChildren[i] = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMatrix4x4& matrix = ainode->mTransformation;
|
||||||
|
if (node.matrix.isPresent) {
|
||||||
|
CopyValue(node.matrix.value, matrix);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (node.translation.isPresent) {
|
||||||
|
aiVector3D trans;
|
||||||
|
CopyValue(node.translation.value, trans);
|
||||||
|
aiMatrix4x4 t;
|
||||||
|
aiMatrix4x4::Translation(trans, t);
|
||||||
|
matrix = t * matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.scale.isPresent) {
|
||||||
|
aiVector3D scal(1.f);
|
||||||
|
CopyValue(node.scale.value, scal);
|
||||||
|
aiMatrix4x4 s;
|
||||||
|
aiMatrix4x4::Scaling(scal, s);
|
||||||
|
matrix = s * matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (node.rotation.isPresent) {
|
||||||
|
aiQuaternion rot;
|
||||||
|
CopyValue(node.rotation.value, rot);
|
||||||
|
matrix = aiMatrix4x4(rot.GetMatrix()) * matrix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.meshes.empty()) {
|
||||||
|
int count = 0;
|
||||||
|
for (size_t i = 0; i < node.meshes.size(); ++i) {
|
||||||
|
int idx = node.meshes[i].GetIndex();
|
||||||
|
count += meshOffsets[idx + 1] - meshOffsets[idx];
|
||||||
|
}
|
||||||
|
ainode->mNumMeshes = count;
|
||||||
|
|
||||||
|
ainode->mMeshes = new unsigned int[count];
|
||||||
|
|
||||||
|
int k = 0;
|
||||||
|
for (size_t i = 0; i < node.meshes.size(); ++i) {
|
||||||
|
int idx = node.meshes[i].GetIndex();
|
||||||
|
for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
|
||||||
|
ainode->mMeshes[k] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.camera) {
|
||||||
|
pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ainode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTF2Importer::ImportNodes(glTF2::Asset& r)
|
||||||
|
{
|
||||||
|
if (!r.scene) return;
|
||||||
|
|
||||||
|
std::vector< Ref<Node> > rootNodes = r.scene->nodes;
|
||||||
|
|
||||||
|
// The root nodes
|
||||||
|
unsigned int numRootNodes = unsigned(rootNodes.size());
|
||||||
|
if (numRootNodes == 1) { // a single root node: use it
|
||||||
|
mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
|
||||||
|
}
|
||||||
|
else if (numRootNodes > 1) { // more than one root node: create a fake root
|
||||||
|
aiNode* root = new aiNode("ROOT");
|
||||||
|
root->mChildren = new aiNode*[numRootNodes];
|
||||||
|
for (unsigned int i = 0; i < numRootNodes; ++i) {
|
||||||
|
aiNode* node = ImportNode(mScene, r, meshOffsets, rootNodes[i]);
|
||||||
|
node->mParent = root;
|
||||||
|
root->mChildren[root->mNumChildren++] = node;
|
||||||
|
}
|
||||||
|
mScene->mRootNode = root;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!mScene->mRootNode) {
|
||||||
|
// mScene->mRootNode = new aiNode("EMPTY");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset& r)
|
||||||
|
{
|
||||||
|
embeddedTexIdxs.resize(r.images.Size(), -1);
|
||||||
|
|
||||||
|
int numEmbeddedTexs = 0;
|
||||||
|
for (size_t i = 0; i < r.images.Size(); ++i) {
|
||||||
|
if (r.images[i].HasData())
|
||||||
|
numEmbeddedTexs += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numEmbeddedTexs == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mScene->mTextures = new aiTexture*[numEmbeddedTexs];
|
||||||
|
|
||||||
|
// Add the embedded textures
|
||||||
|
for (size_t i = 0; i < r.images.Size(); ++i) {
|
||||||
|
Image img = r.images[i];
|
||||||
|
if (!img.HasData()) continue;
|
||||||
|
|
||||||
|
int idx = mScene->mNumTextures++;
|
||||||
|
embeddedTexIdxs[i] = idx;
|
||||||
|
|
||||||
|
aiTexture* tex = mScene->mTextures[idx] = new aiTexture();
|
||||||
|
|
||||||
|
size_t length = img.GetDataLength();
|
||||||
|
void* data = img.StealData();
|
||||||
|
|
||||||
|
tex->mWidth = static_cast<unsigned int>(length);
|
||||||
|
tex->mHeight = 0;
|
||||||
|
tex->pcData = reinterpret_cast<aiTexel*>(data);
|
||||||
|
|
||||||
|
if (!img.mimeType.empty()) {
|
||||||
|
const char* ext = strchr(img.mimeType.c_str(), '/') + 1;
|
||||||
|
if (ext) {
|
||||||
|
if (strcmp(ext, "jpeg") == 0) ext = "jpg";
|
||||||
|
|
||||||
|
size_t len = strlen(ext);
|
||||||
|
if (len <= 3) {
|
||||||
|
strcpy(tex->achFormatHint, ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
|
||||||
|
|
||||||
|
this->mScene = pScene;
|
||||||
|
|
||||||
|
// read the asset file
|
||||||
|
glTF2::Asset asset(pIOHandler);
|
||||||
|
asset.Load(pFile);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the data out
|
||||||
|
//
|
||||||
|
|
||||||
|
ImportEmbeddedTextures(asset);
|
||||||
|
ImportMaterials(asset);
|
||||||
|
|
||||||
|
ImportMeshes(asset);
|
||||||
|
|
||||||
|
ImportCameras(asset);
|
||||||
|
|
||||||
|
ImportNodes(asset);
|
||||||
|
|
||||||
|
// TODO: it does not split the loaded vertices, should it?
|
||||||
|
//pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
||||||
|
MakeVerboseFormatProcess process;
|
||||||
|
process.Execute(pScene);
|
||||||
|
|
||||||
|
|
||||||
|
if (pScene->mNumMeshes == 0) {
|
||||||
|
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2017, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef AI_GLTF2IMPORTER_H_INC
|
||||||
|
#define AI_GLTF2IMPORTER_H_INC
|
||||||
|
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include <assimp/DefaultIOSystem.h>
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
|
||||||
|
|
||||||
|
namespace glTF2
|
||||||
|
{
|
||||||
|
class Asset;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the glTF2 format.
|
||||||
|
* https://github.com/KhronosGroup/glTF/tree/master/specification
|
||||||
|
*/
|
||||||
|
class glTF2Importer : public BaseImporter{
|
||||||
|
public:
|
||||||
|
glTF2Importer();
|
||||||
|
virtual ~glTF2Importer();
|
||||||
|
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const aiImporterDesc* GetInfo() const;
|
||||||
|
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<unsigned int> meshOffsets;
|
||||||
|
|
||||||
|
std::vector<int> embeddedTexIdxs;
|
||||||
|
|
||||||
|
aiScene* mScene;
|
||||||
|
|
||||||
|
void ImportEmbeddedTextures(glTF2::Asset& a);
|
||||||
|
void ImportMaterials(glTF2::Asset& a);
|
||||||
|
void ImportMeshes(glTF2::Asset& a);
|
||||||
|
void ImportCameras(glTF2::Asset& a);
|
||||||
|
void ImportLights(glTF2::Asset& a);
|
||||||
|
void ImportNodes(glTF2::Asset& a);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Namespace assimp
|
||||||
|
|
||||||
|
#endif // AI_GLTF2IMPORTER_H_INC
|
||||||
|
|
|
@ -232,7 +232,9 @@ namespace glTF
|
||||||
case ComponentType_UNSIGNED_BYTE:
|
case ComponentType_UNSIGNED_BYTE:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
throw DeadlyImportError("GLTF: Unsupported Component Type "+t);
|
std::string err = "GLTF: Unsupported Component Type ";
|
||||||
|
err += t;
|
||||||
|
throw DeadlyImportError(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,13 +1060,13 @@ namespace glTF
|
||||||
std::string version; //!< Specifies the target rendering API (default: "1.0.3")
|
std::string version; //!< Specifies the target rendering API (default: "1.0.3")
|
||||||
} profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
|
} profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
|
||||||
|
|
||||||
int version; //!< The glTF format version (should be 1)
|
std::string version; //!< The glTF format version (should be 1.0)
|
||||||
|
|
||||||
void Read(Document& doc);
|
void Read(Document& doc);
|
||||||
|
|
||||||
AssetMetadata()
|
AssetMetadata()
|
||||||
: premultipliedAlpha(false)
|
: premultipliedAlpha(false)
|
||||||
, version(0)
|
, version("")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StringUtils.h"
|
#include "StringUtils.h"
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
// Header files, Assimp
|
// Header files, Assimp
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
@ -128,6 +129,12 @@ namespace {
|
||||||
return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0;
|
return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Value* FindNumber(Value& val, const char* id)
|
||||||
|
{
|
||||||
|
Value::MemberIterator it = val.FindMember(id);
|
||||||
|
return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline Value* FindArray(Value& val, const char* id)
|
inline Value* FindArray(Value& val, const char* id)
|
||||||
{
|
{
|
||||||
Value::MemberIterator it = val.FindMember(id);
|
Value::MemberIterator it = val.FindMember(id);
|
||||||
|
@ -309,7 +316,9 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
||||||
}
|
}
|
||||||
else { // Local file
|
else { // Local file
|
||||||
if (byteLength > 0) {
|
if (byteLength > 0) {
|
||||||
IOStream* file = r.OpenFile(uri, "rb");
|
std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir + "/") : "";
|
||||||
|
|
||||||
|
IOStream* file = r.OpenFile(dir + uri, "rb");
|
||||||
if (file) {
|
if (file) {
|
||||||
bool ok = LoadFromStream(*file, byteLength);
|
bool ok = LoadFromStream(*file, byteLength);
|
||||||
delete file;
|
delete file;
|
||||||
|
@ -332,7 +341,7 @@ inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseO
|
||||||
stream.Seek(baseOffset, aiOrigin_SET);
|
stream.Seek(baseOffset, aiOrigin_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
mData.reset(new uint8_t[byteLength]);
|
mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());
|
||||||
|
|
||||||
if (stream.Read(mData.get(), byteLength, 1) != 1) {
|
if (stream.Read(mData.get(), byteLength, 1) != 1) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1228,13 +1237,21 @@ inline void Scene::Read(Value& obj, Asset& r)
|
||||||
inline void AssetMetadata::Read(Document& doc)
|
inline void AssetMetadata::Read(Document& doc)
|
||||||
{
|
{
|
||||||
// read the version, etc.
|
// read the version, etc.
|
||||||
int statedVersion = 0;
|
|
||||||
if (Value* obj = FindObject(doc, "asset")) {
|
if (Value* obj = FindObject(doc, "asset")) {
|
||||||
ReadMember(*obj, "copyright", copyright);
|
ReadMember(*obj, "copyright", copyright);
|
||||||
ReadMember(*obj, "generator", generator);
|
ReadMember(*obj, "generator", generator);
|
||||||
|
|
||||||
premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
|
premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
|
||||||
statedVersion = MemberOrDefault(*obj, "version", 0);
|
|
||||||
|
if (Value* versionString = FindString(*obj, "version")) {
|
||||||
|
version = versionString->GetString();
|
||||||
|
} else if (Value* versionNumber = FindNumber (*obj, "version")) {
|
||||||
|
char buf[4];
|
||||||
|
|
||||||
|
ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
|
||||||
|
|
||||||
|
version = buf;
|
||||||
|
}
|
||||||
|
|
||||||
if (Value* profile = FindObject(*obj, "profile")) {
|
if (Value* profile = FindObject(*obj, "profile")) {
|
||||||
ReadMember(*profile, "api", this->profile.api);
|
ReadMember(*profile, "api", this->profile.api);
|
||||||
|
@ -1242,16 +1259,8 @@ inline void AssetMetadata::Read(Document& doc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
version = std::max(statedVersion, version);
|
if (version.empty() || version[0] != '1') {
|
||||||
if (version == 0) {
|
throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
|
||||||
// if missing version, we'll assume version 1...
|
|
||||||
version = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version != 1) {
|
|
||||||
char msg[128];
|
|
||||||
ai_snprintf(msg, 128, "GLTF: Unsupported glTF version: %d", version);
|
|
||||||
throw DeadlyImportError(msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1273,7 +1282,7 @@ inline void Asset::ReadBinaryHeader(IOStream& stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_SWAP4(header.version);
|
AI_SWAP4(header.version);
|
||||||
asset.version = header.version;
|
asset.version = std::to_string(header.version);
|
||||||
if (header.version != 1) {
|
if (header.version != 1) {
|
||||||
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
||||||
}
|
}
|
||||||
|
|
|
@ -606,13 +606,8 @@ namespace glTF {
|
||||||
{
|
{
|
||||||
Value asset;
|
Value asset;
|
||||||
asset.SetObject();
|
asset.SetObject();
|
||||||
{
|
asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl);
|
||||||
char versionChar[10];
|
|
||||||
ai_snprintf(versionChar, sizeof(versionChar), "%d", mAsset.asset.version);
|
|
||||||
asset.AddMember("version", Value(versionChar, mAl).Move(), mAl);
|
|
||||||
|
|
||||||
asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
|
asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
|
||||||
}
|
|
||||||
mDoc.AddMember("asset", asset, mAl);
|
mDoc.AddMember("asset", asset, mAl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -444,7 +444,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
|
||||||
Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
|
Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
|
||||||
nodeRef->jointName = nodeRef->id;
|
nodeRef->jointName = nodeRef->id;
|
||||||
|
|
||||||
unsigned int jointNamesIndex;
|
unsigned int jointNamesIndex = 0;
|
||||||
bool addJointToJointNames = true;
|
bool addJointToJointNames = true;
|
||||||
for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
||||||
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
||||||
|
@ -473,7 +473,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexJointData[vertexId][jointsPerVertex[vertexId]] = jointNamesIndex;
|
vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
|
||||||
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
|
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
|
||||||
|
|
||||||
jointsPerVertex[vertexId] += 1;
|
jointsPerVertex[vertexId] += 1;
|
||||||
|
@ -507,7 +507,7 @@ void glTFExporter::ExportMeshes()
|
||||||
|
|
||||||
// Variables needed for compression. BEGIN.
|
// Variables needed for compression. BEGIN.
|
||||||
// Indices, not pointers - because pointer to buffer is changing while writing to it.
|
// Indices, not pointers - because pointer to buffer is changing while writing to it.
|
||||||
size_t idx_srcdata_begin;// Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
|
size_t idx_srcdata_begin = 0; // Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
|
||||||
size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
|
size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
|
||||||
std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
|
std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
|
||||||
size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer.
|
size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer.
|
||||||
|
@ -872,10 +872,10 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
||||||
size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
|
size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
|
||||||
// mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
|
// mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
|
||||||
// Check if we have to cast type here. e.g. uint16_t()
|
// Check if we have to cast type here. e.g. uint16_t()
|
||||||
timeData[i] = nodeChannel->mPositionKeys[frameIndex].mTime / ticksPerSecond;
|
timeData[i] = static_cast<float>(nodeChannel->mPositionKeys[frameIndex].mTime / ticksPerSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, numKeyframes, &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
|
Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
|
||||||
if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
|
if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -888,7 +888,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
||||||
translationData[i] = nodeChannel->mPositionKeys[frameIndex].mValue;
|
translationData[i] = nodeChannel->mPositionKeys[frameIndex].mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, numKeyframes, translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||||
if ( tranAccessor ) {
|
if ( tranAccessor ) {
|
||||||
animRef->Parameters.translation = tranAccessor;
|
animRef->Parameters.translation = tranAccessor;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +904,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
||||||
scaleData[i] = nodeChannel->mScalingKeys[frameIndex].mValue;
|
scaleData[i] = nodeChannel->mScalingKeys[frameIndex].mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, numKeyframes, scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||||
if ( scaleAccessor ) {
|
if ( scaleAccessor ) {
|
||||||
animRef->Parameters.scale = scaleAccessor;
|
animRef->Parameters.scale = scaleAccessor;
|
||||||
}
|
}
|
||||||
|
@ -923,7 +923,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
||||||
rotationData[i][3] = nodeChannel->mRotationKeys[frameIndex].mValue.w;
|
rotationData[i][3] = nodeChannel->mRotationKeys[frameIndex].mValue.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, numKeyframes, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||||
if ( rotAccessor ) {
|
if ( rotAccessor ) {
|
||||||
animRef->Parameters.rotation = rotAccessor;
|
animRef->Parameters.rotation = rotAccessor;
|
||||||
}
|
}
|
||||||
|
@ -953,7 +953,7 @@ void glTFExporter::ExportAnimations()
|
||||||
Ref<Animation> animRef = mAsset->animations.Create(name);
|
Ref<Animation> animRef = mAsset->animations.Create(name);
|
||||||
|
|
||||||
/******************* Parameters ********************/
|
/******************* Parameters ********************/
|
||||||
ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel, anim->mTicksPerSecond);
|
ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel, static_cast<float>(anim->mTicksPerSecond));
|
||||||
|
|
||||||
for (unsigned int j = 0; j < 3; ++j) {
|
for (unsigned int j = 0; j < 3; ++j) {
|
||||||
std::string channelType;
|
std::string channelType;
|
||||||
|
|
|
@ -100,24 +100,19 @@ const aiImporterDesc* glTFImporter::GetInfo() const
|
||||||
|
|
||||||
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||||
{
|
{
|
||||||
const std::string& extension = GetExtension(pFile);
|
const std::string &extension = GetExtension(pFile);
|
||||||
|
|
||||||
if (extension == "gltf" || extension == "glb")
|
if (extension != "gltf" && extension != "glb")
|
||||||
return true;
|
return false;
|
||||||
|
|
||||||
if ((checkSig || !extension.length()) && pIOHandler) {
|
if (checkSig && pIOHandler) {
|
||||||
char buffer[4];
|
glTF::Asset asset(pIOHandler);
|
||||||
|
try {
|
||||||
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile));
|
asset.Load(pFile, extension == "glb");
|
||||||
if (pStream && pStream->Read(buffer, sizeof(buffer), 1) == 1) {
|
std::string version = asset.asset.version;
|
||||||
if (memcmp(buffer, AI_GLB_MAGIC_NUMBER, sizeof(buffer)) == 0) {
|
return !version.empty() && version[0] == '1';
|
||||||
return true; // Has GLB header
|
} catch (...) {
|
||||||
}
|
return false;
|
||||||
else if (memcmp(buffer, "{\r\n ", sizeof(buffer)) == 0
|
|
||||||
|| memcmp(buffer, "{\n ", sizeof(buffer)) == 0) {
|
|
||||||
// seems a JSON file, and we're the only format that can read them
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,10 +174,8 @@ inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& r
|
||||||
else {
|
else {
|
||||||
aiColor4D col;
|
aiColor4D col;
|
||||||
CopyValue(prop.color, col);
|
CopyValue(prop.color, col);
|
||||||
if (col.r != 1.f || col.g != 1.f || col.b != 1.f || col.a != 1.f) {
|
|
||||||
mat->AddProperty(&col, 1, pKey, type, idx);
|
mat->AddProperty(&col, 1, pKey, type, idx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void glTFImporter::ImportMaterials(glTF::Asset& r)
|
void glTFImporter::ImportMaterials(glTF::Asset& r)
|
||||||
|
|
|
@ -140,8 +140,8 @@ namespace o3dgc
|
||||||
{
|
{
|
||||||
return End(element) - Begin(element);
|
return End(element) - Begin(element);
|
||||||
}
|
}
|
||||||
long * const GetNumNeighborsBuffer() { return m_numNeighbors;}
|
long * GetNumNeighborsBuffer() { return m_numNeighbors;}
|
||||||
long * const GetNeighborsBuffer() { return m_neighbors;}
|
long * GetNeighborsBuffer() { return m_neighbors;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long m_neighborsSize; // actual allocated size for m_neighbors
|
long m_neighborsSize; // actual allocated size for m_neighbors
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue