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
|
||||
LICENSE 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()
|
||||
{
|
||||
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
|
||||
|
|
47
.travis.yml
47
.travis.yml
|
@ -1,9 +1,19 @@
|
|||
sudo: required
|
||||
language: cpp
|
||||
|
||||
cache: ccache
|
||||
|
||||
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" = "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
|
||||
# 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
|
||||
|
@ -12,22 +22,36 @@ branches:
|
|||
only:
|
||||
- master
|
||||
|
||||
osx_image: xcode8.3
|
||||
os:
|
||||
- linux
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
global:
|
||||
# COVERITY_SCAN_TOKEN
|
||||
- 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}
|
||||
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:
|
||||
- gcc
|
||||
- clang
|
||||
matrix:
|
||||
include:
|
||||
- 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:
|
||||
- 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_REPO_TOKEN=abc12345
|
||||
- . ./.travis.sh
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
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
|
||||
|
|
12
CHANGES
12
CHANGES
|
@ -1,6 +1,18 @@
|
|||
----------------------------------------------------------------------
|
||||
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)
|
||||
|
||||
FEATURES:
|
||||
|
|
147
CMakeLists.txt
147
CMakeLists.txt
|
@ -34,7 +34,7 @@
|
|||
# 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
|
||||
cmake_minimum_required( VERSION 2.8 )
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
PROJECT( Assimp )
|
||||
|
||||
# All supported options ###############################################
|
||||
|
@ -62,11 +62,11 @@ OPTION( ASSIMP_BUILD_ZLIB
|
|||
"Build your own zlib"
|
||||
OFF
|
||||
)
|
||||
option( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||
OPTION( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||
"If the supplementary tools for Assimp are built in addition to the library."
|
||||
ON
|
||||
)
|
||||
option ( ASSIMP_BUILD_SAMPLES
|
||||
OPTION ( ASSIMP_BUILD_SAMPLES
|
||||
"If the official samples are built as well (needs Glut)."
|
||||
OFF
|
||||
)
|
||||
|
@ -75,24 +75,36 @@ OPTION ( ASSIMP_BUILD_TESTS
|
|||
ON
|
||||
)
|
||||
OPTION ( ASSIMP_COVERALLS
|
||||
"Eańable this to measure test coverage."
|
||||
OFF
|
||||
"Enable this to measure test coverage."
|
||||
OFF
|
||||
)
|
||||
option ( SYSTEM_IRRXML
|
||||
"Use system installed Irrlicht/IrrXML library."
|
||||
OFF
|
||||
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."
|
||||
OFF
|
||||
)
|
||||
OPTION ( BUILD_DOCS
|
||||
"Build documentation using Doxygen."
|
||||
OFF
|
||||
"Build documentation using Doxygen."
|
||||
OFF
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
add_definitions( -DWIN32_LEAN_AND_MEAN )
|
||||
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
|
||||
endif()
|
||||
|
||||
IF(MSVC)
|
||||
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||
SET (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||
OPTION( ASSIMP_INSTALL_PDB
|
||||
"Install MSVC debug files."
|
||||
ON
|
||||
|
@ -100,21 +112,24 @@ IF(MSVC)
|
|||
ENDIF(MSVC)
|
||||
|
||||
IF(NOT BUILD_SHARED_LIBS)
|
||||
MESSAGE(STATUS "Shared libraries disabled")
|
||||
SET(LINK_SEARCH_START_STATIC TRUE)
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Shared libraries enabled")
|
||||
ENDIF(NOT BUILD_SHARED_LIBS)
|
||||
|
||||
# Define here the needed parameters
|
||||
SET (ASSIMP_VERSION_MAJOR 4)
|
||||
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_SOVERSION 4)
|
||||
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
|
||||
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||
ADD_DEFINITIONS( -DOPENDDL_NO_USE_CPP11 )
|
||||
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
|
||||
|
||||
# Get the current working branch
|
||||
|
@ -136,32 +151,26 @@ EXECUTE_PROCESS(
|
|||
)
|
||||
|
||||
IF(NOT GIT_COMMIT_HASH)
|
||||
SET(GIT_COMMIT_HASH 0)
|
||||
SET(GIT_COMMIT_HASH 0)
|
||||
ENDIF(NOT GIT_COMMIT_HASH)
|
||||
|
||||
IF(ASSIMP_DOUBLE_PRECISION)
|
||||
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
||||
|
||||
# Check for OpenMP support
|
||||
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(
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||
)
|
||||
|
||||
configure_file(
|
||||
CONFIGURE_FILE(
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/assimp/config.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/assimp/config.h
|
||||
)
|
||||
|
||||
include_directories(
|
||||
INCLUDE_DIRECTORIES(
|
||||
./
|
||||
include
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
)
|
||||
|
@ -179,7 +188,7 @@ IF( UNIX )
|
|||
ENDIF()
|
||||
|
||||
# Use GNUInstallDirs for Unix predefined directories
|
||||
include(GNUInstallDirs)
|
||||
INCLUDE(GNUInstallDirs)
|
||||
ENDIF( UNIX )
|
||||
|
||||
|
||||
|
@ -192,20 +201,48 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
|||
ELSEIF(MSVC)
|
||||
# enable multi-core compilation with MSVC
|
||||
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" )
|
||||
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 )
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
|
||||
add_definitions( -U__STRICT_ANSI__ )
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" )
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
|
||||
ENDIF()
|
||||
|
||||
if (ASSIMP_COVERALLS)
|
||||
include(Coveralls)
|
||||
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")
|
||||
MESSAGE(STATUS "Coveralls enabled")
|
||||
INCLUDE(Coveralls)
|
||||
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()
|
||||
|
||||
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 (PrecompiledHeader)
|
||||
|
@ -237,13 +274,13 @@ ENDIF()
|
|||
# Only generate this target if no higher-level project already has
|
||||
IF (NOT TARGET uninstall)
|
||||
# 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")
|
||||
ENDIF()
|
||||
|
||||
# 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-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.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)
|
||||
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 )
|
||||
|
@ -265,9 +302,9 @@ ENDIF( NOT ASSIMP_BUILD_ZLIB )
|
|||
|
||||
IF( NOT ZLIB_FOUND )
|
||||
message(STATUS "compiling zlib from souces")
|
||||
include(CheckIncludeFile)
|
||||
include(CheckTypeSize)
|
||||
include(CheckFunctionExists)
|
||||
INCLUDE(CheckIncludeFile)
|
||||
INCLUDE(CheckTypeSize)
|
||||
INCLUDE(CheckFunctionExists)
|
||||
# compile from sources
|
||||
add_subdirectory(contrib/zlib)
|
||||
SET(ZLIB_FOUND 1)
|
||||
|
@ -472,13 +509,25 @@ if(WIN32)
|
|||
|
||||
if(MSVC12 OR MSVC14)
|
||||
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)
|
||||
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.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.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.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.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.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)
|
||||
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.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.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.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.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.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.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.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 (WIN32)
|
||||
|
|
91
Readme.md
91
Readme.md
|
@ -1,5 +1,6 @@
|
|||
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 ###
|
||||
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
|
||||
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
|
||||
|
@ -7,7 +8,6 @@ Open Asset Import Library (assimp)
|
|||
<img alt="Coverity Scan Build Status"
|
||||
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
||||
</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>
|
||||
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
||||
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
<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).
|
||||
|
||||
Monthly donations via Patreon:
|
||||
<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
|
||||
|
||||
<br>
|
||||
|
||||
One-off donations via PayPal:
|
||||
<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](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).
|
||||
__Importers__:
|
||||
|
||||
- 3D
|
||||
- 3DS
|
||||
- BLEND (Blender)
|
||||
- DAE/Collada
|
||||
- FBX
|
||||
- IFC-STEP
|
||||
- 3MF
|
||||
- AC
|
||||
- AC3D
|
||||
- ACC
|
||||
- AMJ
|
||||
- ASE
|
||||
- ASK
|
||||
- B3D;
|
||||
- BLEND (Blender)
|
||||
- BVH
|
||||
- COB
|
||||
- CMS
|
||||
- DAE/Collada
|
||||
- DXF
|
||||
- HMP
|
||||
- ENFF
|
||||
- FBX
|
||||
- glTF 1.0 + GLB
|
||||
- glTF 2.0
|
||||
- HMB
|
||||
- IFC-STEP
|
||||
- IRR / IRRMESH
|
||||
- LWO
|
||||
- LWS
|
||||
- LXO
|
||||
- MD2
|
||||
- MD3
|
||||
- MD5
|
||||
- MDC
|
||||
- MDL
|
||||
- NFF
|
||||
- PLY
|
||||
- STL
|
||||
- X
|
||||
- OBJ
|
||||
- OpenGEX
|
||||
- SMD
|
||||
- LWO
|
||||
- LXO
|
||||
- LWS
|
||||
- TER
|
||||
- AC3D
|
||||
- MESH / MESH.XML
|
||||
- MOT
|
||||
- MS3D
|
||||
- COB
|
||||
- Q3BSP
|
||||
- XGL
|
||||
- CSM
|
||||
- BVH
|
||||
- B3D
|
||||
- NDO
|
||||
- Ogre Binary
|
||||
- Ogre XML
|
||||
- Q3D
|
||||
- ASSBIN (Assimp custom format)
|
||||
- glTF (partial)
|
||||
- 3MF
|
||||
- NFF
|
||||
- OBJ
|
||||
- OFF
|
||||
- OGEX
|
||||
- PLY
|
||||
- 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):
|
||||
|
||||
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
||||
- C4D (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange)
|
||||
|
||||
__Exporters__:
|
||||
|
||||
|
@ -85,7 +107,8 @@ __Exporters__:
|
|||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||
- ASSBIN
|
||||
- STEP
|
||||
- glTF (partial)
|
||||
- glTF 1.0 (partial)
|
||||
- glTF 2.0 (partial)
|
||||
|
||||
### 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.
|
||||
|
@ -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)
|
||||
* [Pascal](port/AssimpPascal/Readme.md)
|
||||
* [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 ###
|
||||
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
|
||||
|
|
65
appveyor.yml
65
appveyor.yml
|
@ -10,33 +10,54 @@ branches:
|
|||
only:
|
||||
- master
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
image:
|
||||
- Visual Studio 2013
|
||||
- Visual Studio 2015
|
||||
- Visual Studio 2017
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
configuration:
|
||||
- 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 ) ) )
|
||||
- Win32
|
||||
- x64
|
||||
|
||||
configuration: Release
|
||||
|
||||
install:
|
||||
# Make compiler command line tools available
|
||||
- call c:\projects\assimp\scripts\appveyor\compiler_setup.bat
|
||||
|
||||
build_script:
|
||||
- cd c:\projects\assimp
|
||||
- if "%platform%" equ "x64" (cmake CMakeLists.txt -G "Visual Studio %Configuration% Win64")
|
||||
- if "%platform%" equ "x86" (cmake CMakeLists.txt -G "Visual Studio %Configuration%")
|
||||
- if "%platform%" equ "x64" (msbuild /m /p:Configuration=Release /p:Platform="x64" Assimp.sln)
|
||||
- if "%platform%" equ "x86" (msbuild /m /p:Configuration=Release /p:Platform="Win32" Assimp.sln)
|
||||
|
||||
- set PATH=C:\Ruby24-x64\bin;%PATH%
|
||||
- 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%"
|
||||
|
||||
cache:
|
||||
- code\assimp.dir\%CONFIGURATION%
|
||||
- contrib\zlib\zlibstatic.dir\%CONFIGURATION%
|
||||
- contrib\zlib\zlib.dir\%CONFIGURATION%
|
||||
- tools\assimp_cmd\assimp_cmd.dir\%CONFIGURATION%
|
||||
- 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:
|
||||
- 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:
|
||||
- path: assimp.7z
|
||||
name: assimp_lib
|
||||
|
|
|
@ -56,18 +56,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
static const unsigned int NotSet = 0xcdcdcdcd;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup final material indices, generae a default material if necessary
|
||||
void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||
{
|
||||
|
||||
// Try to find an existing material that matches the
|
||||
// typical default material setting:
|
||||
// - no textures
|
||||
// - diffuse color (in grey!)
|
||||
// NOTE: This is here to workaround the fact that some
|
||||
// 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)
|
||||
{
|
||||
std::string s = mScene->mMaterials[i].mName;
|
||||
|
@ -93,7 +94,9 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
|
|||
}
|
||||
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
|
||||
// find all faces that are using the default material
|
||||
|
|
|
@ -1381,7 +1381,7 @@ void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent )
|
|||
bGamma = true;
|
||||
|
||||
case Discreet3DS::CHUNK_RGBF:
|
||||
if (sizeof(ai_real) * 3 > diff) {
|
||||
if (sizeof(float) * 3 > diff) {
|
||||
*out = clrError;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -686,7 +686,6 @@ std::list<unsigned int> mesh_idx;
|
|||
tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
|
||||
tmesh->mVertices = new aiVector3D[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->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;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// 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
|
||||
template <>
|
||||
|
@ -325,7 +336,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
|||
{
|
||||
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<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<aiVector3D>(&chunk,(const aiVector3D&)l->mColorDiffuse);
|
||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorSpecular);
|
||||
Write<aiVector3D>(&chunk,(const aiVector3D&)l->mColorAmbient);
|
||||
Write<aiColor3D>(&chunk,l->mColorDiffuse);
|
||||
Write<aiColor3D>(&chunk,l->mColorSpecular);
|
||||
Write<aiColor3D>(&chunk,l->mColorAmbient);
|
||||
|
||||
if (l->mType == aiLightSource_SPOT) {
|
||||
Write<float>(&chunk,l->mAngleInnerCone);
|
||||
|
|
|
@ -71,7 +71,6 @@ class AssbinImporter : public BaseImporter
|
|||
private:
|
||||
bool shortened;
|
||||
bool compressed;
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual bool CanRead(
|
||||
|
|
|
@ -82,6 +82,20 @@ static const aiImporterDesc desc = {
|
|||
|
||||
//#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{
|
||||
|
||||
|
@ -157,7 +171,8 @@ int B3DImporter::ReadByte(){
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
int B3DImporter::ReadInt(){
|
||||
if( _pos+4<=_buf.size() ){
|
||||
int n=*(int*)&_buf[_pos];
|
||||
int n;
|
||||
memcpy(&n, &_buf[_pos], 4);
|
||||
_pos+=4;
|
||||
return n;
|
||||
}
|
||||
|
@ -168,7 +183,8 @@ int B3DImporter::ReadInt(){
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
float B3DImporter::ReadFloat(){
|
||||
if( _pos+4<=_buf.size() ){
|
||||
float n=*(float*)&_buf[_pos];
|
||||
float n;
|
||||
memcpy(&n, &_buf[_pos], 4);
|
||||
_pos+=4;
|
||||
return n;
|
||||
}
|
||||
|
@ -558,13 +574,19 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
|||
void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||
|
||||
_textures.clear();
|
||||
|
||||
_materials.clear();
|
||||
|
||||
_vertices.clear();
|
||||
|
||||
_meshes.clear();
|
||||
|
||||
DeleteAllBarePointers(_nodes);
|
||||
_nodes.clear();
|
||||
|
||||
_nodeAnims.clear();
|
||||
|
||||
DeleteAllBarePointers(_animations);
|
||||
_animations.clear();
|
||||
|
||||
string t=ReadChunk();
|
||||
|
|
|
@ -59,6 +59,8 @@ namespace Assimp{
|
|||
|
||||
class B3DImporter : public BaseImporter{
|
||||
public:
|
||||
B3DImporter() = default;
|
||||
virtual ~B3DImporter();
|
||||
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -253,7 +253,7 @@ public:
|
|||
* a compiler complain is the result.
|
||||
* @param dest Destination value to be written
|
||||
* @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
|
||||
|
|
|
@ -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)
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
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;
|
||||
|
|
|
@ -59,7 +59,11 @@ static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
|
|||
|
||||
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;
|
||||
|
@ -252,7 +256,11 @@ void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
|||
|
||||
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;
|
||||
|
|
|
@ -393,7 +393,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||
{
|
||||
assert(object != NULL && object->GetType() == Opolygon);
|
||||
ai_assert(object != NULL && object->GetType() == Opolygon);
|
||||
|
||||
// based on Melange sample code
|
||||
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
||||
|
@ -635,7 +635,7 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
|
|||
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
|
||||
|
||||
BaseMaterial* const mat = ttag.GetMaterial();
|
||||
assert(mat != NULL);
|
||||
ai_assert(mat != NULL);
|
||||
|
||||
const MaterialMap::const_iterator it = material_mapping.find(mat);
|
||||
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 "LogAux.h"
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
struct aiNode;
|
||||
struct aiMesh;
|
||||
struct aiMaterial;
|
||||
|
|
|
@ -61,6 +61,7 @@ SET( PUBLIC_HEADERS
|
|||
${HEADER_PATH}/color4.inl
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
|
||||
${HEADER_PATH}/defs.h
|
||||
${HEADER_PATH}/Defines.h
|
||||
${HEADER_PATH}/cfileio.h
|
||||
${HEADER_PATH}/light.h
|
||||
${HEADER_PATH}/material.h
|
||||
|
@ -661,6 +662,14 @@ ADD_ASSIMP_IMPORTER( GLTF
|
|||
glTFImporter.h
|
||||
glTFExporter.h
|
||||
glTFExporter.cpp
|
||||
glTF2Asset.h
|
||||
glTF2Asset.inl
|
||||
glTF2AssetWriter.h
|
||||
glTF2AssetWriter.inl
|
||||
glTF2Importer.cpp
|
||||
glTF2Importer.h
|
||||
glTF2Exporter.h
|
||||
glTF2Exporter.cpp
|
||||
)
|
||||
|
||||
ADD_ASSIMP_IMPORTER( 3MF
|
||||
|
@ -934,14 +943,25 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM)
|
|||
endif(ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
|
||||
if(MSVC AND ASSIMP_INSTALL_PDB)
|
||||
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
|
||||
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
CONFIGURATIONS Debug
|
||||
)
|
||||
install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb
|
||||
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
CONFIGURATIONS RelWithDebInfo
|
||||
)
|
||||
IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
|
||||
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
|
||||
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
CONFIGURATIONS Debug
|
||||
)
|
||||
install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb
|
||||
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
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 ()
|
||||
|
||||
if (ASSIMP_COVERALLS)
|
||||
|
|
|
@ -866,8 +866,8 @@ void ColladaExporter::WriteController( size_t pIndex)
|
|||
|
||||
std::vector<ai_real> bind_poses;
|
||||
bind_poses.reserve(mesh->mNumBones * 16);
|
||||
for( size_t i = 0; i < mesh->mNumBones; ++i)
|
||||
for( size_t j = 0; j < 4; ++j)
|
||||
for(unsigned int i = 0; i < mesh->mNumBones; ++i)
|
||||
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);
|
||||
|
||||
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;
|
||||
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( size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
|
||||
for( unsigned int i = 0; i < mesh->mNumBones; ++i)
|
||||
for( unsigned j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -128,7 +128,10 @@ protected:
|
|||
/// Enters a new xml element, which increases the indentation
|
||||
void PushTag() { startstr.append( " "); }
|
||||
/// 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
|
||||
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.
|
||||
*/
|
||||
if (!pIOHandler)return true;
|
||||
const char* tokens[] = {"collada"};
|
||||
const char* tokens[] = {"<collada"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||
}
|
||||
return false;
|
||||
|
@ -674,7 +674,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|||
// create morph target meshes if any
|
||||
std::vector<aiMesh*> targetMeshes;
|
||||
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();
|
||||
it != pParser.mControllerLibrary.end(); it++)
|
||||
|
@ -728,7 +728,7 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|||
? aiMorphingMethod_MORPH_RELATIVE
|
||||
: aiMorphingMethod_MORPH_NORMALIZED;
|
||||
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++)
|
||||
dstMesh->mAnimMeshes[i] = animMeshes.at(i);
|
||||
}
|
||||
|
@ -1377,9 +1377,9 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
{
|
||||
aiNodeAnim* dstAnim = new aiNodeAnim;
|
||||
dstAnim->mNodeName = nodeName;
|
||||
dstAnim->mNumPositionKeys = resultTrafos.size();
|
||||
dstAnim->mNumRotationKeys= resultTrafos.size();
|
||||
dstAnim->mNumScalingKeys = resultTrafos.size();
|
||||
dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mNumScalingKeys = static_cast<unsigned int>(resultTrafos.size());
|
||||
dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
|
||||
dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
|
||||
dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
|
||||
|
@ -1445,11 +1445,11 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
++morphAnimChannelIndex;
|
||||
}
|
||||
|
||||
morphAnim->mNumKeys = morphTimeValues.size();
|
||||
morphAnim->mNumKeys = static_cast<unsigned int>(morphTimeValues.size());
|
||||
morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys];
|
||||
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].mWeights = new double [morphChannels.size()];
|
||||
|
||||
|
@ -1470,13 +1470,13 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
{
|
||||
aiAnimation* anim = new aiAnimation;
|
||||
anim->mName.Set( pName);
|
||||
anim->mNumChannels = anims.size();
|
||||
anim->mNumChannels = static_cast<unsigned int>(anims.size());
|
||||
if (anim->mNumChannels > 0)
|
||||
{
|
||||
anim->mChannels = new aiNodeAnim*[anims.size()];
|
||||
std::copy( anims.begin(), anims.end(), anim->mChannels);
|
||||
}
|
||||
anim->mNumMorphMeshChannels = morphAnims.size();
|
||||
anim->mNumMorphMeshChannels = static_cast<unsigned int>(morphAnims.size());
|
||||
if (anim->mNumMorphMeshChannels > 0)
|
||||
{
|
||||
anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
|
||||
|
|
|
@ -2231,7 +2231,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
|||
}
|
||||
|
||||
#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'.
|
||||
ai_assert(actualPrimitives == numPrimitives);
|
||||
}
|
||||
|
@ -2400,6 +2400,10 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pP
|
|||
size_t numberOfVertices = indices.size() / numOffsets;
|
||||
numPrimitives = numberOfVertices - 2;
|
||||
}
|
||||
if (pPrimType == Prim_LineStrip) {
|
||||
size_t numberOfVertices = indices.size() / numOffsets;
|
||||
numPrimitives = numberOfVertices - 1;
|
||||
}
|
||||
|
||||
pMesh->mFaceSize.reserve( numPrimitives);
|
||||
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++)
|
||||
CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
|
||||
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:
|
||||
numPoints = 3;
|
||||
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
|
||||
|
|
|
@ -95,14 +95,10 @@ public:
|
|||
XmlSerializer(XmlReader* xmlReader)
|
||||
: xmlReader(xmlReader)
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
void ImportXml(aiScene* scene)
|
||||
{
|
||||
|
||||
scene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
||||
|
||||
void ImportXml(aiScene* scene) {
|
||||
scene->mRootNode = new aiNode();
|
||||
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/ai_assert.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
@ -228,7 +229,7 @@ ZipFile::~ZipFile() {
|
|||
|
||||
size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
||||
const size_t size = pSize * pCount;
|
||||
assert(size <= m_Size);
|
||||
ai_assert(size <= m_Size);
|
||||
|
||||
std::memcpy(pvBuffer, m_Buffer, size);
|
||||
|
||||
|
|
|
@ -253,8 +253,8 @@ void DefaultLogger::kill()
|
|||
// Debug message
|
||||
void DefaultLogger::OnDebug( const char* message )
|
||||
{
|
||||
if ( m_Severity == Logger::NORMAL )
|
||||
return;
|
||||
if ( m_Severity == Logger::NORMAL )
|
||||
return;
|
||||
|
||||
static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
|
||||
char msg[Size];
|
||||
|
|
|
@ -90,6 +90,7 @@ void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportPr
|
|||
void ExportScene3DS(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 ExportSceneGLTF2(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 ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||
|
@ -144,6 +145,8 @@ Exporter::ExportFormatEntry gExporters[] =
|
|||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType),
|
||||
#endif
|
||||
|
||||
#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 "FBXImporter.h"
|
||||
#include "FBXDocumentUtil.h"
|
||||
#include "FBXProperties.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
using namespace Util;
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||
const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name,
|
||||
const Document& doc, const char* const * target_prop_whitelist /*= NULL*/,
|
||||
size_t whitelist_size /*= 0*/)
|
||||
: Object(id, element, name)
|
||||
, target()
|
||||
, doc(doc)
|
||||
|
@ -155,18 +153,16 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, cons
|
|||
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::~AnimationCurveNode()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
||||
{
|
||||
if(curves.empty()) {
|
||||
if ( curves.empty() ) {
|
||||
// resolve attached animation curves
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
||||
|
||||
|
@ -196,7 +192,6 @@ const AnimationCurveMap& AnimationCurveNode::Curves() const
|
|||
return curves;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: 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);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::~AnimationLayer()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
||||
size_t whitelist_size /*= 0*/) const
|
||||
|
@ -299,14 +292,13 @@ AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::s
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationStack::~AnimationStack()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
} //!FBX
|
||||
} //!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 FBX {
|
||||
|
||||
enum Flag
|
||||
{
|
||||
e_unknown_0 = 1 << 0,
|
||||
e_unknown_1 = 1 << 1,
|
||||
e_unknown_2 = 1 << 2,
|
||||
e_unknown_3 = 1 << 3,
|
||||
e_unknown_4 = 1 << 4,
|
||||
e_unknown_5 = 1 << 5,
|
||||
e_unknown_6 = 1 << 6,
|
||||
e_unknown_7 = 1 << 7,
|
||||
e_unknown_8 = 1 << 8,
|
||||
e_unknown_9 = 1 << 9,
|
||||
e_unknown_10 = 1 << 10,
|
||||
e_unknown_11 = 1 << 11,
|
||||
e_unknown_12 = 1 << 12,
|
||||
e_unknown_13 = 1 << 13,
|
||||
e_unknown_14 = 1 << 14,
|
||||
e_unknown_15 = 1 << 15,
|
||||
e_unknown_16 = 1 << 16,
|
||||
e_unknown_17 = 1 << 17,
|
||||
e_unknown_18 = 1 << 18,
|
||||
e_unknown_19 = 1 << 19,
|
||||
e_unknown_20 = 1 << 20,
|
||||
e_unknown_21 = 1 << 21,
|
||||
e_unknown_22 = 1 << 22,
|
||||
e_unknown_23 = 1 << 23,
|
||||
e_flag_field_size_64_bit = 1 << 24, // Not sure what is
|
||||
e_unknown_25 = 1 << 25,
|
||||
e_unknown_26 = 1 << 26,
|
||||
e_unknown_27 = 1 << 27,
|
||||
e_unknown_28 = 1 << 28,
|
||||
e_unknown_29 = 1 << 29,
|
||||
e_unknown_30 = 1 << 30,
|
||||
e_unknown_31 = 1 << 31
|
||||
};
|
||||
|
||||
bool check_flag(uint32_t flags, Flag to_check)
|
||||
{
|
||||
return (flags & to_check) != 0;
|
||||
}
|
||||
|
||||
//enum Flag
|
||||
//{
|
||||
// e_unknown_0 = 1 << 0,
|
||||
// e_unknown_1 = 1 << 1,
|
||||
// e_unknown_2 = 1 << 2,
|
||||
// e_unknown_3 = 1 << 3,
|
||||
// e_unknown_4 = 1 << 4,
|
||||
// e_unknown_5 = 1 << 5,
|
||||
// e_unknown_6 = 1 << 6,
|
||||
// e_unknown_7 = 1 << 7,
|
||||
// e_unknown_8 = 1 << 8,
|
||||
// e_unknown_9 = 1 << 9,
|
||||
// e_unknown_10 = 1 << 10,
|
||||
// e_unknown_11 = 1 << 11,
|
||||
// e_unknown_12 = 1 << 12,
|
||||
// e_unknown_13 = 1 << 13,
|
||||
// e_unknown_14 = 1 << 14,
|
||||
// e_unknown_15 = 1 << 15,
|
||||
// e_unknown_16 = 1 << 16,
|
||||
// e_unknown_17 = 1 << 17,
|
||||
// e_unknown_18 = 1 << 18,
|
||||
// e_unknown_19 = 1 << 19,
|
||||
// e_unknown_20 = 1 << 20,
|
||||
// e_unknown_21 = 1 << 21,
|
||||
// e_unknown_22 = 1 << 22,
|
||||
// e_unknown_23 = 1 << 23,
|
||||
// e_flag_field_size_64_bit = 1 << 24, // Not sure what is
|
||||
// e_unknown_25 = 1 << 25,
|
||||
// e_unknown_26 = 1 << 26,
|
||||
// e_unknown_27 = 1 << 27,
|
||||
// e_unknown_28 = 1 << 28,
|
||||
// e_unknown_29 = 1 << 29,
|
||||
// e_unknown_30 = 1 << 30,
|
||||
// e_unknown_31 = 1 << 31
|
||||
//};
|
||||
//
|
||||
//bool check_flag(uint32_t flags, Flag to_check)
|
||||
//{
|
||||
// return (flags & to_check) != 0;
|
||||
//}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
|
||||
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
|
||||
uint32_t word;
|
||||
memcpy(&word, cursor, 4);
|
||||
AI_SWAP4(word);
|
||||
|
||||
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
|
||||
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 -
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
// 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.
|
||||
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 (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 ..
|
||||
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) ));
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
ai_assert(input);
|
||||
|
@ -438,19 +439,17 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
|||
TokenizeError("magic bytes not found",0);
|
||||
}
|
||||
|
||||
|
||||
//uint32_t offset = 0x15;
|
||||
const char* cursor = input + 0x15;
|
||||
|
||||
const uint32_t flags = ReadWord(input, cursor, input + length);
|
||||
|
||||
const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
|
||||
(void) padding_0;
|
||||
const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused
|
||||
(void) padding_1;
|
||||
const char* cursor = input + 18;
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||
const bool is64bits = version >= 7500;
|
||||
while (cursor < input + length)
|
||||
{
|
||||
if(!ReadScope(output_tokens, input, cursor, input + length, flags)) {
|
||||
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,4 +66,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# 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 <assimp/scene.h>
|
||||
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
|
@ -931,7 +931,7 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
|
|||
const TransformationComp comp = static_cast< TransformationComp >( i );
|
||||
|
||||
if ( comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation ||
|
||||
comp == TransformationComp_GeometricScaling || comp == TransformationComp_GeometricRotation || comp == TransformationComp_GeometricTranslation ) {
|
||||
comp == TransformationComp_GeometricScaling || comp == TransformationComp_GeometricRotation || comp == TransformationComp_GeometricTranslation ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -949,8 +949,7 @@ std::string Converter::NameTransformationChainNode( const std::string& name, Tra
|
|||
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
|
||||
}
|
||||
|
||||
void Converter::GenerateTransformationNodeChain( const Model& model,
|
||||
std::vector<aiNode*>& output_nodes )
|
||||
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes )
|
||||
{
|
||||
const PropertyTable& props = model.Props();
|
||||
const Model::RotOrder rot = model.RotationOrder();
|
||||
|
@ -1065,6 +1064,10 @@ void Converter::GenerateTransformationNodeChain( const Model& model,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( comp == TransformationComp_PostRotation ) {
|
||||
chain[ i ] = chain[ i ].Inverse();
|
||||
}
|
||||
|
||||
aiNode* nd = new aiNode();
|
||||
output_nodes.push_back( nd );
|
||||
|
||||
|
@ -1093,7 +1096,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
|
|||
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
|
||||
|
||||
// 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) );
|
||||
nd.mMetaData = data;
|
||||
int index = 0;
|
||||
|
@ -2368,8 +2371,13 @@ void Converter::ConvertAnimationStack( const AnimationStack& st )
|
|||
|
||||
int64_t start_time = st.LocalStart();
|
||||
int64_t stop_time = st.LocalStop();
|
||||
double start_timeF = CONVERT_FBX_TIME( start_time );
|
||||
double stop_timeF = CONVERT_FBX_TIME( stop_time );
|
||||
bool has_local_startstop = start_time != 0 || stop_time != 0;
|
||||
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 {
|
||||
for( const NodeMap::value_type& kv : node_map ) {
|
||||
|
@ -2401,27 +2409,23 @@ void Converter::ConvertAnimationStack( const AnimationStack& st )
|
|||
return;
|
||||
}
|
||||
|
||||
//adjust relative timing for animation
|
||||
{
|
||||
double start_fps = start_timeF * anim_fps;
|
||||
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;
|
||||
|
||||
for ( unsigned int c = 0; c < anim->mNumChannels; c++ )
|
||||
{
|
||||
aiNodeAnim* channel = anim->mChannels[ c ];
|
||||
for ( uint32_t i = 0; i < channel->mNumPositionKeys; i++ )
|
||||
channel->mPositionKeys[ i ].mTime -= start_fps;
|
||||
for ( uint32_t i = 0; i < channel->mNumRotationKeys; i++ )
|
||||
channel->mRotationKeys[ i ].mTime -= start_fps;
|
||||
for ( uint32_t i = 0; i < channel->mNumScalingKeys; i++ )
|
||||
channel->mScalingKeys[ i ].mTime -= start_fps;
|
||||
}
|
||||
|
||||
max_time -= min_time;
|
||||
// adjust relative timing for animation
|
||||
for ( unsigned int c = 0; c < anim->mNumChannels; c++ ) {
|
||||
aiNodeAnim* channel = anim->mChannels[ c ];
|
||||
for ( uint32_t i = 0; i < channel->mNumPositionKeys; i++ )
|
||||
channel->mPositionKeys[ i ].mTime -= start_time_fps;
|
||||
for ( uint32_t i = 0; i < channel->mNumRotationKeys; i++ )
|
||||
channel->mRotationKeys[ i ].mTime -= start_time_fps;
|
||||
for ( uint32_t i = 0; i < channel->mNumScalingKeys; i++ )
|
||||
channel->mScalingKeys[ i ].mTime -= start_time_fps;
|
||||
}
|
||||
|
||||
// for some mysterious reason, mDuration is simply the maximum key -- the
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -3119,7 +3123,6 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
|
||||
const aiVector3D& def_value,
|
||||
double& maxTime,
|
||||
|
@ -3140,7 +3143,6 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
|
|||
|
||||
valOut[ i ].mTime = temp[ i ].mTime;
|
||||
|
||||
|
||||
GetRotationMatrix( order, temp[ i ].mValue, 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,
|
||||
aiVectorKey* out_translation,
|
||||
const KeyFrameListList& scaling,
|
||||
|
@ -3218,7 +3219,6 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
|
||||
{
|
||||
aiMatrix4x4 m;
|
||||
|
@ -3227,7 +3227,6 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
|
|||
return aiQuaternion( aiMatrix3x3( m ) );
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||
const LayerMap& /*layers*/,
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
|
||||
const LayerMap& /*layers*/,
|
||||
int64_t start, int64_t stop,
|
||||
|
@ -3289,7 +3286,8 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
|
|||
|
||||
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
|
||||
// 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)
|
||||
, flags()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject::~LazyObject()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -232,16 +232,15 @@ Object::Object(uint64_t id, const Element& element, const std::string& name)
|
|||
, name(name)
|
||||
, id(id)
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object::~Object()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
|
||||
: props(props)
|
||||
|
@ -292,11 +291,10 @@ Document::~Document()
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static const int LowerSupportedVersion = 7100;
|
||||
static const int UpperSupportedVersion = 7400;
|
||||
static const unsigned int LowerSupportedVersion = 7100;
|
||||
static const unsigned int UpperSupportedVersion = 7400;
|
||||
|
||||
void Document::ReadHeader()
|
||||
{
|
||||
void Document::ReadHeader() {
|
||||
// Read ID objects from "Objects" section
|
||||
const Scope& sc = parser.GetRootScope();
|
||||
const Element* const ehead = sc["FBXHeaderExtension"];
|
||||
|
@ -362,7 +360,6 @@ void Document::ReadGlobalSettings()
|
|||
globals.reset(new FileGlobalSettings(*this, props));
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Document::ReadObjects()
|
||||
{
|
||||
|
@ -388,7 +385,6 @@ void Document::ReadObjects()
|
|||
}
|
||||
|
||||
const char* err;
|
||||
|
||||
const uint64_t id = ParseTokenAsID(*tok[0], err);
|
||||
if(err) {
|
||||
DOMError(err,el.second);
|
||||
|
@ -470,8 +466,6 @@ void Document::ReadPropertyTemplates()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Document::ReadConnections()
|
||||
{
|
||||
|
@ -483,7 +477,6 @@ void Document::ReadConnections()
|
|||
}
|
||||
|
||||
uint64_t insertionOrder = 0l;
|
||||
|
||||
const Scope& sconns = *econns->Compound();
|
||||
const ElementCollection conns = sconns.GetCollection("C");
|
||||
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
|
||||
// (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 dest = ParseTokenAsID(GetRequiredToken(el,2));
|
||||
|
@ -519,11 +514,10 @@ void Document::ReadConnections()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
||||
{
|
||||
if (!animationStacksResolved.empty() || !animationStacks.size()) {
|
||||
if (!animationStacksResolved.empty() || animationStacks.empty()) {
|
||||
return animationStacksResolved;
|
||||
}
|
||||
|
||||
|
@ -541,7 +535,6 @@ const std::vector<const AnimationStack*>& Document::AnimationStacks() const
|
|||
return animationStacksResolved;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject* Document::GetObject(uint64_t id) const
|
||||
{
|
||||
|
@ -552,8 +545,7 @@ LazyObject* Document::GetObject(uint64_t id) const
|
|||
#define MAX_CLASSNAMES 6
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id,
|
||||
const ConnectionMap& conns) const
|
||||
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, const ConnectionMap& conns) const
|
||||
{
|
||||
std::vector<const Connection*> temp;
|
||||
|
||||
|
@ -570,7 +562,6 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id,
|
|||
return temp; // NRVO should handle this
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src,
|
||||
const ConnectionMap& conns,
|
||||
|
@ -579,17 +570,17 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
|||
|
||||
{
|
||||
ai_assert(classnames);
|
||||
ai_assert(count != 0 && count <= MAX_CLASSNAMES);
|
||||
ai_assert( count != 0 );
|
||||
ai_assert( count <= MAX_CLASSNAMES);
|
||||
|
||||
size_t lenghts[MAX_CLASSNAMES];
|
||||
|
||||
const size_t c = count;
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
lenghts[i] = strlen(classnames[i]);
|
||||
lenghts[ i ] = strlen(classnames[i]);
|
||||
}
|
||||
|
||||
std::vector<const Connection*> temp;
|
||||
|
||||
const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range =
|
||||
conns.equal_range(id);
|
||||
|
||||
|
@ -621,49 +612,40 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
|||
return temp; // NRVO should handle this
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source) const
|
||||
{
|
||||
return GetConnectionsSequenced(source, ConnectionsBySource());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest,
|
||||
const char* classname) const
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t dest, const char* classname) const
|
||||
{
|
||||
const char* arr[] = {classname};
|
||||
return GetConnectionsBySourceSequenced(dest, arr,1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
|
||||
const char* const* classnames, size_t count) const
|
||||
std::vector<const Connection*> Document::GetConnectionsBySourceSequenced(uint64_t source,
|
||||
const char* const* classnames, size_t count) const
|
||||
{
|
||||
return GetConnectionsSequenced(source, true, ConnectionsBySource(),classnames, count);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
||||
const char* classname) const
|
||||
const char* classname) const
|
||||
{
|
||||
const char* arr[] = {classname};
|
||||
return GetConnectionsByDestinationSequenced(dest, arr,1);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest) const
|
||||
{
|
||||
return GetConnectionsSequenced(dest, ConnectionsByDestination());
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(uint64_t dest,
|
||||
const char* const* classnames, size_t count) const
|
||||
|
@ -672,10 +654,9 @@ std::vector<const Connection*> Document::GetConnectionsByDestinationSequenced(ui
|
|||
return GetConnectionsSequenced(dest, false, ConnectionsByDestination(),classnames, count);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Connection::Connection(uint64_t insertionOrder, uint64_t src, uint64_t dest, const std::string& prop,
|
||||
const Document& doc)
|
||||
const Document& doc)
|
||||
|
||||
: insertionOrder(insertionOrder)
|
||||
, prop(prop)
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Connection::~Connection()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject& Connection::LazySourceObject() const
|
||||
{
|
||||
|
@ -704,7 +683,6 @@ LazyObject& Connection::LazySourceObject() const
|
|||
return *lazy;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject& Connection::LazyDestinationObject() const
|
||||
{
|
||||
|
@ -713,7 +691,6 @@ LazyObject& Connection::LazyDestinationObject() const
|
|||
return *lazy;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Object* Connection::SourceObject() const
|
||||
{
|
||||
|
@ -722,7 +699,6 @@ const Object* Connection::SourceObject() const
|
|||
return lazy->Get();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Object* Connection::DestinationObject() const
|
||||
{
|
||||
|
@ -735,4 +711,3 @@ const Object* Connection::DestinationObject() const
|
|||
} // !Assimp
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -338,12 +338,7 @@ public:
|
|||
class Model : public Object
|
||||
{
|
||||
public:
|
||||
Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Model();
|
||||
|
||||
public:
|
||||
enum RotOrder
|
||||
{
|
||||
enum RotOrder {
|
||||
RotOrder_EulerXYZ = 0,
|
||||
RotOrder_EulerXZY,
|
||||
RotOrder_EulerYZX,
|
||||
|
@ -357,8 +352,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
enum TransformInheritance
|
||||
{
|
||||
enum TransformInheritance {
|
||||
TransformInheritance_RrSs = 0,
|
||||
TransformInheritance_RSrs,
|
||||
TransformInheritance_Rrs,
|
||||
|
@ -366,7 +360,10 @@ public:
|
|||
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(RotationOffset, aiVector3D, aiVector3D())
|
||||
|
@ -443,7 +440,6 @@ public:
|
|||
fbx_simple_property(LODBox, bool, false)
|
||||
fbx_simple_property(Freeze, bool, false)
|
||||
|
||||
public:
|
||||
const std::string& Shading() const {
|
||||
return shading;
|
||||
}
|
||||
|
@ -462,13 +458,11 @@ public:
|
|||
return materials;
|
||||
}
|
||||
|
||||
|
||||
/** Get geometry links */
|
||||
const std::vector<const Geometry*>& GetGeometry() const {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
||||
/** Get node attachments */
|
||||
const std::vector<const NodeAttribute*>& GetAttributes() const {
|
||||
return attributes;
|
||||
|
@ -477,7 +471,6 @@ public:
|
|||
/** convenience method to check if the node has a Null node marker */
|
||||
bool IsNull() const;
|
||||
|
||||
|
||||
private:
|
||||
void ResolveLinks(const Element& element, const Document& doc);
|
||||
|
||||
|
@ -603,10 +596,10 @@ public:
|
|||
return textures[index];
|
||||
|
||||
}
|
||||
const int textureCount() const {
|
||||
int textureCount() const {
|
||||
return static_cast<int>(textures.size());
|
||||
}
|
||||
const BlendMode GetBlendMode() const
|
||||
BlendMode GetBlendMode() const
|
||||
{
|
||||
return blendMode;
|
||||
}
|
||||
|
@ -654,7 +647,7 @@ public:
|
|||
return content;
|
||||
}
|
||||
|
||||
const uint32_t ContentLength() const {
|
||||
uint32_t ContentLength() const {
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
|
@ -805,7 +798,6 @@ private:
|
|||
|
||||
typedef std::vector<const AnimationCurveNode*> AnimationCurveNodeList;
|
||||
|
||||
|
||||
/** Represents a FBX animation layer (i.e. a list of node animations) */
|
||||
class AnimationLayer : public Object
|
||||
{
|
||||
|
@ -828,10 +820,8 @@ private:
|
|||
const Document& doc;
|
||||
};
|
||||
|
||||
|
||||
typedef std::vector<const AnimationLayer*> AnimationLayerList;
|
||||
|
||||
|
||||
/** Represents a FBX animation stack (i.e. a list of animation layers) */
|
||||
class AnimationStack : public Object
|
||||
{
|
||||
|
@ -839,7 +829,6 @@ public:
|
|||
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationStack();
|
||||
|
||||
public:
|
||||
fbx_simple_property(LocalStart, int64_t, 0L)
|
||||
fbx_simple_property(LocalStop, int64_t, 0L)
|
||||
fbx_simple_property(ReferenceStart, int64_t, 0L)
|
||||
|
@ -879,7 +868,6 @@ private:
|
|||
typedef std::vector<float> WeightArray;
|
||||
typedef std::vector<unsigned int> WeightIndexArray;
|
||||
|
||||
|
||||
/** DOM class for skin deformer clusters (aka subdeformers) */
|
||||
class Cluster : public Deformer
|
||||
{
|
||||
|
@ -924,8 +912,6 @@ private:
|
|||
const Model* node;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** DOM class for skin deformers */
|
||||
class Skin : public Deformer
|
||||
{
|
||||
|
@ -1009,10 +995,8 @@ public:
|
|||
typedef std::map<uint64_t, LazyObject*> ObjectMap;
|
||||
typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
|
||||
|
||||
|
||||
typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
|
||||
|
||||
|
||||
/** DOM class for global document settings, a single instance per document can
|
||||
* be accessed via Document.Globals(). */
|
||||
class FileGlobalSettings
|
||||
|
@ -1074,9 +1058,6 @@ private:
|
|||
const Document& doc;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/** DOM root for a FBX file */
|
||||
class Document
|
||||
{
|
||||
|
@ -1154,8 +1135,6 @@ private:
|
|||
const ConnectionMap&,
|
||||
const char* const* classnames,
|
||||
size_t count) const;
|
||||
|
||||
private:
|
||||
void ReadHeader();
|
||||
void ReadObjects();
|
||||
void ReadPropertyTemplates();
|
||||
|
|
|
@ -59,7 +59,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/importerdesc.h>
|
||||
|
||||
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;
|
||||
|
|
|
@ -243,7 +243,6 @@ const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, un
|
|||
ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );
|
||||
count = m_mapping_counts[ in_index ];
|
||||
|
||||
// ai_assert( count != 0 );
|
||||
ai_assert( m_mapping_offsets[ in_index ] + count <= m_mappings.size() );
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Model::~Model()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
using namespace Util;
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,33 +101,30 @@ CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Docume
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CameraSwitcher::~CameraSwitcher()
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Camera::~Camera()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& 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));
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Parser::~Parser()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::AdvanceToNextToken()
|
||||
{
|
||||
last = current;
|
||||
if (cursor == tokens.end()) {
|
||||
current = NULL;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
current = *cursor++;
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::CurrentToken() const
|
||||
{
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::LastToken() const
|
||||
{
|
||||
return last;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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());
|
||||
ai_assert(length > 0);
|
||||
|
||||
const char* out;
|
||||
const char* out = nullptr;
|
||||
const uint64_t id = strtoul10_64(t.begin(),&out,&length);
|
||||
if (out > t.end()) {
|
||||
err_out = "failed to parse ID (text)";
|
||||
|
@ -296,7 +291,6 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
|
|||
return id;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
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;
|
||||
}
|
||||
|
||||
const char* out;
|
||||
const char* out = nullptr;
|
||||
const size_t id = static_cast<size_t>(strtoul10_64(t.begin() + 1,&out,&length));
|
||||
if (out > t.end()) {
|
||||
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());
|
||||
ai_assert(length > 0);
|
||||
|
||||
const char* out;
|
||||
const char* out = nullptr;
|
||||
const int64_t id = strtol10_64(t.begin(), &out, &length);
|
||||
if (out > t.end()) {
|
||||
err_out = "failed to parse Int64 (text)";
|
||||
|
|
|
@ -85,12 +85,9 @@ typedef std::pair<ElementMap::const_iterator,ElementMap::const_iterator> Element
|
|||
class Element
|
||||
{
|
||||
public:
|
||||
|
||||
Element(const Token& key_token, Parser& parser);
|
||||
~Element();
|
||||
|
||||
public:
|
||||
|
||||
const Scope* Compound() const {
|
||||
return compound.get();
|
||||
}
|
||||
|
@ -104,14 +101,11 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
const Token& key_token;
|
||||
TokenList tokens;
|
||||
std::unique_ptr<Scope> compound;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/** FBX data entity that consists of a 'scope', a collection
|
||||
* of not necessarily unique #Element instances.
|
||||
*
|
||||
|
@ -125,14 +119,10 @@ private:
|
|||
* @endverbatim */
|
||||
class Scope
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Scope(Parser& parser, bool topLevel = false);
|
||||
~Scope();
|
||||
|
||||
public:
|
||||
|
||||
const Element* operator[] (const std::string& index) const {
|
||||
ElementMap::const_iterator it = elements.find(index);
|
||||
return it == elements.end() ? NULL : (*it).second;
|
||||
|
@ -158,28 +148,23 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
ElementMap elements;
|
||||
};
|
||||
|
||||
|
||||
/** FBX parsing class, takes a list of input tokens and generates a hierarchy
|
||||
* of nested #Scope instances, representing the fbx DOM.*/
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
|
||||
/** Parse given a token list. Does not take ownership of the tokens -
|
||||
* the objects must persist during the entire parser lifetime */
|
||||
Parser (const TokenList& tokens,bool is_binary);
|
||||
~Parser();
|
||||
|
||||
public:
|
||||
const Scope& GetRootScope() const {
|
||||
return *root.get();
|
||||
}
|
||||
|
||||
|
||||
bool IsBinary() const {
|
||||
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<int64_t>& out, const Element& el);
|
||||
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
|
@ -243,8 +226,6 @@ const Scope& GetRequiredScope(const Element& el);
|
|||
// get token at a particular index
|
||||
const Token& GetRequiredToken(const Element& el, unsigned int index);
|
||||
|
||||
|
||||
|
||||
// read a 4x4 matrix from an array of 16 floats
|
||||
aiMatrix4x4 ReadMatrix(const Element& element);
|
||||
|
||||
|
|
|
@ -55,17 +55,14 @@ namespace FBX {
|
|||
// Forward declarations
|
||||
class Element;
|
||||
|
||||
|
||||
/** Represents a dynamic property. Type info added by deriving classes,
|
||||
* see #TypedProperty.
|
||||
Example:
|
||||
@verbatim
|
||||
P: "ShininessExponent", "double", "Number", "",0.5
|
||||
@endvebatim
|
||||
|
||||
*/
|
||||
class Property
|
||||
{
|
||||
class Property {
|
||||
protected:
|
||||
Property();
|
||||
|
||||
|
@ -79,17 +76,14 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
class TypedProperty : public Property
|
||||
{
|
||||
class TypedProperty : public Property {
|
||||
public:
|
||||
explicit TypedProperty(const T& value)
|
||||
: value(value)
|
||||
{
|
||||
: value(value) {
|
||||
// empty
|
||||
}
|
||||
|
||||
public:
|
||||
const T& Value() const {
|
||||
return value;
|
||||
}
|
||||
|
@ -100,21 +94,19 @@ private:
|
|||
|
||||
|
||||
typedef std::fbx_unordered_map<std::string,std::shared_ptr<Property> > DirectPropertyMap;
|
||||
typedef std::fbx_unordered_map<std::string,const Property*> PropertyMap;
|
||||
typedef std::fbx_unordered_map<std::string,const Element*> LazyPropertyMap;
|
||||
typedef std::fbx_unordered_map<std::string,const Property*> PropertyMap;
|
||||
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)
|
||||
*/
|
||||
class PropertyTable
|
||||
{
|
||||
class PropertyTable {
|
||||
public:
|
||||
// in-memory property table with no source element
|
||||
PropertyTable();
|
||||
PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps);
|
||||
~PropertyTable();
|
||||
|
||||
public:
|
||||
const Property* Get(const std::string& name) const;
|
||||
|
||||
// PropertyTable's need not be coupled with FBX elements so this can be NULL
|
||||
|
@ -135,41 +127,37 @@ private:
|
|||
const Element* const element;
|
||||
};
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
||||
const T& defaultValue)
|
||||
{
|
||||
inline
|
||||
T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
|
||||
const Property* const prop = in.Get(name);
|
||||
if(!prop) {
|
||||
if( nullptr == prop) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
// strong typing, no need to be lenient
|
||||
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
|
||||
if(!tprop) {
|
||||
if( nullptr == tprop) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return tprop->Value();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
||||
bool& result)
|
||||
{
|
||||
inline
|
||||
T PropertyGet(const PropertyTable& in, const std::string& name, bool& result) {
|
||||
const Property* const prop = in.Get(name);
|
||||
if(!prop) {
|
||||
if( nullptr == prop) {
|
||||
result = false;
|
||||
return T();
|
||||
}
|
||||
|
||||
// strong typing, no need to be lenient
|
||||
const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
|
||||
if(!tprop) {
|
||||
if( nullptr == tprop) {
|
||||
result = false;
|
||||
return T();
|
||||
}
|
||||
|
@ -178,7 +166,6 @@ inline T PropertyGet(const PropertyTable& in, const std::string& name,
|
|||
return tprop->Value();
|
||||
}
|
||||
|
||||
|
||||
} //! FBX
|
||||
} //! Assimp
|
||||
|
||||
|
|
|
@ -101,7 +101,6 @@ public:
|
|||
return std::string(begin(),end());
|
||||
}
|
||||
|
||||
public:
|
||||
bool IsBinary() const {
|
||||
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
|
||||
|
||||
// Workaround for issue #1361
|
||||
// https://github.com/assimp/assimp/issues/1361
|
||||
#ifdef __ANDROID__
|
||||
#define _GLIBCXX_USE_C99 1
|
||||
#endif
|
||||
|
||||
#include "FIReader.hpp"
|
||||
#include "Exceptional.h"
|
||||
#include <assimp/IOStream.hpp>
|
||||
|
@ -162,7 +168,7 @@ struct FIBase64ValueImpl: public FIBase64Value {
|
|||
if (!strValueValid) {
|
||||
strValueValid = true;
|
||||
std::ostringstream os;
|
||||
uint8_t c1, c2;
|
||||
uint8_t c1 = 0, c2;
|
||||
int imod3 = 0;
|
||||
std::vector<uint8_t>::size_type valueSize = value.size();
|
||||
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>
|
||||
inline const bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
inline bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* 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,
|
||||
const unsigned char** szCursorOut)
|
||||
{
|
||||
ai_assert(0 != iNumSkins && NULL != szCursor);
|
||||
ai_assert( 0 != iNumSkins );
|
||||
ai_assert( nullptr != szCursor);
|
||||
|
||||
// read the type of the skin ...
|
||||
// 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& b1 = boundary[(i + 1) % bcount];
|
||||
IfcVector3 b = b1 - b0;
|
||||
IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
|
||||
|
||||
// segment-segment intersection
|
||||
// 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)
|
||||
continue;
|
||||
}
|
||||
IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
|
||||
|
||||
const IfcFloat x = b0.x - e0.x;
|
||||
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);
|
||||
votes += intersected_boundary.size() % 2;
|
||||
|
||||
// ai_assert(votes == 3 || votes == 0);
|
||||
return votes > 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -548,8 +548,6 @@ bool Curve :: InRange(IfcFloat u) const
|
|||
const ParamRange range = GetParametricRange();
|
||||
if (IsClosed()) {
|
||||
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;
|
||||
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 {
|
||||
template<> const std::string LogFunctions<IFCImporter>::log_prefix = "IFC: ";
|
||||
template<> const char* LogFunctions<IFCImporter>::Prefix()
|
||||
{
|
||||
static auto prefix = "IFC: ";
|
||||
return prefix;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace Assimp;
|
||||
|
|
|
@ -1492,7 +1492,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
vmax -= vmin;
|
||||
|
||||
// If this happens then the projection must have been wrong.
|
||||
assert(vmax.Length());
|
||||
ai_assert(vmax.Length());
|
||||
|
||||
ClipperLib::ExPolygons clipped;
|
||||
ClipperLib::Polygons holes_union;
|
||||
|
@ -1616,7 +1616,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
std::vector<IfcVector3> tmpvec;
|
||||
for(ClipperLib::Polygon& opening : holes_union) {
|
||||
|
||||
assert(ClipperLib::Orientation(opening));
|
||||
ai_assert(ClipperLib::Orientation(opening));
|
||||
|
||||
tmpvec.clear();
|
||||
|
||||
|
@ -1705,7 +1705,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
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) ;
|
||||
|
||||
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.vertcnt.push_back(segments);
|
||||
meshout.vertcnt.push_back(static_cast<unsigned int>(segments));
|
||||
}
|
||||
else if( const IfcIShapeProfileDef* const ishape = def.ToPtr<IfcIShapeProfileDef>()) {
|
||||
// construct simplified IBeam shape
|
||||
|
|
|
@ -284,11 +284,17 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
|
|||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
inline
|
||||
bool isEndOfCache( size_t pos, size_t cacheSize ) {
|
||||
return ( pos == cacheSize );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
|
||||
buffer.resize(m_cacheSize);
|
||||
if (m_cachePos == m_cacheSize || 0 == m_filePos) {
|
||||
if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
|
||||
if (!readNextBlock()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -300,11 +306,16 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
|
|||
++m_cachePos;
|
||||
}
|
||||
++m_cachePos;
|
||||
if ( isEndOfCache( m_cachePos, m_cacheSize ) ) {
|
||||
if ( !readNextBlock() ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (!IsLineEnd(m_cache[m_cachePos])) {
|
||||
buffer[i] = m_cache[m_cachePos];
|
||||
while (!IsLineEnd(m_cache[ m_cachePos ])) {
|
||||
buffer[i] = m_cache[ m_cachePos ];
|
||||
m_cachePos++;
|
||||
i++;
|
||||
if (m_cachePos >= m_cacheSize) {
|
||||
|
|
|
@ -831,8 +831,8 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
|
|||
pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()), static_cast<int>(pimpl->mPostProcessingSteps.size()) );
|
||||
|
||||
// update private scene flags
|
||||
if( pimpl->mScene )
|
||||
ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags;
|
||||
if( pimpl->mScene )
|
||||
ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags;
|
||||
|
||||
// clear any data allocated by post-process steps
|
||||
pimpl->mPPShared->Clean();
|
||||
|
|
|
@ -182,6 +182,7 @@ corresponding preprocessor flag to selectively disable formats.
|
|||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||
# include "glTFImporter.h"
|
||||
# include "glTF2Importer.h"
|
||||
#endif
|
||||
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||
# include "C4DImporter.h"
|
||||
|
@ -336,6 +337,7 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
|
|||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER )
|
||||
out.push_back( new glTFImporter() );
|
||||
out.push_back( new glTF2Importer() );
|
||||
#endif
|
||||
#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||
out.push_back( new C4DImporter() );
|
||||
|
|
|
@ -60,34 +60,34 @@ public:
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
static void ThrowException(const std::string& msg)
|
||||
{
|
||||
throw DeadlyImportError(log_prefix+msg);
|
||||
throw DeadlyImportError(Prefix()+msg);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void LogWarn(const Formatter::format& message) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
if (!DefaultLogger::isNullLogger()) {
|
||||
DefaultLogger::get()->debug(log_prefix+(std::string)message);
|
||||
DefaultLogger::get()->debug(Prefix()+(std::string)message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,8 +125,7 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
|
||||
static const std::string log_prefix;
|
||||
static const char* Prefix();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -126,16 +126,16 @@ struct Header {
|
|||
int32_t version;
|
||||
|
||||
//! scale factors for each axis
|
||||
aiVector3D scale;
|
||||
ai_real scale[3];
|
||||
|
||||
//! translation factors for each axis
|
||||
aiVector3D translate;
|
||||
ai_real translate[3];
|
||||
|
||||
//! bounding radius of the mesh
|
||||
float boundingradius;
|
||||
|
||||
//! Position of the viewer's exe. Ignored
|
||||
aiVector3D vEyePos;
|
||||
ai_real vEyePos[3];
|
||||
|
||||
//! Number of textures
|
||||
int32_t num_skins;
|
||||
|
@ -164,7 +164,7 @@ struct Header {
|
|||
|
||||
//! Could be the total size of the file (and not a float)
|
||||
float size;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -223,7 +223,7 @@ struct Header_MDL7 {
|
|||
|
||||
//! Size of the Frame_MDL7 data structure used in the file
|
||||
uint16_t frame_stc_size;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -242,7 +242,7 @@ struct Bone_MDL7 {
|
|||
|
||||
//! Optional name of the bone
|
||||
char name[1 /* DUMMY SIZE */];
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
|
||||
# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
|
||||
|
@ -290,7 +290,7 @@ struct Group_MDL7 {
|
|||
|
||||
//! Number of frames
|
||||
int32_t numframes;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
|
||||
#define AI_MDL7_SKINTYPE_MATERIAL 0x10
|
||||
|
@ -312,7 +312,7 @@ struct Deformer_MDL7 {
|
|||
int32_t group_index;
|
||||
int32_t elements;
|
||||
int32_t deformerdata_size;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -324,7 +324,7 @@ struct DeformerElement_MDL7 {
|
|||
int32_t element_index;
|
||||
char element_name[AI_MDL7_MAX_BONENAMESIZE];
|
||||
int32_t weights;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct DeformerWeight_MDL7
|
||||
|
@ -334,7 +334,7 @@ struct DeformerWeight_MDL7 {
|
|||
//! for deformer_typ==0 (==bones) index == vertex index
|
||||
int32_t index;
|
||||
float weight;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// don't know why this was in the original headers ...
|
||||
typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
||||
|
@ -345,7 +345,7 @@ typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
|
|||
*/
|
||||
struct ColorValue_MDL7 {
|
||||
float r,g,b,a;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Material_MDL7
|
||||
|
@ -366,7 +366,7 @@ struct Material_MDL7 {
|
|||
|
||||
//! Phong power
|
||||
float Power;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Skin
|
||||
|
@ -388,7 +388,7 @@ struct Skin {
|
|||
|
||||
//! Texture data
|
||||
uint8_t *data;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -399,7 +399,7 @@ struct Skin {
|
|||
struct Skin_MDL5 {
|
||||
int32_t size, width, height;
|
||||
uint8_t *data;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// maximum length of texture file name
|
||||
#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
|
||||
|
@ -416,7 +416,7 @@ struct Skin_MDL7 {
|
|||
int32_t width;
|
||||
int32_t height;
|
||||
char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct RGB565
|
||||
|
@ -426,7 +426,7 @@ struct RGB565 {
|
|||
uint16_t r : 5;
|
||||
uint16_t g : 6;
|
||||
uint16_t b : 5;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct ARGB4
|
||||
|
@ -455,7 +455,7 @@ struct GroupSkin {
|
|||
|
||||
//! Data of each image
|
||||
uint8_t **data;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct TexCoord
|
||||
|
@ -470,7 +470,7 @@ struct TexCoord {
|
|||
|
||||
//! Texture coordinate in the ty direction
|
||||
int32_t t;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct TexCoord_MDL3
|
||||
|
@ -482,7 +482,7 @@ struct TexCoord_MDL3 {
|
|||
|
||||
//! position, vertically in range 0..skinheight-1
|
||||
int16_t v;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct TexCoord_MDL7
|
||||
|
@ -494,7 +494,7 @@ struct TexCoord_MDL7 {
|
|||
|
||||
//! position, vertically in range 0..1
|
||||
float v;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct SkinSet_MDL7
|
||||
|
@ -510,7 +510,7 @@ struct SkinSet_MDL7
|
|||
|
||||
//! Material index
|
||||
int32_t material; // size 4
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Triangle
|
||||
|
@ -523,7 +523,7 @@ struct Triangle
|
|||
|
||||
//! Vertex indices
|
||||
int32_t vertex[3];
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Triangle_MDL3
|
||||
|
@ -536,7 +536,7 @@ struct Triangle_MDL3
|
|||
|
||||
//! Index of 3 skin vertices in range 0..numskinverts
|
||||
uint16_t index_uv[3];
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Triangle_MDL7
|
||||
|
@ -549,7 +549,7 @@ struct Triangle_MDL7
|
|||
|
||||
//! Two skinsets. The second will be used for multi-texturing
|
||||
SkinSet_MDL7 skinsets[2];
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
|
||||
# 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 normalIndex;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -603,7 +603,7 @@ struct Vertex_MDL7
|
|||
uint8_t norm162index;
|
||||
float norm[3];
|
||||
};
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct BoneTransform_MDL7
|
||||
|
@ -620,7 +620,7 @@ struct BoneTransform_MDL7
|
|||
//! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
|
||||
//! THIS STUPID FILE FORMAT!
|
||||
int8_t _unused_[2];
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
#define AI_MDL7_MAX_FRAMENAMESIZE 16
|
||||
|
@ -654,7 +654,7 @@ struct SimpleFrame
|
|||
|
||||
//! Vertex list of the frame
|
||||
Vertex *verts;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct Frame
|
||||
|
@ -667,7 +667,7 @@ struct Frame
|
|||
|
||||
//! Frame data
|
||||
SimpleFrame frame;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
@ -684,7 +684,7 @@ struct SimpleFrame_MDLn_SP
|
|||
|
||||
//! Vertex list of the frame
|
||||
Vertex_MDL4 *verts;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
/** \struct GroupFrame
|
||||
|
@ -706,7 +706,7 @@ struct GroupFrame
|
|||
|
||||
//! List of single frames
|
||||
SimpleFrame *frames;
|
||||
} /* PACK_STRUCT */;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#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** 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;
|
||||
|
||||
// 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
|
||||
fileStream.seekg(0, fileStream.end);
|
||||
size_t fileSize = fileStream.tellg();
|
||||
size_t fileSize = static_cast<size_t>(fileStream.tellg());
|
||||
fileStream.seekg(0, fileStream.beg);
|
||||
|
||||
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(
|
||||
aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
|
||||
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;
|
||||
case pmx::PmxVertexSkinningType::BDEF4:
|
||||
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(
|
||||
aiVertexWeight(index, vsSDEF_ptr->bone_weight));
|
||||
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;
|
||||
case pmx::PmxVertexSkinningType::QDEF:
|
||||
const auto vsQDEF_ptr =
|
||||
|
@ -325,7 +325,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
|||
aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
|
||||
auto it = bone_vertex_map.find(ii);
|
||||
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();
|
||||
it->second.swap(*(new vector<aiVertexWeight>));
|
||||
}
|
||||
|
|
|
@ -49,17 +49,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace pmd
|
||||
{
|
||||
/// ヘッダ
|
||||
class PmdHeader
|
||||
{
|
||||
public:
|
||||
/// モデル名
|
||||
std::string name;
|
||||
/// モデル名(英語)
|
||||
std::string name_english;
|
||||
/// コメント
|
||||
std::string comment;
|
||||
/// コメント(英語)
|
||||
std::string comment_english;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
|
@ -83,26 +78,19 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 頂点
|
||||
class PmdVertex
|
||||
{
|
||||
public:
|
||||
/// 位置
|
||||
float position[3];
|
||||
|
||||
/// 法線
|
||||
float normal[3];
|
||||
|
||||
/// UV座標
|
||||
float uv[2];
|
||||
|
||||
/// 関連ボーンインデックス
|
||||
uint16_t bone_index[2];
|
||||
|
||||
/// ボーンウェイト
|
||||
uint8_t bone_weight;
|
||||
|
||||
/// エッジ不可視
|
||||
bool edge_invisible;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
|
@ -117,27 +105,17 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 材質
|
||||
class PmdMaterial
|
||||
{
|
||||
public:
|
||||
/// 減衰色
|
||||
float diffuse[4];
|
||||
/// 光沢度
|
||||
float power;
|
||||
/// 光沢色
|
||||
float specular[3];
|
||||
/// 環境色
|
||||
float ambient[3];
|
||||
/// トーンインデックス
|
||||
uint8_t toon_index;
|
||||
/// エッジ
|
||||
uint8_t edge_flag;
|
||||
/// インデックス数
|
||||
uint32_t index_count;
|
||||
/// テクスチャファイル名
|
||||
std::string texture_filename;
|
||||
/// スフィアファイル名
|
||||
std::string sphere_filename;
|
||||
|
||||
bool Read(std::ifstream* stream)
|
||||
|
@ -158,7 +136,7 @@ namespace pmd
|
|||
sphere_filename.clear();
|
||||
}
|
||||
else {
|
||||
*pstar = (char)NULL;
|
||||
*pstar = 0;
|
||||
texture_filename = std::string(buffer);
|
||||
sphere_filename = std::string(pstar+1);
|
||||
}
|
||||
|
@ -180,23 +158,15 @@ namespace pmd
|
|||
RotationMovement
|
||||
};
|
||||
|
||||
/// ボーン
|
||||
class PmdBone
|
||||
{
|
||||
public:
|
||||
/// ボーン名
|
||||
std::string name;
|
||||
/// ボーン名(英語)
|
||||
std::string name_english;
|
||||
/// 親ボーン番号
|
||||
uint16_t parent_bone_index;
|
||||
/// 末端ボーン番号
|
||||
uint16_t tail_pos_bone_index;
|
||||
/// ボーン種類
|
||||
BoneType bone_type;
|
||||
/// IKボーン番号
|
||||
uint16_t ik_parent_bone_index;
|
||||
/// ボーンのヘッドの位置
|
||||
float bone_head_pos[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -219,19 +189,13 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// IK
|
||||
class PmdIk
|
||||
{
|
||||
public:
|
||||
/// IKボーン番号
|
||||
uint16_t ik_bone_index;
|
||||
/// IKターゲットボーン番号
|
||||
uint16_t target_bone_index;
|
||||
/// 再帰回数
|
||||
uint16_t interations;
|
||||
/// 角度制限
|
||||
float angle_limit;
|
||||
/// 影響下ボーン番号
|
||||
std::vector<uint16_t> ik_child_bone_index;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -303,7 +267,6 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// ボーン枠用の枠名
|
||||
class PmdBoneDispName
|
||||
{
|
||||
public:
|
||||
|
@ -338,59 +301,36 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 衝突形状
|
||||
enum class RigidBodyShape : uint8_t
|
||||
{
|
||||
/// 球
|
||||
Sphere = 0,
|
||||
/// 直方体
|
||||
Box = 1,
|
||||
/// カプセル
|
||||
Cpusel = 2
|
||||
};
|
||||
|
||||
/// 剛体タイプ
|
||||
enum class RigidBodyType : uint8_t
|
||||
{
|
||||
/// ボーン追従
|
||||
BoneConnected = 0,
|
||||
/// 物理演算
|
||||
Physics = 1,
|
||||
/// 物理演算(Bone位置合せ)
|
||||
ConnectedPhysics = 2
|
||||
};
|
||||
|
||||
/// 剛体
|
||||
class PmdRigidBody
|
||||
{
|
||||
public:
|
||||
/// 名前
|
||||
std::string name;
|
||||
/// 関連ボーン番号
|
||||
uint16_t related_bone_index;
|
||||
/// グループ番号
|
||||
uint8_t group_index;
|
||||
/// マスク
|
||||
uint16_t mask;
|
||||
/// 形状
|
||||
RigidBodyShape shape;
|
||||
/// 大きさ
|
||||
float size[3];
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 質量
|
||||
float weight;
|
||||
/// 移動ダンピング
|
||||
float linear_damping;
|
||||
/// 回転ダンピング
|
||||
float anglar_damping;
|
||||
/// 反発係数
|
||||
float restitution;
|
||||
/// 摩擦係数
|
||||
float friction;
|
||||
/// 演算方法
|
||||
RigidBodyType rigid_type;
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -414,31 +354,19 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 剛体の拘束
|
||||
class PmdConstraint
|
||||
{
|
||||
public:
|
||||
/// 名前
|
||||
std::string name;
|
||||
/// 剛体Aのインデックス
|
||||
uint32_t rigid_body_index_a;
|
||||
/// 剛体Bのインデックス
|
||||
uint32_t rigid_body_index_b;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 最小移動制限
|
||||
float linear_lower_limit[3];
|
||||
/// 最大移動制限
|
||||
float linear_upper_limit[3];
|
||||
/// 最小回転制限
|
||||
float angular_lower_limit[3];
|
||||
/// 最大回転制限
|
||||
float angular_upper_limit[3];
|
||||
/// 移動に対する復元力
|
||||
float linear_stiffness[3];
|
||||
/// 回転に対する復元力
|
||||
float angular_stiffness[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -459,7 +387,6 @@ namespace pmd
|
|||
}
|
||||
};
|
||||
|
||||
/// PMDモデル
|
||||
class PmdModel
|
||||
{
|
||||
public:
|
||||
|
@ -491,7 +418,6 @@ namespace pmd
|
|||
return result;
|
||||
}
|
||||
|
||||
/// ファイルからPmdModelを生成する
|
||||
static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
|
||||
{
|
||||
auto result = mmd::make_unique<PmdModel>();
|
||||
|
|
|
@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace pmx
|
||||
{
|
||||
/// インデックス値を読み込む
|
||||
int ReadIndex(std::istream *stream, int size)
|
||||
{
|
||||
switch (size)
|
||||
|
@ -79,7 +78,6 @@ namespace pmx
|
|||
}
|
||||
}
|
||||
|
||||
/// 文字列を読み込む
|
||||
std::string ReadString(std::istream *stream, uint8_t encoding)
|
||||
{
|
||||
int size;
|
||||
|
@ -218,8 +216,8 @@ namespace pmx
|
|||
|
||||
void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->material_name = std::move(ReadString(stream, setting->encoding));
|
||||
this->material_english_name = std::move(ReadString(stream, setting->encoding));
|
||||
this->material_name = ReadString(stream, setting->encoding);
|
||||
this->material_english_name = ReadString(stream, setting->encoding);
|
||||
stream->read((char*) this->diffuse, sizeof(float) * 4);
|
||||
stream->read((char*) this->specular, sizeof(float) * 3);
|
||||
stream->read((char*) &this->specularlity, sizeof(float));
|
||||
|
@ -238,7 +236,7 @@ namespace pmx
|
|||
else {
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -255,8 +253,8 @@ namespace pmx
|
|||
|
||||
void PmxBone::Read(std::istream *stream, PmxSetting *setting)
|
||||
{
|
||||
this->bone_name = std::move(ReadString(stream, setting->encoding));
|
||||
this->bone_english_name = std::move(ReadString(stream, setting->encoding));
|
||||
this->bone_name = ReadString(stream, setting->encoding);
|
||||
this->bone_english_name = ReadString(stream, setting->encoding);
|
||||
stream->read((char*) this->position, sizeof(float) * 3);
|
||||
this->parent_index = ReadIndex(stream, setting->bone_index_size);
|
||||
stream->read((char*) &this->level, sizeof(int));
|
||||
|
@ -530,10 +528,10 @@ namespace pmx
|
|||
this->setting.Read(stream);
|
||||
|
||||
// モデル情報
|
||||
this->model_name = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_english_name = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_comment = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_english_comment = std::move(ReadString(stream, setting.encoding));
|
||||
this->model_name = ReadString(stream, setting.encoding);
|
||||
this->model_english_name = ReadString(stream, setting.encoding);
|
||||
this->model_comment = ReadString(stream, setting.encoding);
|
||||
this->model_english_comment = ReadString(stream, setting.encoding);
|
||||
|
||||
// 頂点
|
||||
stream->read((char*) &vertex_count, sizeof(int));
|
||||
|
@ -607,7 +605,6 @@ namespace pmx
|
|||
this->joints[i].Read(stream, &setting);
|
||||
}
|
||||
|
||||
//// ソフトボディ
|
||||
//if (this->version == 2.1f)
|
||||
//{
|
||||
// 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
|
||||
{
|
||||
/// インデックス設定
|
||||
class PmxSetting
|
||||
{
|
||||
public:
|
||||
|
@ -64,26 +63,17 @@ namespace pmx
|
|||
, rigidbody_index_size(0)
|
||||
{}
|
||||
|
||||
/// エンコード方式
|
||||
uint8_t encoding;
|
||||
/// 追加UV数
|
||||
uint8_t uv;
|
||||
/// 頂点インデックスサイズ
|
||||
uint8_t vertex_index_size;
|
||||
/// テクスチャインデックスサイズ
|
||||
uint8_t texture_index_size;
|
||||
/// マテリアルインデックスサイズ
|
||||
uint8_t material_index_size;
|
||||
/// ボーンインデックスサイズ
|
||||
uint8_t bone_index_size;
|
||||
/// モーフインデックスサイズ
|
||||
uint8_t morph_index_size;
|
||||
/// 剛体インデックスサイズ
|
||||
uint8_t rigidbody_index_size;
|
||||
void Read(std::istream *stream);
|
||||
};
|
||||
|
||||
/// 頂点スキニングタイプ
|
||||
enum class PmxVertexSkinningType : uint8_t
|
||||
{
|
||||
BDEF1 = 0,
|
||||
|
@ -93,7 +83,6 @@ namespace pmx
|
|||
QDEF = 4,
|
||||
};
|
||||
|
||||
/// 頂点スキニング
|
||||
class PmxVertexSkinning
|
||||
{
|
||||
public:
|
||||
|
@ -200,7 +189,6 @@ namespace pmx
|
|||
void Read(std::istream *stresam, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// 頂点
|
||||
class PmxVertex
|
||||
{
|
||||
public:
|
||||
|
@ -219,24 +207,16 @@ namespace pmx
|
|||
}
|
||||
}
|
||||
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 法線
|
||||
float normal[3];
|
||||
/// テクスチャ座標
|
||||
float uv[2];
|
||||
/// 追加テクスチャ座標
|
||||
float uva[4][4];
|
||||
/// スキニングタイプ
|
||||
PmxVertexSkinningType skinning_type;
|
||||
/// スキニング
|
||||
std::unique_ptr<PmxVertexSkinning> skinning;
|
||||
/// エッジ倍率
|
||||
float edge;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// マテリアル
|
||||
class PmxMaterial
|
||||
{
|
||||
public:
|
||||
|
@ -261,42 +241,25 @@ namespace pmx
|
|||
}
|
||||
}
|
||||
|
||||
/// モデル名
|
||||
std::string material_name;
|
||||
/// モデル英名
|
||||
std::string material_english_name;
|
||||
/// 減衰色
|
||||
float diffuse[4];
|
||||
/// 光沢色
|
||||
float specular[3];
|
||||
/// 光沢度
|
||||
float specularlity;
|
||||
/// 環境色
|
||||
float ambient[3];
|
||||
/// 描画フラグ
|
||||
uint8_t flag;
|
||||
/// エッジ色
|
||||
float edge_color[4];
|
||||
/// エッジサイズ
|
||||
float edge_size;
|
||||
/// アルベドテクスチャインデックス
|
||||
int diffuse_texture_index;
|
||||
/// スフィアテクスチャインデックス
|
||||
int sphere_texture_index;
|
||||
/// スフィアテクスチャ演算モード
|
||||
uint8_t sphere_op_mode;
|
||||
/// 共有トゥーンフラグ
|
||||
uint8_t common_toon_flag;
|
||||
/// トゥーンテクスチャインデックス
|
||||
int toon_texture_index;
|
||||
/// メモ
|
||||
std::string memo;
|
||||
/// 頂点インデックス数
|
||||
int index_count;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// リンク
|
||||
class PmxIkLink
|
||||
{
|
||||
public:
|
||||
|
@ -310,18 +273,13 @@ namespace pmx
|
|||
}
|
||||
}
|
||||
|
||||
/// リンクボーンインデックス
|
||||
int link_target;
|
||||
/// 角度制限
|
||||
uint8_t angle_lock;
|
||||
/// 最大制限角度
|
||||
float max_radian[3];
|
||||
/// 最小制限角度
|
||||
float min_radian[3];
|
||||
void Read(std::istream *stream, PmxSetting *settingn);
|
||||
};
|
||||
|
||||
/// ボーン
|
||||
class PmxBone
|
||||
{
|
||||
public:
|
||||
|
@ -347,43 +305,24 @@ namespace pmx
|
|||
}
|
||||
}
|
||||
|
||||
/// ボーン名
|
||||
std::string bone_name;
|
||||
/// ボーン英名
|
||||
std::string bone_english_name;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 親ボーンインデックス
|
||||
int parent_index;
|
||||
/// 階層
|
||||
int level;
|
||||
/// ボーンフラグ
|
||||
uint16_t bone_flag;
|
||||
/// 座標オフセット(has Target)
|
||||
float offset[3];
|
||||
/// 接続先ボーンインデックス(not has Target)
|
||||
int target_index;
|
||||
/// 付与親ボーンインデックス
|
||||
int grant_parent_index;
|
||||
/// 付与率
|
||||
float grant_weight;
|
||||
/// 固定軸の方向
|
||||
float lock_axis_orientation[3];
|
||||
/// ローカル軸のX軸方向
|
||||
float local_axis_x_orientation[3];
|
||||
/// ローカル軸のY軸方向
|
||||
float local_axis_y_orientation[3];
|
||||
/// 外部親変形のkey値
|
||||
int key;
|
||||
/// IKターゲットボーン
|
||||
int ik_target_bone_index;
|
||||
/// IKループ回数
|
||||
int ik_loop;
|
||||
/// IKループ計算時の角度制限(ラジアン)
|
||||
float ik_loop_angle_limit;
|
||||
/// IKリンク数
|
||||
int ik_link_count;
|
||||
/// IKリンク
|
||||
std::unique_ptr<PmxIkLink []> ik_links;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
@ -543,7 +482,6 @@ namespace pmx
|
|||
void Read(std::istream *stream, PmxSetting *setting); //override;
|
||||
};
|
||||
|
||||
/// モーフ
|
||||
class PmxMorph
|
||||
{
|
||||
public:
|
||||
|
@ -551,34 +489,21 @@ namespace pmx
|
|||
: offset_count(0)
|
||||
{
|
||||
}
|
||||
/// モーフ名
|
||||
std::string morph_name;
|
||||
/// モーフ英名
|
||||
std::string morph_english_name;
|
||||
/// カテゴリ
|
||||
MorphCategory category;
|
||||
/// モーフタイプ
|
||||
MorphType morph_type;
|
||||
/// オフセット数
|
||||
int offset_count;
|
||||
/// 頂点モーフ配列
|
||||
std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
|
||||
/// UVモーフ配列
|
||||
std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
|
||||
/// ボーンモーフ配列
|
||||
std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
|
||||
/// マテリアルモーフ配列
|
||||
std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
|
||||
/// グループモーフ配列
|
||||
std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
|
||||
/// フリップモーフ配列
|
||||
std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
|
||||
/// インパルスモーフ配列
|
||||
std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// 枠内要素
|
||||
class PmxFrameElement
|
||||
{
|
||||
public:
|
||||
|
@ -587,14 +512,11 @@ namespace pmx
|
|||
, index(0)
|
||||
{
|
||||
}
|
||||
/// 要素対象
|
||||
uint8_t element_target;
|
||||
/// 要素対象インデックス
|
||||
int index;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// 表示枠
|
||||
class PmxFrame
|
||||
{
|
||||
public:
|
||||
|
@ -603,15 +525,10 @@ namespace pmx
|
|||
, element_count(0)
|
||||
{
|
||||
}
|
||||
/// 枠名
|
||||
std::string frame_name;
|
||||
/// 枠英名
|
||||
std::string frame_english_name;
|
||||
/// 特殊枠フラグ
|
||||
uint8_t frame_flag;
|
||||
/// 枠内要素数
|
||||
int element_count;
|
||||
/// 枠内要素配列
|
||||
std::unique_ptr<PmxFrameElement []> elements;
|
||||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
@ -637,17 +554,11 @@ namespace pmx
|
|||
orientation[i] = 0.0f;
|
||||
}
|
||||
}
|
||||
/// 剛体名
|
||||
std::string girid_body_name;
|
||||
/// 剛体英名
|
||||
std::string girid_body_english_name;
|
||||
/// 関連ボーンインデックス
|
||||
int target_bone;
|
||||
/// グループ
|
||||
uint8_t group;
|
||||
/// マスク
|
||||
uint16_t mask;
|
||||
/// 形状
|
||||
uint8_t shape;
|
||||
float size[3];
|
||||
float position[3];
|
||||
|
@ -818,7 +729,6 @@ namespace pmx
|
|||
void Read(std::istream *stream, PmxSetting *setting);
|
||||
};
|
||||
|
||||
/// PMXモデル
|
||||
class PmxModel
|
||||
{
|
||||
public:
|
||||
|
@ -836,65 +746,35 @@ namespace pmx
|
|||
, soft_body_count(0)
|
||||
{}
|
||||
|
||||
/// バージョン
|
||||
float version;
|
||||
/// 設定
|
||||
PmxSetting setting;
|
||||
/// モデル名
|
||||
std::string model_name;
|
||||
/// モデル英名
|
||||
std::string model_english_name;
|
||||
/// コメント
|
||||
std::string model_comment;
|
||||
/// 英語コメント
|
||||
std::string model_english_comment;
|
||||
/// 頂点数
|
||||
int vertex_count;
|
||||
/// 頂点配列
|
||||
std::unique_ptr<PmxVertex []> vertices;
|
||||
/// インデックス数
|
||||
int index_count;
|
||||
/// インデックス配列
|
||||
std::unique_ptr<int []> indices;
|
||||
/// テクスチャ数
|
||||
int texture_count;
|
||||
/// テクスチャ配列
|
||||
std::unique_ptr< std::string []> textures;
|
||||
/// マテリアル数
|
||||
int material_count;
|
||||
/// マテリアル
|
||||
std::unique_ptr<PmxMaterial []> materials;
|
||||
/// ボーン数
|
||||
int bone_count;
|
||||
/// ボーン配列
|
||||
std::unique_ptr<PmxBone []> bones;
|
||||
/// モーフ数
|
||||
int morph_count;
|
||||
/// モーフ配列
|
||||
std::unique_ptr<PmxMorph []> morphs;
|
||||
/// 表示枠数
|
||||
int frame_count;
|
||||
/// 表示枠配列
|
||||
std::unique_ptr<PmxFrame [] > frames;
|
||||
/// 剛体数
|
||||
int rigid_body_count;
|
||||
/// 剛体配列
|
||||
std::unique_ptr<PmxRigidBody []> rigid_bodies;
|
||||
/// ジョイント数
|
||||
int joint_count;
|
||||
/// ジョイント配列
|
||||
std::unique_ptr<PmxJoint []> joints;
|
||||
/// ソフトボディ数
|
||||
int soft_body_count;
|
||||
/// ソフトボディ配列
|
||||
std::unique_ptr<PmxSoftBody []> soft_bodies;
|
||||
/// モデル初期化
|
||||
void Init();
|
||||
/// モデル読み込み
|
||||
void Read(std::istream *stream);
|
||||
///// ファイルからモデルの読み込み
|
||||
//static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
|
||||
///// 入力ストリームからモデルの読み込み
|
||||
//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
|
||||
{
|
||||
/// ボーンフレーム
|
||||
class VmdBoneFrame
|
||||
{
|
||||
public:
|
||||
/// ボーン名
|
||||
std::string name;
|
||||
/// フレーム番号
|
||||
int frame;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[4];
|
||||
/// 補間曲線
|
||||
char interpolation[4][4][4];
|
||||
|
||||
void Read(std::istream* stream)
|
||||
|
@ -86,15 +80,11 @@ namespace vmd
|
|||
}
|
||||
};
|
||||
|
||||
/// 表情フレーム
|
||||
class VmdFaceFrame
|
||||
{
|
||||
public:
|
||||
/// 表情名
|
||||
std::string face_name;
|
||||
/// 表情の重み
|
||||
float weight;
|
||||
/// フレーム番号
|
||||
uint32_t frame;
|
||||
|
||||
void Read(std::istream* stream)
|
||||
|
@ -114,23 +104,15 @@ namespace vmd
|
|||
}
|
||||
};
|
||||
|
||||
/// カメラフレーム
|
||||
class VmdCameraFrame
|
||||
{
|
||||
public:
|
||||
/// フレーム番号
|
||||
int frame;
|
||||
/// 距離
|
||||
float distance;
|
||||
/// 位置
|
||||
float position[3];
|
||||
/// 回転
|
||||
float orientation[3];
|
||||
/// 補間曲線
|
||||
char interpolation[6][4];
|
||||
/// 視野角
|
||||
float angle;
|
||||
/// 不明データ
|
||||
char unknown[3];
|
||||
|
||||
void Read(std::istream *stream)
|
||||
|
@ -156,15 +138,11 @@ namespace vmd
|
|||
}
|
||||
};
|
||||
|
||||
/// ライトフレーム
|
||||
class VmdLightFrame
|
||||
{
|
||||
public:
|
||||
/// フレーム番号
|
||||
int frame;
|
||||
/// 色
|
||||
float color[3];
|
||||
/// 位置
|
||||
float position[3];
|
||||
|
||||
void Read(std::istream* stream)
|
||||
|
@ -182,7 +160,6 @@ namespace vmd
|
|||
}
|
||||
};
|
||||
|
||||
/// IKの有効無効
|
||||
class VmdIkEnable
|
||||
{
|
||||
public:
|
||||
|
@ -190,7 +167,6 @@ namespace vmd
|
|||
bool enable;
|
||||
};
|
||||
|
||||
/// IKフレーム
|
||||
class VmdIkFrame
|
||||
{
|
||||
public:
|
||||
|
@ -229,23 +205,15 @@ namespace vmd
|
|||
}
|
||||
};
|
||||
|
||||
/// VMDモーション
|
||||
class VmdMotion
|
||||
{
|
||||
public:
|
||||
/// モデル名
|
||||
std::string model_name;
|
||||
/// バージョン
|
||||
int version;
|
||||
/// ボーンフレーム
|
||||
std::vector<VmdBoneFrame> bone_frames;
|
||||
/// 表情フレーム
|
||||
std::vector<VmdFaceFrame> face_frames;
|
||||
/// カメラフレーム
|
||||
std::vector<VmdCameraFrame> camera_frames;
|
||||
/// ライトフレーム
|
||||
std::vector<VmdLightFrame> light_frames;
|
||||
/// IKフレーム
|
||||
std::vector<VmdIkFrame> ik_frames;
|
||||
|
||||
static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
|
||||
|
|
|
@ -193,14 +193,14 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
|||
p = 0;
|
||||
while (pcMesh->HasTextureCoords(p))
|
||||
{
|
||||
delete pcMesh->mTextureCoords[p];
|
||||
delete[] pcMesh->mTextureCoords[p];
|
||||
pcMesh->mTextureCoords[p] = apvTextureCoords[p];
|
||||
++p;
|
||||
}
|
||||
p = 0;
|
||||
while (pcMesh->HasVertexColors(p))
|
||||
{
|
||||
delete pcMesh->mColors[p];
|
||||
delete[] pcMesh->mColors[p];
|
||||
pcMesh->mColors[p] = apvColorSets[p];
|
||||
++p;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
{
|
||||
if (!pIOHandler)return true;
|
||||
const char* tokens[] = {"off"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,3);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -91,11 +91,11 @@ ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene)
|
|||
, vn()
|
||||
, vt()
|
||||
, vc()
|
||||
, vpMap()
|
||||
, vnMap()
|
||||
, vtMap()
|
||||
, vcMap()
|
||||
, meshes()
|
||||
, mVpMap()
|
||||
, mVnMap()
|
||||
, mVtMap()
|
||||
, mVcMap()
|
||||
, mMeshes()
|
||||
, endl("\n") {
|
||||
// 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");
|
||||
|
@ -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 << "# (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];
|
||||
if ( nullptr == mat ) {
|
||||
static const std::string EmptyStr;
|
||||
return EmptyStr;
|
||||
}
|
||||
|
||||
aiString s;
|
||||
if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) {
|
||||
return std::string(s.data,s.length);
|
||||
|
@ -235,8 +241,8 @@ void ObjExporter::WriteGeometryFile() {
|
|||
AddNode(pScene->mRootNode, mBase);
|
||||
|
||||
// write vertex positions with colors, if any
|
||||
vpMap.getVectors( vp );
|
||||
vcMap.getColors( vc );
|
||||
mVpMap.getVectors( vp );
|
||||
mVcMap.getColors( vc );
|
||||
if ( vc.empty() ) {
|
||||
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
||||
for ( const aiVector3D& v : vp ) {
|
||||
|
@ -253,7 +259,7 @@ void ObjExporter::WriteGeometryFile() {
|
|||
mOutput << endl;
|
||||
|
||||
// write uv coordinates
|
||||
vtMap.getVectors(vt);
|
||||
mVtMap.getVectors(vt);
|
||||
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
||||
for(const aiVector3D& v : vt) {
|
||||
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
||||
|
@ -261,7 +267,7 @@ void ObjExporter::WriteGeometryFile() {
|
|||
mOutput << endl;
|
||||
|
||||
// write vertex normals
|
||||
vnMap.getVectors(vn);
|
||||
mVnMap.getVectors(vn);
|
||||
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
||||
for(const aiVector3D& v : vn) {
|
||||
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
||||
|
@ -269,7 +275,7 @@ void ObjExporter::WriteGeometryFile() {
|
|||
mOutput << endl;
|
||||
|
||||
// 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;
|
||||
if (!m.name.empty()) {
|
||||
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) {
|
||||
meshes.push_back(MeshInstance());
|
||||
MeshInstance& mesh = meshes.back();
|
||||
mMeshes.push_back(MeshInstance());
|
||||
MeshInstance& mesh = mMeshes.back();
|
||||
|
||||
mesh.name = std::string(name.data,name.length) + (m->mName.length ? "_" + std::string(m->mName.data,m->mName.length) : "");
|
||||
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];
|
||||
|
||||
aiVector3D vert = mat * m->mVertices[idx];
|
||||
face.indices[a].vp = vpMap.getIndex(vert);
|
||||
face.indices[a].vp = mVpMap.getIndex(vert);
|
||||
|
||||
if (m->mNormals) {
|
||||
aiVector3D norm = aiMatrix3x3(mat) * m->mNormals[idx];
|
||||
face.indices[a].vn = vnMap.getIndex(norm);
|
||||
face.indices[a].vn = mVnMap.getIndex(norm);
|
||||
} else {
|
||||
face.indices[a].vn = 0;
|
||||
}
|
||||
|
||||
if ( nullptr != m->mColors[ 0 ] ) {
|
||||
aiColor4D col4 = m->mColors[ 0 ][ idx ];
|
||||
face.indices[ a ].vc = vcMap.getIndex( col4 );
|
||||
face.indices[ a ].vc = mVcMap.getIndex( col4 );
|
||||
} else {
|
||||
face.indices[ a ].vc = 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 {
|
||||
face.indices[a].vt = 0;
|
||||
}
|
||||
|
|
|
@ -163,9 +163,9 @@ private:
|
|||
void getColors( std::vector<aiColor4D> &colors );
|
||||
};
|
||||
|
||||
vecIndexMap vpMap, vnMap, vtMap;
|
||||
colIndexMap vcMap;
|
||||
std::vector<MeshInstance> meshes;
|
||||
vecIndexMap mVpMap, mVnMap, mVtMap;
|
||||
colIndexMap mVcMap;
|
||||
std::vector<MeshInstance> mMeshes;
|
||||
|
||||
// this endl() doesn't flush() the stream
|
||||
const std::string endl;
|
||||
|
|
|
@ -55,20 +55,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
// Material specific token
|
||||
static const std::string DiffuseTexture = "map_Kd";
|
||||
static const std::string AmbientTexture = "map_Ka";
|
||||
static const std::string SpecularTexture = "map_Ks";
|
||||
static const std::string OpacityTexture = "map_d";
|
||||
static const std::string EmissiveTexture = "map_emissive";
|
||||
static const std::string EmissiveTexture_1 = "map_Ke";
|
||||
static const std::string BumpTexture1 = "map_bump";
|
||||
static const std::string BumpTexture2 = "map_Bump";
|
||||
static const std::string BumpTexture3 = "bump";
|
||||
static const std::string NormalTexture = "map_Kn";
|
||||
static const std::string ReflectionTexture = "refl";
|
||||
static const std::string DisplacementTexture = "disp";
|
||||
static const std::string SpecularityTexture = "map_ns";
|
||||
// Material specific token (case insensitive compare)
|
||||
static const std::string DiffuseTexture = "map_Kd";
|
||||
static const std::string AmbientTexture = "map_Ka";
|
||||
static const std::string SpecularTexture = "map_Ks";
|
||||
static const std::string OpacityTexture = "map_d";
|
||||
static const std::string EmissiveTexture1 = "map_emissive";
|
||||
static const std::string EmissiveTexture2 = "map_Ke";
|
||||
static const std::string BumpTexture1 = "map_bump";
|
||||
static const std::string BumpTexture2 = "bump";
|
||||
static const std::string NormalTexture = "map_Kn";
|
||||
static const std::string ReflectionTexture = "refl";
|
||||
static const std::string DisplacementTexture1 = "map_disp";
|
||||
static const std::string DisplacementTexture2 = "disp";
|
||||
static const std::string SpecularityTexture = "map_ns";
|
||||
|
||||
// texture option specific token
|
||||
static const std::string BlendUOption = "-blendu";
|
||||
|
@ -304,7 +304,7 @@ void ObjFileMtlImporter::createMaterial()
|
|||
m_pModel->m_pCurrentMaterial = new ObjFile::Material();
|
||||
m_pModel->m_pCurrentMaterial->MaterialName.Set( name );
|
||||
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_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial;
|
||||
|
@ -329,7 +329,7 @@ void ObjFileMtlImporter::getTexture() {
|
|||
// Ambient texture
|
||||
out = & m_pModel->m_pCurrentMaterial->textureAmbient;
|
||||
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
|
||||
out = & m_pModel->m_pCurrentMaterial->textureSpecular;
|
||||
clampIndex = ObjFile::Material::TextureSpecularType;
|
||||
|
@ -337,33 +337,30 @@ void ObjFileMtlImporter::getTexture() {
|
|||
// Opacity texture
|
||||
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
|
||||
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
|
||||
out = & m_pModel->m_pCurrentMaterial->textureEmissive;
|
||||
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()) ) ||
|
||||
!ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()) ) ||
|
||||
!ASSIMP_strincmp( pPtr, BumpTexture3.c_str(), static_cast<unsigned int>(BumpTexture3.size()) ) ) {
|
||||
!ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()) ) ) {
|
||||
// Bump texture
|
||||
out = & m_pModel->m_pCurrentMaterial->textureBump;
|
||||
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
|
||||
out = & m_pModel->m_pCurrentMaterial->textureNormal;
|
||||
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)
|
||||
//Do nothing here
|
||||
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
|
||||
out = &m_pModel->m_pCurrentMaterial->textureDisp;
|
||||
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)
|
||||
out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
|
||||
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 );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 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 ) {
|
||||
ai_real x, y, z;
|
||||
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 );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get values for a new 2D vector instance
|
||||
void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
||||
ai_real x, y;
|
||||
copyNextWord(m_buffer, Buffersize);
|
||||
|
@ -405,8 +401,6 @@ void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
|||
|
||||
static const std::string DefaultObjName = "defaultobject";
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get values for a new face instance
|
||||
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
||||
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
||||
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 );
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get values for a new material description
|
||||
void ObjFileParser::getMaterialDesc() {
|
||||
// Get next data for material data
|
||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
|
@ -555,10 +547,15 @@ void ObjFileParser::getMaterialDesc() {
|
|||
// Search for material
|
||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
|
||||
if (it == m_pModel->m_MaterialMap.end()) {
|
||||
// Not found, use default material
|
||||
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
||||
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
|
||||
strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
|
||||
// Not found, so we don't know anything about the material except for its name.
|
||||
// This may be the case if the material library is missing. We don't want to lose all
|
||||
// materials if that happens, so create a new named material instead of discarding it
|
||||
// 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 {
|
||||
// Found, using detected material
|
||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
||||
|
|
|
@ -261,6 +261,7 @@ OpenGEXImporter::OpenGEXImporter()
|
|||
, m_nodeChildMap()
|
||||
, m_meshCache()
|
||||
, m_mesh2refMap()
|
||||
, m_material2refMap()
|
||||
, m_ctx( nullptr )
|
||||
, m_metrics()
|
||||
, m_currentNode( nullptr )
|
||||
|
@ -306,6 +307,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce
|
|||
|
||||
std::vector<char> buffer;
|
||||
TextFileToBuffer( file, buffer );
|
||||
pIOHandler->Close( file );
|
||||
|
||||
OpenDDLParser myParser;
|
||||
myParser.setBuffer( &buffer[ 0 ], buffer.size() );
|
||||
|
@ -320,6 +322,7 @@ void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pSce
|
|||
copyMeshes( pScene );
|
||||
copyCameras( pScene );
|
||||
copyLights( pScene );
|
||||
copyMaterials( pScene );
|
||||
resolveReferences();
|
||||
createNodeTree( pScene );
|
||||
}
|
||||
|
@ -482,7 +485,10 @@ void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) {
|
|||
|| m_tokenType == Grammar::CameraNodeToken ) {
|
||||
m_currentNode->mName.Set( name.c_str() );
|
||||
} 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->mMeshes = new unsigned int[ objRefNames.size() ];
|
||||
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 ) {
|
||||
// TODO!
|
||||
|
@ -539,7 +545,7 @@ void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene
|
|||
std::vector<std::string> matRefNames;
|
||||
getRefNames( node, matRefNames );
|
||||
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 ) );
|
||||
} else if( prop->m_value->getString() == Grammar::SpecularPowerTextureToken ) {
|
||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR( 0 ) );
|
||||
|
||||
} else if( prop->m_value->getString() == Grammar::EmissionTextureToken ) {
|
||||
m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE( 0 ) );
|
||||
} 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 );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
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() {
|
||||
if( m_unresolvedRefStack.empty() ) {
|
||||
|
@ -1161,12 +1179,12 @@ void OpenGEXImporter::resolveReferences() {
|
|||
}
|
||||
|
||||
RefInfo *currentRefInfo( nullptr );
|
||||
for( std::vector<RefInfo*>::iterator it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
|
||||
currentRefInfo = *it;
|
||||
for( auto it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
|
||||
currentRefInfo = it->get();
|
||||
if( nullptr != currentRefInfo ) {
|
||||
aiNode *node( currentRefInfo->m_node );
|
||||
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 ] );
|
||||
ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
|
||||
if( m_mesh2refMap.end() != it ) {
|
||||
|
@ -1175,7 +1193,22 @@ void OpenGEXImporter::resolveReferences() {
|
|||
}
|
||||
}
|
||||
} 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 {
|
||||
throw DeadlyImportError( "Unknown reference info to resolve." );
|
||||
}
|
||||
|
@ -1213,9 +1246,9 @@ void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
|||
if( m_nodeChildMap.end() == it ) {
|
||||
info = new ChildInfo;
|
||||
m_root = info;
|
||||
m_nodeChildMap[ node->mParent ] = info;
|
||||
m_nodeChildMap[ node->mParent ] = std::unique_ptr<ChildInfo>(info);
|
||||
} else {
|
||||
info = it->second;
|
||||
info = it->second.get();
|
||||
}
|
||||
info->m_children.push_back( node );
|
||||
} else {
|
||||
|
@ -1225,9 +1258,9 @@ void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
|||
NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
|
||||
if( m_nodeChildMap.end() == it ) {
|
||||
info = new ChildInfo;
|
||||
m_nodeChildMap[ node->mParent ] = info;
|
||||
m_nodeChildMap[ node->mParent ] = std::unique_ptr<ChildInfo>(info);
|
||||
} else {
|
||||
info = it->second;
|
||||
info = it->second.get();
|
||||
}
|
||||
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 <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace ODDLParser {
|
||||
class DDLNode;
|
||||
|
@ -132,6 +133,7 @@ protected:
|
|||
void copyMeshes( aiScene *pScene );
|
||||
void copyCameras( aiScene *pScene );
|
||||
void copyLights( aiScene *pScene );
|
||||
void copyMaterials( aiScene *pScene );
|
||||
void resolveReferences();
|
||||
void pushNode( aiNode *node, aiScene *pScene );
|
||||
aiNode *popNode();
|
||||
|
@ -179,12 +181,13 @@ private:
|
|||
std::list<aiNode*> m_children;
|
||||
};
|
||||
ChildInfo *m_root;
|
||||
typedef std::map<aiNode*, ChildInfo*> NodeChildMap;
|
||||
typedef std::map<aiNode*, std::unique_ptr<ChildInfo> > NodeChildMap;
|
||||
NodeChildMap m_nodeChildMap;
|
||||
|
||||
std::vector<aiMesh*> m_meshCache;
|
||||
typedef std::map<std::string, size_t> ReferenceMap;
|
||||
std::map<std::string, size_t> m_mesh2refMap;
|
||||
std::map<std::string, size_t> m_material2refMap;
|
||||
|
||||
ODDLParser::Context *m_ctx;
|
||||
MetricInfo m_metrics[ MetricInfo::Max ];
|
||||
|
@ -199,7 +202,7 @@ private:
|
|||
std::vector<aiCamera*> m_cameraCache;
|
||||
std::vector<aiLight*> m_lightCache;
|
||||
std::vector<aiNode*> m_nodeStack;
|
||||
std::vector<RefInfo*> m_unresolvedRefStack;
|
||||
std::vector<std::unique_ptr<RefInfo> > m_unresolvedRefStack;
|
||||
};
|
||||
|
||||
} // Namespace OpenGEX
|
||||
|
|
|
@ -181,11 +181,8 @@ void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
|
|||
verts += mScene->mMeshes[am]->mNumVertices;
|
||||
faces += mScene->mMeshes[am]->mNumFaces;
|
||||
|
||||
pNode->mMeshes[a] = pNode->mMeshes[pNode->mNumMeshes - 1];
|
||||
--pNode->mNumMeshes;
|
||||
for( unsigned int n = a; n < pNode->mNumMeshes; ++n ) {
|
||||
pNode->mMeshes[ n ] = pNode->mMeshes[ n + 1 ];
|
||||
}
|
||||
|
||||
--a;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -170,9 +170,10 @@ void PLYImporter::InternReadFile(const std::string& pFile,
|
|||
std::vector<char> headerCheck;
|
||||
streamedBuffer.getNextLine(headerCheck);
|
||||
|
||||
if ((headerCheck.size() >= 3) && (headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
|
||||
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
|
||||
(headerCheck[2] != 'Y' && headerCheck[2] != 'y'))
|
||||
if ((headerCheck.size() < 3) ||
|
||||
(headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
|
||||
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
|
||||
(headerCheck[2] != 'Y' && headerCheck[2] != 'y') )
|
||||
{
|
||||
streamedBuffer.close();
|
||||
throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
|
||||
|
@ -299,252 +300,205 @@ void PLYImporter::InternReadFile(const std::string& pFile,
|
|||
}
|
||||
}
|
||||
|
||||
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
|
||||
{
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != instElement);
|
||||
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
|
||||
ai_assert(NULL != pcElement);
|
||||
ai_assert(NULL != instElement);
|
||||
|
||||
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
||||
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
||||
|
||||
ai_uint aiNormal[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiNormalTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
||||
ai_uint aiNormal[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiNormalTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
|
||||
|
||||
unsigned int aiColors[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiColorsTypes[4] = { EDT_Char, EDT_Char, EDT_Char, EDT_Char };
|
||||
unsigned int aiColors[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiColorsTypes[4] = { EDT_Char, EDT_Char, EDT_Char, EDT_Char };
|
||||
|
||||
unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
|
||||
unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
|
||||
PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
|
||||
|
||||
unsigned int cnt = 0;
|
||||
// now check whether which normal components are available
|
||||
unsigned int _a( 0 ), cnt( 0 );
|
||||
for ( std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
a != pcElement->alProperties.end(); ++a, ++_a) {
|
||||
if ((*a).bIsList) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// now check whether which normal components are available
|
||||
unsigned int _a = 0;
|
||||
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
|
||||
a != pcElement->alProperties.end(); ++a, ++_a)
|
||||
{
|
||||
if ((*a).bIsList)continue;
|
||||
|
||||
// Positions
|
||||
if (PLY::EST_XCoord == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiPositions[0] = _a;
|
||||
aiTypes[0] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_YCoord == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiPositions[1] = _a;
|
||||
aiTypes[1] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_ZCoord == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiPositions[2] = _a;
|
||||
aiTypes[2] = (*a).eType;
|
||||
// Positions
|
||||
if (PLY::EST_XCoord == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiPositions[0] = _a;
|
||||
aiTypes[0] = (*a).eType;
|
||||
} else if (PLY::EST_YCoord == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiPositions[1] = _a;
|
||||
aiTypes[1] = (*a).eType;
|
||||
} else if (PLY::EST_ZCoord == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiPositions[2] = _a;
|
||||
aiTypes[2] = (*a).eType;
|
||||
} else if (PLY::EST_XNormal == (*a).Semantic) {
|
||||
// Normals
|
||||
++cnt;
|
||||
aiNormal[0] = _a;
|
||||
aiNormalTypes[0] = (*a).eType;
|
||||
} else if (PLY::EST_YNormal == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiNormal[1] = _a;
|
||||
aiNormalTypes[1] = (*a).eType;
|
||||
} else if (PLY::EST_ZNormal == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiNormal[2] = _a;
|
||||
aiNormalTypes[2] = (*a).eType;
|
||||
} else if (PLY::EST_Red == (*a).Semantic) {
|
||||
// Colors
|
||||
++cnt;
|
||||
aiColors[0] = _a;
|
||||
aiColorsTypes[0] = (*a).eType;
|
||||
} else if (PLY::EST_Green == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiColors[1] = _a;
|
||||
aiColorsTypes[1] = (*a).eType;
|
||||
} else if (PLY::EST_Blue == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiColors[2] = _a;
|
||||
aiColorsTypes[2] = (*a).eType;
|
||||
} else if (PLY::EST_Alpha == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiColors[3] = _a;
|
||||
aiColorsTypes[3] = (*a).eType;
|
||||
} else if (PLY::EST_UTextureCoord == (*a).Semantic) {
|
||||
// Texture coordinates
|
||||
++cnt;
|
||||
aiTexcoord[0] = _a;
|
||||
aiTexcoordTypes[0] = (*a).eType;
|
||||
} else if (PLY::EST_VTextureCoord == (*a).Semantic) {
|
||||
++cnt;
|
||||
aiTexcoord[1] = _a;
|
||||
aiTexcoordTypes[1] = (*a).eType;
|
||||
}
|
||||
}
|
||||
|
||||
// Normals
|
||||
else if (PLY::EST_XNormal == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiNormal[0] = _a;
|
||||
aiNormalTypes[0] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_YNormal == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiNormal[1] = _a;
|
||||
aiNormalTypes[1] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_ZNormal == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiNormal[2] = _a;
|
||||
aiNormalTypes[2] = (*a).eType;
|
||||
}
|
||||
// Colors
|
||||
else if (PLY::EST_Red == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiColors[0] = _a;
|
||||
aiColorsTypes[0] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_Green == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiColors[1] = _a;
|
||||
aiColorsTypes[1] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_Blue == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiColors[2] = _a;
|
||||
aiColorsTypes[2] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_Alpha == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiColors[3] = _a;
|
||||
aiColorsTypes[3] = (*a).eType;
|
||||
}
|
||||
// Texture coordinates
|
||||
else if (PLY::EST_UTextureCoord == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiTexcoord[0] = _a;
|
||||
aiTexcoordTypes[0] = (*a).eType;
|
||||
}
|
||||
else if (PLY::EST_VTextureCoord == (*a).Semantic)
|
||||
{
|
||||
cnt++;
|
||||
aiTexcoord[1] = _a;
|
||||
aiTexcoordTypes[1] = (*a).eType;
|
||||
}
|
||||
}
|
||||
// check whether we have a valid source for the vertex data
|
||||
if (0 != cnt) {
|
||||
// Position
|
||||
aiVector3D vOut;
|
||||
if (0xFFFFFFFF != aiPositions[0]) {
|
||||
vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
|
||||
}
|
||||
|
||||
// check whether we have a valid source for the vertex data
|
||||
if (0 != cnt)
|
||||
{
|
||||
// Position
|
||||
aiVector3D vOut;
|
||||
if (0xFFFFFFFF != aiPositions[0])
|
||||
{
|
||||
vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
|
||||
}
|
||||
if (0xFFFFFFFF != aiPositions[1]) {
|
||||
vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiPositions[1])
|
||||
{
|
||||
vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
|
||||
}
|
||||
if (0xFFFFFFFF != aiPositions[2]) {
|
||||
vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiPositions[2])
|
||||
{
|
||||
vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
|
||||
}
|
||||
// Normals
|
||||
aiVector3D nOut;
|
||||
bool haveNormal = false;
|
||||
if (0xFFFFFFFF != aiNormal[0]) {
|
||||
nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
|
||||
haveNormal = true;
|
||||
}
|
||||
|
||||
// Normals
|
||||
aiVector3D nOut;
|
||||
bool haveNormal = false;
|
||||
if (0xFFFFFFFF != aiNormal[0])
|
||||
{
|
||||
nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
|
||||
haveNormal = true;
|
||||
}
|
||||
if (0xFFFFFFFF != aiNormal[1]) {
|
||||
nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
|
||||
haveNormal = true;
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiNormal[1])
|
||||
{
|
||||
nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
|
||||
haveNormal = true;
|
||||
}
|
||||
if (0xFFFFFFFF != aiNormal[2]) {
|
||||
nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
|
||||
haveNormal = true;
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiNormal[2])
|
||||
{
|
||||
nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
|
||||
haveNormal = true;
|
||||
}
|
||||
//Colors
|
||||
aiColor4D cOut;
|
||||
bool haveColor = false;
|
||||
if (0xFFFFFFFF != aiColors[0]) {
|
||||
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[0]).avList.front(), aiColorsTypes[0]);
|
||||
haveColor = true;
|
||||
}
|
||||
|
||||
//Colors
|
||||
aiColor4D cOut;
|
||||
bool haveColor = false;
|
||||
if (0xFFFFFFFF != aiColors[0])
|
||||
{
|
||||
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[0]).avList.front(), aiColorsTypes[0]);
|
||||
haveColor = true;
|
||||
}
|
||||
if (0xFFFFFFFF != aiColors[1]) {
|
||||
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[1]).avList.front(), aiColorsTypes[1]);
|
||||
haveColor = true;
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiColors[1])
|
||||
{
|
||||
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[1]).avList.front(), aiColorsTypes[1]);
|
||||
haveColor = true;
|
||||
}
|
||||
if (0xFFFFFFFF != aiColors[2]) {
|
||||
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[2]).avList.front(), aiColorsTypes[2]);
|
||||
haveColor = true;
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiColors[2])
|
||||
{
|
||||
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[2]).avList.front(), aiColorsTypes[2]);
|
||||
haveColor = true;
|
||||
}
|
||||
// assume 1.0 for the alpha channel ifit is not set
|
||||
if (0xFFFFFFFF == aiColors[3]) {
|
||||
cOut.a = 1.0;
|
||||
} else {
|
||||
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[3]).avList.front(), aiColorsTypes[3]);
|
||||
|
||||
// assume 1.0 for the alpha channel ifit is not set
|
||||
if (0xFFFFFFFF == aiColors[3])
|
||||
{
|
||||
cOut.a = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
|
||||
aiColors[3]).avList.front(), aiColorsTypes[3]);
|
||||
haveColor = true;
|
||||
}
|
||||
|
||||
haveColor = true;
|
||||
}
|
||||
//Texture coordinates
|
||||
aiVector3D tOut;
|
||||
tOut.z = 0;
|
||||
bool haveTextureCoords = false;
|
||||
if (0xFFFFFFFF != aiTexcoord[0]) {
|
||||
tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
|
||||
haveTextureCoords = true;
|
||||
}
|
||||
|
||||
//Texture coordinates
|
||||
aiVector3D tOut;
|
||||
tOut.z = 0;
|
||||
bool haveTextureCoords = false;
|
||||
if (0xFFFFFFFF != aiTexcoord[0])
|
||||
{
|
||||
tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
|
||||
haveTextureCoords = true;
|
||||
}
|
||||
if (0xFFFFFFFF != aiTexcoord[1]) {
|
||||
tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
|
||||
haveTextureCoords = true;
|
||||
}
|
||||
|
||||
if (0xFFFFFFFF != aiTexcoord[1])
|
||||
{
|
||||
tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
|
||||
GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
|
||||
haveTextureCoords = true;
|
||||
}
|
||||
//create aiMesh if needed
|
||||
if ( nullptr == mGeneratedMesh ) {
|
||||
mGeneratedMesh = new aiMesh();
|
||||
mGeneratedMesh->mMaterialIndex = 0;
|
||||
}
|
||||
|
||||
//create aiMesh if needed
|
||||
if (mGeneratedMesh == NULL)
|
||||
{
|
||||
mGeneratedMesh = new aiMesh();
|
||||
mGeneratedMesh->mMaterialIndex = 0;
|
||||
}
|
||||
if (nullptr == mGeneratedMesh->mVertices) {
|
||||
mGeneratedMesh->mNumVertices = pcElement->NumOccur;
|
||||
mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
}
|
||||
|
||||
if (mGeneratedMesh->mVertices == NULL)
|
||||
{
|
||||
mGeneratedMesh->mNumVertices = pcElement->NumOccur;
|
||||
mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
}
|
||||
mGeneratedMesh->mVertices[pos] = vOut;
|
||||
|
||||
mGeneratedMesh->mVertices[pos] = vOut;
|
||||
if (haveNormal) {
|
||||
if (nullptr == mGeneratedMesh->mNormals)
|
||||
mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
mGeneratedMesh->mNormals[pos] = nOut;
|
||||
}
|
||||
|
||||
if (haveNormal)
|
||||
{
|
||||
if (mGeneratedMesh->mNormals == NULL)
|
||||
mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
mGeneratedMesh->mNormals[pos] = nOut;
|
||||
}
|
||||
if (haveColor) {
|
||||
if (nullptr == mGeneratedMesh->mColors[0])
|
||||
mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
|
||||
mGeneratedMesh->mColors[0][pos] = cOut;
|
||||
}
|
||||
|
||||
if (haveColor)
|
||||
{
|
||||
if (mGeneratedMesh->mColors[0] == NULL)
|
||||
mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
|
||||
mGeneratedMesh->mColors[0][pos] = cOut;
|
||||
if (haveTextureCoords) {
|
||||
if (nullptr == mGeneratedMesh->mTextureCoords[0]) {
|
||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
}
|
||||
mGeneratedMesh->mTextureCoords[0][pos] = tOut;
|
||||
}
|
||||
}
|
||||
|
||||
if (haveTextureCoords)
|
||||
{
|
||||
if (mGeneratedMesh->mTextureCoords[0] == NULL)
|
||||
{
|
||||
mGeneratedMesh->mNumUVComponents[0] = 2;
|
||||
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
|
||||
}
|
||||
mGeneratedMesh->mTextureCoords[0][pos] = tOut;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -585,7 +539,7 @@ void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInst
|
|||
ai_assert(NULL != instElement);
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -618,7 +618,7 @@ bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pc
|
|||
}
|
||||
|
||||
streamBuffer.getNextBlock(buffer);
|
||||
unsigned int bufferSize = buffer.size();
|
||||
unsigned int bufferSize = static_cast<unsigned int>(buffer.size());
|
||||
const char* pCur = (char*)&buffer[0];
|
||||
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.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
|
||||
nbuffer.clear();
|
||||
bufferSize = buffer.size();
|
||||
bufferSize = static_cast<unsigned int>(buffer.size());
|
||||
pCur = (char*)&buffer[0];
|
||||
}
|
||||
else
|
||||
|
|
|
@ -104,7 +104,7 @@ unsigned int PretransformVertices::CountNodes( aiNode* pcNode )
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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.
|
||||
// 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]];
|
||||
ai_assert(0 != num_ref);
|
||||
--num_ref;
|
||||
// Save the name of the last mesh
|
||||
if (num_ref==0)
|
||||
{
|
||||
pcMeshOut->mName = pcMesh->mName;
|
||||
}
|
||||
|
||||
if (identity) {
|
||||
// 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
|
||||
// flat node graph with a root node and some level 1 children
|
||||
aiNode* newRoot = new aiNode();
|
||||
newRoot->mName = pScene->mRootNode->mName;
|
||||
delete pScene->mRootNode;
|
||||
pScene->mRootNode = new aiNode();
|
||||
pScene->mRootNode->mName.Set("<dummy_root>");
|
||||
pScene->mRootNode = newRoot;
|
||||
|
||||
if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
|
||||
{
|
||||
|
@ -646,7 +652,7 @@ void PretransformVertices::Execute( aiScene* pScene)
|
|||
{
|
||||
aiNode* pcNode = *nodes = new aiNode();
|
||||
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
|
||||
pcNode->mNumMeshes = 1;
|
||||
|
|
|
@ -52,21 +52,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <map>
|
||||
|
||||
namespace Assimp {
|
||||
namespace Profiling {
|
||||
|
||||
using namespace Formatter;
|
||||
namespace Profiling {
|
||||
|
||||
using namespace Formatter;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically
|
||||
* dumped to the log file.
|
||||
*/
|
||||
class Profiler
|
||||
{
|
||||
|
||||
class Profiler {
|
||||
public:
|
||||
|
||||
Profiler() {}
|
||||
Profiler() {
|
||||
// empty
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
@ -84,17 +82,17 @@ public:
|
|||
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"));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<std::string,std::chrono::time_point<std::chrono::system_clock>> RegionMap;
|
||||
RegionMap regions;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -39,14 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
|
||||
#include "Q3BSPZipArchive.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <assimp/ai_assert.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
@ -137,7 +133,6 @@ zlib_filefunc_def IOSystem2Unzip::get(IOSystem* pIOHandler) {
|
|||
return mapping;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ZipFile::ZipFile(size_t size) : m_Size(size) {
|
||||
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 <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#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.
|
||||
static aiString ReadString(StreamReaderLE* stream, uint32_t numWChars)
|
||||
{
|
||||
if ( 0 == numWChars ) {
|
||||
static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) {
|
||||
if ( nullptr == stream || 0 == numWChars ) {
|
||||
static const aiString empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
// Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
|
||||
//UTF16* temp = new UTF16[numWChars];
|
||||
std::vector<unsigned char> str;
|
||||
str.reserve(numWChars * 4 + 1);
|
||||
//unsigned char* str = new unsigned char[numWChars * 4 + 1];
|
||||
uint16_t *temp = new uint16_t[numWChars];
|
||||
for (uint32_t n=0;n<numWChars;n++)
|
||||
temp[n] = stream->GetU2();
|
||||
str.reserve( numWChars * 4 + 1 );
|
||||
uint16_t *temp = new uint16_t[ numWChars ];
|
||||
for ( uint32_t n = 0; n < numWChars; ++n ) {
|
||||
temp[ n ] = stream->GetU2();
|
||||
}
|
||||
|
||||
// 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.
|
||||
aiString result = aiString((const char *)&str[0]);
|
||||
//delete[] str;
|
||||
delete[] temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -223,26 +216,26 @@ SIBImporter::~SIBImporter() {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiImporterDesc* SIBImporter::GetInfo () const
|
||||
{
|
||||
const aiImporterDesc* SIBImporter::GetInfo () const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count)
|
||||
{
|
||||
mesh->pos.resize(count);
|
||||
static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) {
|
||||
if ( nullptr == mesh || nullptr == stream ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t n=0;n<count;n++) {
|
||||
mesh->pos[n].x = stream->GetF4();
|
||||
mesh->pos[n].y = stream->GetF4();
|
||||
mesh->pos[n].z = stream->GetF4();
|
||||
mesh->pos.resize(count);
|
||||
for ( uint32_t n=0; n<count; ++n ) {
|
||||
mesh->pos[ n ].x = 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)
|
||||
{
|
||||
uint32_t version = stream->GetU4();
|
||||
if ( version != 1 ) {
|
||||
if ( version < 1 || version > 2 ) {
|
||||
throw DeadlyImportError( "SIB: Unsupported file version." );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -450,7 +450,9 @@ void SMDImporter::CreateOutputMeshes()
|
|||
// add bone child nodes
|
||||
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 ...
|
||||
for (unsigned int i = 0; i < asBones.size();++i)
|
||||
|
@ -648,12 +650,14 @@ void SMDImporter::ComputeAbsoluteBoneTransformations()
|
|||
// create output materials
|
||||
void SMDImporter::CreateOutputMaterials()
|
||||
{
|
||||
ai_assert( nullptr != pScene );
|
||||
|
||||
pScene->mNumMaterials = (unsigned int)aszTextures.size();
|
||||
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();
|
||||
ai_assert( nullptr != pcMat );
|
||||
pScene->mMaterials[iMat] = pcMat;
|
||||
|
||||
aiString szName;
|
||||
|
|
|
@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "time.h"
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <stdio.h>
|
||||
#include "ScenePrivate.h"
|
||||
|
||||
|
@ -757,7 +758,7 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// 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 end)
|
||||
{
|
||||
|
@ -772,8 +773,14 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
|||
aiMesh* out = *_out = new aiMesh();
|
||||
out->mMaterialIndex = (*begin)->mMaterialIndex;
|
||||
|
||||
std::string name;
|
||||
// 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->mNumFaces += (*it)->mNumFaces;
|
||||
out->mNumBones += (*it)->mNumBones;
|
||||
|
@ -781,6 +788,7 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
|||
// combine primitive type flags
|
||||
out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
|
||||
}
|
||||
out->mName.Set( name.c_str() );
|
||||
|
||||
if (out->mNumVertices) {
|
||||
aiVector3D* pv2;
|
||||
|
@ -789,7 +797,7 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
|||
if ((**begin).HasPositions()) {
|
||||
|
||||
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) {
|
||||
::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D));
|
||||
}
|
||||
|
@ -809,7 +817,7 @@ void SceneCombiner::MergeMeshes(aiMesh** _out,unsigned int /*flags*/,
|
|||
pv2 += (*it)->mNumVertices;
|
||||
}
|
||||
}
|
||||
// copy tangents and bitangents
|
||||
// copy tangents and bi-tangents
|
||||
if ((**begin).HasTangentsAndBitangents()) {
|
||||
|
||||
pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
|
||||
|
|
|
@ -291,15 +291,11 @@ private:
|
|||
throw DeadlyImportError("End of file or stream limit was reached");
|
||||
}
|
||||
|
||||
///*#ifdef __arm__
|
||||
T f;
|
||||
::memcpy (&f, current, sizeof(T));
|
||||
//#else*/
|
||||
// T f = *((const T*)current);
|
||||
//#endif
|
||||
Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
|
||||
|
||||
Intern::Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
|
||||
current += sizeof(T);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
|||
DefaultLogger::get()->debug("UNREAL: uc file is " + uc_path);
|
||||
|
||||
// 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)
|
||||
throw DeadlyImportError("UNREAL: Unable to open _d file");
|
||||
StreamReaderLE d_reader(pIOHandler->Open(d_path));
|
||||
|
@ -203,7 +203,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
|||
d_reader.IncPtr(1);
|
||||
}
|
||||
|
||||
p = pIOHandler->Open(a_path);
|
||||
p.reset(pIOHandler->Open(a_path));
|
||||
if (!p)
|
||||
throw DeadlyImportError("UNREAL: Unable to open _a file");
|
||||
StreamReaderLE a_reader(pIOHandler->Open(a_path));
|
||||
|
|
|
@ -89,9 +89,7 @@ AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
|
|||
ai_assert(iLen > 0);
|
||||
|
||||
va_end(args);
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
ai_assert( false );
|
||||
#endif
|
||||
|
||||
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
|
||||
// mode to tell us that the JoinVerticesProcess might have
|
||||
// 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]])
|
||||
{
|
||||
ReportError("aiMesh::mVertices[%i] is referenced twice - second "
|
||||
"time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
|
||||
}
|
||||
}*/
|
||||
abRefList[face.mIndices[a]] = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,8 +107,7 @@ ASSIMP_API unsigned int aiGetCompileFlags () {
|
|||
#include "revision.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ASSIMP_API unsigned int aiGetVersionRevision ()
|
||||
{
|
||||
ASSIMP_API unsigned int aiGetVersionRevision() {
|
||||
return GitVersion;
|
||||
}
|
||||
|
||||
|
@ -133,8 +132,7 @@ ASSIMP_API aiScene::aiScene()
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
ASSIMP_API aiScene::~aiScene()
|
||||
{
|
||||
ASSIMP_API aiScene::~aiScene() {
|
||||
// delete all sub-objects recursively
|
||||
delete mRootNode;
|
||||
|
||||
|
@ -173,3 +171,4 @@ ASSIMP_API aiScene::~aiScene()
|
|||
|
||||
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
|
||||
}
|
||||
|
||||
|
|
|
@ -95,8 +95,8 @@ struct WordIterator: public std::iterator<std::input_iterator_tag, const char*>
|
|||
end_ = other.end_;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(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_; }
|
||||
bool operator!=(const WordIterator &other) const { return start_ != other.start_; }
|
||||
WordIterator &operator++() {
|
||||
start_ += strcspn(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 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( " "); }
|
||||
|
||||
/// 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:
|
||||
/// 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
|
||||
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 = {
|
||||
|
|
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:
|
||||
return 1;
|
||||
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")
|
||||
} 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);
|
||||
|
||||
AssetMetadata()
|
||||
: 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 <iomanip>
|
||||
|
||||
// Header files, Assimp
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
@ -128,6 +129,12 @@ namespace {
|
|||
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)
|
||||
{
|
||||
Value::MemberIterator it = val.FindMember(id);
|
||||
|
@ -309,7 +316,9 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
|||
}
|
||||
else { // Local file
|
||||
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) {
|
||||
bool ok = LoadFromStream(*file, byteLength);
|
||||
delete file;
|
||||
|
@ -332,7 +341,7 @@ inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseO
|
|||
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) {
|
||||
return false;
|
||||
|
@ -1228,13 +1237,21 @@ inline void Scene::Read(Value& obj, Asset& r)
|
|||
inline void AssetMetadata::Read(Document& doc)
|
||||
{
|
||||
// read the version, etc.
|
||||
int statedVersion = 0;
|
||||
if (Value* obj = FindObject(doc, "asset")) {
|
||||
ReadMember(*obj, "copyright", copyright);
|
||||
ReadMember(*obj, "generator", generator);
|
||||
|
||||
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")) {
|
||||
ReadMember(*profile, "api", this->profile.api);
|
||||
|
@ -1242,16 +1259,8 @@ inline void AssetMetadata::Read(Document& doc)
|
|||
}
|
||||
}
|
||||
|
||||
version = std::max(statedVersion, version);
|
||||
if (version == 0) {
|
||||
// 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);
|
||||
if (version.empty() || version[0] != '1') {
|
||||
throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1273,7 +1282,7 @@ inline void Asset::ReadBinaryHeader(IOStream& stream)
|
|||
}
|
||||
|
||||
AI_SWAP4(header.version);
|
||||
asset.version = header.version;
|
||||
asset.version = std::to_string(header.version);
|
||||
if (header.version != 1) {
|
||||
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
|
||||
}
|
||||
|
|
|
@ -606,13 +606,8 @@ namespace glTF {
|
|||
{
|
||||
Value asset;
|
||||
asset.SetObject();
|
||||
{
|
||||
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("version", Value(mAsset.asset.version, mAl).Move(), mAl);
|
||||
asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), 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());
|
||||
nodeRef->jointName = nodeRef->id;
|
||||
|
||||
unsigned int jointNamesIndex;
|
||||
unsigned int jointNamesIndex = 0;
|
||||
bool addJointToJointNames = true;
|
||||
for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
||||
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
||||
|
@ -469,11 +469,11 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
|
|||
float vertWeight = aib->mWeights[idx_weights].mWeight;
|
||||
|
||||
// A vertex can only have at most four joint weights. Ignore all others.
|
||||
if (jointsPerVertex[vertexId] > 3) {
|
||||
continue;
|
||||
if (jointsPerVertex[vertexId] > 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vertexJointData[vertexId][jointsPerVertex[vertexId]] = jointNamesIndex;
|
||||
vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
|
||||
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
|
||||
|
||||
jointsPerVertex[vertexId] += 1;
|
||||
|
@ -507,7 +507,7 @@ void glTFExporter::ExportMeshes()
|
|||
|
||||
// Variables needed for compression. BEGIN.
|
||||
// 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.
|
||||
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.
|
||||
|
@ -872,10 +872,10 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
|||
size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
|
||||
// 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()
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -888,7 +888,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
|||
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 ) {
|
||||
animRef->Parameters.translation = tranAccessor;
|
||||
}
|
||||
|
@ -904,7 +904,7 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
|||
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 ) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 ) {
|
||||
animRef->Parameters.rotation = rotAccessor;
|
||||
}
|
||||
|
@ -953,7 +953,7 @@ void glTFExporter::ExportAnimations()
|
|||
Ref<Animation> animRef = mAsset->animations.Create(name);
|
||||
|
||||
/******************* 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) {
|
||||
std::string channelType;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue