Merge remote-tracking branch 'upstream/master' into feature/collada-up_axis-api-improvements

pull/1499/head
Doug Stephen 2017-10-17 10:29:03 -05:00
commit 100fa76a90
234 changed files with 17830 additions and 3557 deletions

7
.gitattributes vendored
View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -71,7 +71,6 @@ class AssbinImporter : public BaseImporter
private:
bool shortened;
bool compressed;
protected:
public:
virtual bool CanRead(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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()) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -101,7 +101,6 @@ public:
return std::string(begin(),end());
}
public:
bool IsBinary() const {
return column == BINARY_MARKER;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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." );
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1108
code/glTF2Asset.h 100644

File diff suppressed because it is too large Load Diff

1319
code/glTF2Asset.inl 100644

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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("")
{
}
};

View File

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

View File

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

View File

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