commit
2dd393b800
|
@ -0,0 +1,22 @@
|
||||||
|
# See <http://EditorConfig.org> for details
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[CMakeLists.txt,*.cmake{,.in}]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.h.in]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.txt]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Declare files that will always have LF line endings on checkout.
|
||||||
|
*.cpp text eol=lf
|
||||||
|
*.h text eol=lf
|
||||||
|
*.c text eol=lf
|
||||||
|
*.hpp text eol=lf
|
||||||
|
*.txt text eol=lf
|
||||||
|
*.cmake text eol=lf
|
||||||
|
*.sh text eol=lf
|
|
@ -1,3 +1,4 @@
|
||||||
|
.idea
|
||||||
build
|
build
|
||||||
.project
|
.project
|
||||||
*.kdev4*
|
*.kdev4*
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
function generate()
|
||||||
|
{
|
||||||
|
cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $ANDROID ]; then
|
||||||
|
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
||||||
|
else
|
||||||
|
generate \
|
||||||
|
&& make \
|
||||||
|
&& sudo make install \
|
||||||
|
&& sudo ldconfig \
|
||||||
|
&& (cd test/unit; ../../bin/unit) \
|
||||||
|
&& (cd test/regression; chmod 755 run.py; ./run.py; \
|
||||||
|
chmod 755 result_checker.py; ./result_checker.py)
|
||||||
|
fi
|
16
.travis.yml
16
.travis.yml
|
@ -28,18 +28,4 @@ install:
|
||||||
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [ $ANDROID ]; then
|
- . ./.travis.sh
|
||||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni ;
|
|
||||||
else
|
|
||||||
cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD ;
|
|
||||||
make ;
|
|
||||||
sudo make install ;
|
|
||||||
sudo ldconfig ;
|
|
||||||
cd test/unit ;
|
|
||||||
../../bin/unit ;
|
|
||||||
cd ../regression ;
|
|
||||||
chmod 755 run.py ;
|
|
||||||
./run.py ;
|
|
||||||
chmod 755 result_checker.py ;
|
|
||||||
./result_checker.py;
|
|
||||||
fi
|
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
# Compute paths
|
# Compute paths
|
||||||
get_filename_component(FOOBAR_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
get_filename_component(FOOBAR_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||||
if(EXISTS "${FOOBAR_CMAKE_DIR}/CMakeCache.txt")
|
if(EXISTS "${FOOBAR_CMAKE_DIR}/CMakeCache.txt")
|
||||||
# In build tree
|
# In build tree
|
||||||
include("${FOOBAR_CMAKE_DIR}/FooBarBuildTreeSettings.cmake")
|
include("${FOOBAR_CMAKE_DIR}/FooBarBuildTreeSettings.cmake")
|
||||||
else()
|
else()
|
||||||
set(FOOBAR_INCLUDE_DIRS "${FOOBAR_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@")
|
set(FOOBAR_INCLUDE_DIRS "${FOOBAR_CMAKE_DIR}/@CONF_REL_INCLUDE_DIR@")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Our library dependencies (contains definitions for IMPORTED targets)
|
# Our library dependencies (contains definitions for IMPORTED targets)
|
||||||
|
|
315
CMakeLists.txt
315
CMakeLists.txt
|
@ -4,8 +4,8 @@ PROJECT( Assimp )
|
||||||
|
|
||||||
option(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
|
option(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
|
||||||
if(NOT BUILD_SHARED_LIBS)
|
if(NOT BUILD_SHARED_LIBS)
|
||||||
#set(CMAKE_EXE_LINKER_FLAGS "-static")
|
#set(CMAKE_EXE_LINKER_FLAGS "-static")
|
||||||
set(LINK_SEARCH_START_STATIC TRUE)
|
set(LINK_SEARCH_START_STATIC TRUE)
|
||||||
endif(NOT BUILD_SHARED_LIBS)
|
endif(NOT BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
# Define here the needed parameters
|
# Define here the needed parameters
|
||||||
|
@ -18,31 +18,32 @@ 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 )
|
||||||
|
|
||||||
# Get the current working branch
|
# Get the current working branch
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND git rev-parse --abbrev-ref HEAD
|
COMMAND git rev-parse --abbrev-ref HEAD
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_BRANCH
|
OUTPUT_VARIABLE GIT_BRANCH
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get the latest abbreviated commit hash of the working branch
|
# Get the latest abbreviated commit hash of the working branch
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND git log -1 --format=%h
|
COMMAND git log -1 --format=%h
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT GIT_COMMIT_HASH)
|
if(NOT GIT_COMMIT_HASH)
|
||||||
set(GIT_COMMIT_HASH 0)
|
set(GIT_COMMIT_HASH 0)
|
||||||
endif(NOT GIT_COMMIT_HASH)
|
endif(NOT GIT_COMMIT_HASH)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/revision.h.in
|
${CMAKE_CURRENT_SOURCE_DIR}/revision.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
@ -58,16 +59,16 @@ option(ASSIMP_ANDROID_JNIIOSYSTEM "Android JNI IOSystem support is active" OFF)
|
||||||
|
|
||||||
# Workaround to be able to deal with compiler bug "Too many sections" with mingw.
|
# Workaround to be able to deal with compiler bug "Too many sections" with mingw.
|
||||||
if( CMAKE_COMPILER_IS_MINGW )
|
if( CMAKE_COMPILER_IS_MINGW )
|
||||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_IFC_IMPORTER )
|
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_IFC_IMPORTER )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
|
if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # this is a very important switch and some libraries seem now to have it....
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # this is a very important switch and some libraries seem now to have it....
|
||||||
# hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall" )
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall" )
|
||||||
elseif(MSVC)
|
elseif(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
add_definitions(/MP)
|
add_definitions(/MP)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
INCLUDE (FindPkgConfig)
|
INCLUDE (FindPkgConfig)
|
||||||
|
@ -80,51 +81,51 @@ INCLUDE (PrecompiledHeader)
|
||||||
# source tree. During an out-of-source build, however, do not litter this
|
# source tree. During an out-of-source build, however, do not litter this
|
||||||
# directory, since that is probably what the user wanted to avoid.
|
# directory, since that is probably what the user wanted to avoid.
|
||||||
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||||
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
|
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
|
||||||
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
|
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
|
||||||
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
|
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
|
||||||
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||||
|
|
||||||
# Cache these to allow the user to override them manually.
|
# Cache these to allow the user to override them manually.
|
||||||
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE PATH
|
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE PATH
|
||||||
"Path the built library files are installed to." )
|
"Path the built library files are installed to." )
|
||||||
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
|
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
|
||||||
"Path the header files are installed to." )
|
"Path the header files are installed to." )
|
||||||
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
||||||
"Path the tool executables are installed to." )
|
"Path the tool executables are installed to." )
|
||||||
|
|
||||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall)
|
||||||
# add make uninstall capability
|
# add make uninstall capability
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||||
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Globally enable Boost resp. the Boost workaround – it is also needed by the
|
# Globally enable Boost resp. the Boost workaround – it is also needed by the
|
||||||
# tools which include the Assimp headers.
|
# tools which include the Assimp headers.
|
||||||
option ( ASSIMP_ENABLE_BOOST_WORKAROUND
|
option ( ASSIMP_ENABLE_BOOST_WORKAROUND
|
||||||
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
|
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
INCLUDE_DIRECTORIES( code/BoostWorkaround )
|
INCLUDE_DIRECTORIES( code/BoostWorkaround )
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_BOOST_WORKAROUND )
|
ADD_DEFINITIONS( -DASSIMP_BUILD_BOOST_WORKAROUND )
|
||||||
MESSAGE( STATUS "Building a non-boost version of Assimp." )
|
MESSAGE( STATUS "Building a non-boost version of Assimp." )
|
||||||
ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
SET( Boost_DETAILED_FAILURE_MSG ON )
|
SET( Boost_DETAILED_FAILURE_MSG ON )
|
||||||
SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57" "1.57.0" "1.58" "1.58.0" )
|
SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57" "1.57.0" "1.58" "1.58.0" )
|
||||||
FIND_PACKAGE( Boost )
|
FIND_PACKAGE( Boost )
|
||||||
IF ( NOT Boost_FOUND )
|
IF ( NOT Boost_FOUND )
|
||||||
MESSAGE( FATAL_ERROR
|
MESSAGE( FATAL_ERROR
|
||||||
"Boost libraries (http://www.boost.org/) not found. "
|
"Boost libraries (http://www.boost.org/) not found. "
|
||||||
"You can build a non-boost version of Assimp with slightly reduced "
|
"You can build a non-boost version of Assimp with slightly reduced "
|
||||||
"functionality by specifying -DASSIMP_ENABLE_BOOST_WORKAROUND=ON."
|
"functionality by specifying -DASSIMP_ENABLE_BOOST_WORKAROUND=ON."
|
||||||
)
|
)
|
||||||
ENDIF ( NOT Boost_FOUND )
|
ENDIF ( NOT Boost_FOUND )
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} )
|
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} )
|
||||||
ENDIF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
ENDIF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
||||||
|
|
||||||
# cmake configuration files
|
# cmake configuration files
|
||||||
|
@ -132,9 +133,11 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${C
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
|
|
||||||
|
FIND_PACKAGE( DirectX )
|
||||||
|
|
||||||
option ( ASSIMP_NO_EXPORT
|
option ( ASSIMP_NO_EXPORT
|
||||||
"Disable Assimp's export functionality."
|
"Disable Assimp's export functionality."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
if( CMAKE_COMPILER_IS_GNUCXX )
|
if( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
@ -145,134 +148,134 @@ endif( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
# Search for zlib
|
# Search for zlib
|
||||||
find_package(ZLIB)
|
find_package(ZLIB)
|
||||||
if( NOT ZLIB_FOUND )
|
if( NOT ZLIB_FOUND )
|
||||||
message(STATUS "compiling zlib from souces")
|
message(STATUS "compiling zlib from souces")
|
||||||
include(CheckIncludeFile)
|
include(CheckIncludeFile)
|
||||||
include(CheckTypeSize)
|
include(CheckTypeSize)
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
# compile from sources
|
# compile from sources
|
||||||
add_subdirectory(contrib/zlib)
|
add_subdirectory(contrib/zlib)
|
||||||
set(ZLIB_FOUND 1)
|
set(ZLIB_FOUND 1)
|
||||||
set(ZLIB_LIBRARIES zlibstatic)
|
set(ZLIB_LIBRARIES zlibstatic)
|
||||||
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
||||||
else(NOT ZLIB_FOUND)
|
else(NOT ZLIB_FOUND)
|
||||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
||||||
set(ZLIB_LIBRARIES_LINKED -lz)
|
set(ZLIB_LIBRARIES_LINKED -lz)
|
||||||
endif(NOT ZLIB_FOUND)
|
endif(NOT ZLIB_FOUND)
|
||||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||||
|
|
||||||
# Search for unzip
|
# Search for unzip
|
||||||
if (PKG_CONFIG_FOUND)
|
if (PKG_CONFIG_FOUND)
|
||||||
PKG_CHECK_MODULES(UNZIP minizip)
|
PKG_CHECK_MODULES(UNZIP minizip)
|
||||||
endif (PKG_CONFIG_FOUND)
|
endif (PKG_CONFIG_FOUND)
|
||||||
|
|
||||||
IF ( ASSIMP_NO_EXPORT )
|
IF ( ASSIMP_NO_EXPORT )
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
|
||||||
MESSAGE( STATUS "Build an import-only version of Assimp." )
|
MESSAGE( STATUS "Build an import-only version of Assimp." )
|
||||||
ENDIF( ASSIMP_NO_EXPORT )
|
ENDIF( ASSIMP_NO_EXPORT )
|
||||||
|
|
||||||
SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING
|
SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING
|
||||||
"describe the current architecture."
|
"describe the current architecture."
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
|
IF ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
|
||||||
ELSE ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
|
ELSE ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
|
||||||
ADD_DEFINITIONS ( -D'ASSIMP_BUILD_ARCHITECTURE="${ASSIMP_BUILD_ARCHITECTURE}"' )
|
ADD_DEFINITIONS ( -D'ASSIMP_BUILD_ARCHITECTURE="${ASSIMP_BUILD_ARCHITECTURE}"' )
|
||||||
ENDIF ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
|
ENDIF ( ASSIMP_BUILD_ARCHITECTURE STREQUAL "")
|
||||||
|
|
||||||
# ${CMAKE_GENERATOR}
|
# ${CMAKE_GENERATOR}
|
||||||
SET ( ASSIMP_BUILD_COMPILER "" CACHE STRING
|
SET ( ASSIMP_BUILD_COMPILER "" CACHE STRING
|
||||||
"describe the current compiler."
|
"describe the current compiler."
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
IF ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
||||||
ELSE ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
ELSE ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
||||||
ADD_DEFINITIONS ( -D'ASSIMP_BUILD_COMPILER="${ASSIMP_BUILD_COMPILER}"' )
|
ADD_DEFINITIONS ( -D'ASSIMP_BUILD_COMPILER="${ASSIMP_BUILD_COMPILER}"' )
|
||||||
ENDIF ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
ENDIF ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
||||||
|
|
||||||
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
||||||
|
|
||||||
|
|
||||||
SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
|
SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
|
||||||
"Build the C4D importer, which relies on the non-free Melange SDK."
|
"Build the C4D importer, which relies on the non-free Melange SDK."
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
IF ( MSVC )
|
IF ( MSVC )
|
||||||
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/_melange/includes")
|
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/_melange/includes")
|
||||||
|
|
||||||
# pick the correct prebuilt library
|
# pick the correct prebuilt library
|
||||||
IF(MSVC11)
|
IF(MSVC11)
|
||||||
SET(C4D_LIB_POSTFIX "_2012md")
|
SET(C4D_LIB_POSTFIX "_2012md")
|
||||||
ELSEIF(MSVC10)
|
ELSEIF(MSVC10)
|
||||||
SET(C4D_LIB_POSTFIX "_2010md")
|
SET(C4D_LIB_POSTFIX "_2010md")
|
||||||
ELSEIF(MSVC90)
|
ELSEIF(MSVC90)
|
||||||
SET(C4D_LIB_POSTFIX "_2008md")
|
SET(C4D_LIB_POSTFIX "_2008md")
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE( FATAL_ERROR
|
MESSAGE( FATAL_ERROR
|
||||||
"C4D is currently only supported with MSVC 9, 10, 11"
|
"C4D is currently only supported with MSVC 9, 10, 11"
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(CMAKE_CL_64)
|
IF(CMAKE_CL_64)
|
||||||
SET(C4D_LIB_ARCH_POSTFIX "_x64")
|
SET(C4D_LIB_ARCH_POSTFIX "_x64")
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(C4D_LIB_ARCH_POSTFIX "")
|
SET(C4D_LIB_ARCH_POSTFIX "")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/_melange/lib/WIN")
|
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/_melange/lib/WIN")
|
||||||
|
|
||||||
SET(C4D_DEBUG_LIBRARY "${C4D_LIB_BASE_PATH}/debug/_melange_lib${C4D_LIB_ARCH_POSTFIX}${C4D_LIB_POSTFIX}.lib")
|
SET(C4D_DEBUG_LIBRARY "${C4D_LIB_BASE_PATH}/debug/_melange_lib${C4D_LIB_ARCH_POSTFIX}${C4D_LIB_POSTFIX}.lib")
|
||||||
SET(C4D_RELEASE_LIBRARY "${C4D_LIB_BASE_PATH}/release/_melange_lib${C4D_LIB_ARCH_POSTFIX}${C4D_LIB_POSTFIX}.lib")
|
SET(C4D_RELEASE_LIBRARY "${C4D_LIB_BASE_PATH}/release/_melange_lib${C4D_LIB_ARCH_POSTFIX}${C4D_LIB_POSTFIX}.lib")
|
||||||
|
|
||||||
# winsock and winmm are necessary dependencies of melange (this is undocumented, but true.)
|
# winsock and winmm are necessary dependencies of melange (this is undocumented, but true.)
|
||||||
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
|
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
MESSAGE( FATAL_ERROR
|
MESSAGE( FATAL_ERROR
|
||||||
"C4D is currently only available on Windows with melange SDK installed in contrib/Melange"
|
"C4D is currently only available on Windows with melange SDK installed in contrib/Melange"
|
||||||
)
|
)
|
||||||
ENDIF ( MSVC )
|
ENDIF ( MSVC )
|
||||||
else (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
else (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||||
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( code/ )
|
ADD_SUBDIRECTORY( code/ )
|
||||||
option ( ASSIMP_BUILD_ASSIMP_TOOLS
|
option ( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
"If the supplementary tools for Assimp are built in addition to the library."
|
"If the supplementary tools for Assimp are built in addition to the library."
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
IF ( WIN32 )
|
IF ( WIN32 AND DirectX_FOUND )
|
||||||
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
||||||
ENDIF ( WIN32 )
|
ENDIF ( WIN32 AND DirectX_FOUND )
|
||||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
|
|
||||||
option ( ASSIMP_BUILD_SAMPLES
|
option ( ASSIMP_BUILD_SAMPLES
|
||||||
"If the official samples are built as well (needs Glut)."
|
"If the official samples are built as well (needs Glut)."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_SAMPLES)
|
IF ( ASSIMP_BUILD_SAMPLES)
|
||||||
IF ( WIN32 )
|
IF ( WIN32 )
|
||||||
ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ )
|
ADD_SUBDIRECTORY( samples/SimpleTexturedOpenGL/ )
|
||||||
ENDIF ( WIN32 )
|
ENDIF ( WIN32 )
|
||||||
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
||||||
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
||||||
|
|
||||||
option ( ASSIMP_BUILD_TESTS
|
option ( ASSIMP_BUILD_TESTS
|
||||||
"If the test suite for Assimp is built in addition to the library."
|
"If the test suite for Assimp is built in addition to the library."
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_TESTS )
|
IF ( ASSIMP_BUILD_TESTS )
|
||||||
ADD_SUBDIRECTORY( test/ )
|
ADD_SUBDIRECTORY( test/ )
|
||||||
ENDIF ( ASSIMP_BUILD_TESTS )
|
ENDIF ( ASSIMP_BUILD_TESTS )
|
||||||
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
option ( ASSIMP_INSTALL_PDB
|
option ( ASSIMP_INSTALL_PDB
|
||||||
"Install MSVC debug files."
|
"Install MSVC debug files."
|
||||||
ON
|
ON
|
||||||
)
|
)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
|
|
||||||
# Generate a pkg-config .pc for the Assimp library.
|
# Generate a pkg-config .pc for the Assimp library.
|
||||||
|
@ -280,50 +283,50 @@ CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assi
|
||||||
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
|
|
||||||
if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
|
if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
|
||||||
# Packing information
|
# Packing information
|
||||||
set(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}")
|
set(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
|
set(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
|
||||||
set(CPACK_PACKAGE_VENDOR "http://assimp.sourceforge.net/")
|
set(CPACK_PACKAGE_VENDOR "http://assimp.sourceforge.net/")
|
||||||
set(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
|
set(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY " - Open Asset Import Library ${ASSIMP_VERSION}")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY " - Open Asset Import Library ${ASSIMP_VERSION}")
|
||||||
set(CPACK_PACKAGE_VERSION "${ASSIMP_VERSION}.${ASSIMP_PACKAGE_VERSION}" )
|
set(CPACK_PACKAGE_VERSION "${ASSIMP_VERSION}.${ASSIMP_PACKAGE_VERSION}" )
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "${ASSIMP_VERSION_MAJOR}")
|
set(CPACK_PACKAGE_VERSION_MAJOR "${ASSIMP_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "${ASSIMP_VERSION_MINOR}")
|
set(CPACK_PACKAGE_VERSION_MINOR "${ASSIMP_VERSION_MINOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "${ASSIMP_VERSION_PATCH}")
|
set(CPACK_PACKAGE_VERSION_PATCH "${ASSIMP_VERSION_PATCH}")
|
||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
|
|
||||||
string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER")
|
string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER")
|
||||||
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER")
|
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER")
|
||||||
|
|
||||||
set(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
|
set(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
|
||||||
set(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" )
|
set(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" )
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP_COMPONENT_UPPER}_DISPLAY_NAME "libraries")
|
set(CPACK_COMPONENT_${LIBASSIMP_COMPONENT_UPPER}_DISPLAY_NAME "libraries")
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DISPLAY_NAME "common headers and installs")
|
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DISPLAY_NAME "common headers and installs")
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DEPENDS $ "{LIBASSIMP_COMPONENT}" )
|
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DEPENDS $ "{LIBASSIMP_COMPONENT}" )
|
||||||
set(CPACK_COMPONENT_ASSIMP-DEV_DISPLAY_NAME "${CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT}_DISPLAY_NAME}" )
|
set(CPACK_COMPONENT_ASSIMP-DEV_DISPLAY_NAME "${CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT}_DISPLAY_NAME}" )
|
||||||
set(CPACK_COMPONENT_ASSIMP-DEV_DEPENDS "${LIBASSIMP-DEV_COMPONENT}" )
|
set(CPACK_COMPONENT_ASSIMP-DEV_DEPENDS "${LIBASSIMP-DEV_COMPONENT}" )
|
||||||
set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake libboost-dev libboost-thread-dev libboost-math-dev zlib1g-dev pkg-config)
|
set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake libboost-dev libboost-thread-dev libboost-math-dev zlib1g-dev pkg-config)
|
||||||
|
|
||||||
# debian
|
# debian
|
||||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||||
set(CPACK_DEBIAN_CMAKE_OPTIONS "-DBUILD_ASSIMP_SAMPLES:BOOL=${ASSIMP_BUILD_SAMPLES}")
|
set(CPACK_DEBIAN_CMAKE_OPTIONS "-DBUILD_ASSIMP_SAMPLES:BOOL=${ASSIMP_BUILD_SAMPLES}")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
set(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
set(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
||||||
set(CPACK_DEBIAN_PACKAGE_NAME "assimp")
|
set(CPACK_DEBIAN_PACKAGE_NAME "assimp")
|
||||||
set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging)
|
set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging)
|
||||||
set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
||||||
set(CPACK_DEBIAN_CHANGELOG)
|
set(CPACK_DEBIAN_CHANGELOG)
|
||||||
execute_process(COMMAND lsb_release -is
|
execute_process(COMMAND lsb_release -is
|
||||||
OUTPUT_VARIABLE _lsb_distribution OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_VARIABLE _lsb_distribution OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
RESULT_VARIABLE _lsb_release_failed)
|
RESULT_VARIABLE _lsb_release_failed)
|
||||||
set(CPACK_DEBIAN_DISTRIBUTION_NAME ${_lsb_distribution} CACHE STRING "Name of the distrubiton")
|
set(CPACK_DEBIAN_DISTRIBUTION_NAME ${_lsb_distribution} CACHE STRING "Name of the distrubiton")
|
||||||
string(TOLOWER ${CPACK_DEBIAN_DISTRIBUTION_NAME} CPACK_DEBIAN_DISTRIBUTION_NAME)
|
string(TOLOWER ${CPACK_DEBIAN_DISTRIBUTION_NAME} CPACK_DEBIAN_DISTRIBUTION_NAME)
|
||||||
if( ${CPACK_DEBIAN_DISTRIBUTION_NAME} STREQUAL "ubuntu" )
|
if( ${CPACK_DEBIAN_DISTRIBUTION_NAME} STREQUAL "ubuntu" )
|
||||||
set(CPACK_DEBIAN_DISTRIBUTION_RELEASES lucid maverick natty oneiric precise CACHE STRING "Release code-names of the distrubiton release")
|
set(CPACK_DEBIAN_DISTRIBUTION_RELEASES lucid maverick natty oneiric precise CACHE STRING "Release code-names of the distrubiton release")
|
||||||
endif()
|
endif()
|
||||||
set(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources")
|
set(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources")
|
||||||
include(CPack)
|
include(CPack)
|
||||||
include(DebSourcePPA)
|
include(DebSourcePPA)
|
||||||
endif()
|
endif()
|
||||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
11
Readme.md
11
Readme.md
|
@ -7,9 +7,15 @@ APIs are provided for C and C++. There are various bindings to other languages (
|
||||||
|
|
||||||
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||||
|
|
||||||
This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status is:
|
This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories.
|
||||||
|
The current build status is:
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
Linux [![Linux Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
||||||
|
Windows [![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
|
||||||
|
Coverity<a href="https://scan.coverity.com/projects/5607">
|
||||||
|
<img alt="Coverity Scan Build Status"
|
||||||
|
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
||||||
|
|
||||||
|
@ -36,6 +42,7 @@ __Importers__:
|
||||||
- STL
|
- STL
|
||||||
- X
|
- X
|
||||||
- OBJ
|
- OBJ
|
||||||
|
- OpenGEX
|
||||||
- SMD
|
- SMD
|
||||||
- LWO
|
- LWO
|
||||||
- LXO
|
- LXO
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# AppVeyor file
|
||||||
|
# http://www.appveyor.com/docs/appveyor-yml
|
||||||
|
|
||||||
|
# Operating system (build VM template)
|
||||||
|
os: Previous Windows Server 2012 R2 # using previous worker images since default worker has problem installing DART-Prerequisites.msi
|
||||||
|
|
||||||
|
# clone directory
|
||||||
|
clone_folder: c:\projects\assimp
|
||||||
|
|
||||||
|
# branches to build
|
||||||
|
branches:
|
||||||
|
# whitelist
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
platform: x64
|
||||||
|
configuration: Release
|
||||||
|
|
||||||
|
build:
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cd c:\projects\assimp
|
||||||
|
- cmake CMakeLists.txt -G "Visual Studio 11"
|
||||||
|
- msbuild /m /p:Configuration=Release /p:Platform="Win32" Assimp.sln
|
|
@ -2,30 +2,30 @@ find_package(Threads REQUIRED)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
if(MSYS OR MINGW)
|
if(MSYS OR MINGW)
|
||||||
set(DISABLE_PTHREADS ON)
|
set(DISABLE_PTHREADS ON)
|
||||||
else()
|
else()
|
||||||
set(DISABLE_PTHREADS OFF)
|
set(DISABLE_PTHREADS OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(RELEASE_LIB_DIR ReleaseLibs)
|
set(RELEASE_LIB_DIR ReleaseLibs)
|
||||||
set(DEBUG_LIB_DIR DebugLibs)
|
set(DEBUG_LIB_DIR DebugLibs)
|
||||||
else()
|
else()
|
||||||
set(RELEASE_LIB_DIR "")
|
set(RELEASE_LIB_DIR "")
|
||||||
set(DEBUG_LIB_DIR "")
|
set(DEBUG_LIB_DIR "")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GTEST_CMAKE_ARGS
|
set(GTEST_CMAKE_ARGS
|
||||||
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
|
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
|
||||||
"-Dgtest_force_shared_crt=ON"
|
"-Dgtest_force_shared_crt=ON"
|
||||||
"-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}")
|
"-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}")
|
||||||
set(GTEST_RELEASE_LIB_DIR "")
|
set(GTEST_RELEASE_LIB_DIR "")
|
||||||
set(GTEST_DEBUGLIB_DIR "")
|
set(GTEST_DEBUGLIB_DIR "")
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(GTEST_CMAKE_ARGS ${GTEST_CMAKE_ARGS}
|
set(GTEST_CMAKE_ARGS ${GTEST_CMAKE_ARGS}
|
||||||
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${DEBUG_LIB_DIR}"
|
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${DEBUG_LIB_DIR}"
|
||||||
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${RELEASE_LIB_DIR}")
|
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${RELEASE_LIB_DIR}")
|
||||||
set(GTEST_LIB_DIR)
|
set(GTEST_LIB_DIR)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
|
set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
|
||||||
|
@ -33,40 +33,40 @@ set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
|
||||||
# try to find git - if found, setup gtest
|
# try to find git - if found, setup gtest
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
if(NOT GIT_FOUND)
|
if(NOT GIT_FOUND)
|
||||||
set(AddGTest_FOUND false CACHE BOOL "Was gtest setup correctly?")
|
set(AddGTest_FOUND false CACHE BOOL "Was gtest setup correctly?")
|
||||||
else(NOT GIT_FOUND)
|
else(NOT GIT_FOUND)
|
||||||
set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?")
|
set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?")
|
||||||
|
|
||||||
ExternalProject_Add(gtest
|
ExternalProject_Add(gtest
|
||||||
GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
|
GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
|
||||||
TIMEOUT 10
|
TIMEOUT 10
|
||||||
PREFIX "${GTEST_PREFIX}"
|
PREFIX "${GTEST_PREFIX}"
|
||||||
CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
|
CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
|
||||||
LOG_DOWNLOAD ON
|
LOG_DOWNLOAD ON
|
||||||
LOG_CONFIGURE ON
|
LOG_CONFIGURE ON
|
||||||
LOG_BUILD ON
|
LOG_BUILD ON
|
||||||
# Disable install
|
# Disable install
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
|
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
|
||||||
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||||
set(GTEST_LOCATION "${GTEST_PREFIX}/src/gtest-build")
|
set(GTEST_LOCATION "${GTEST_PREFIX}/src/gtest-build")
|
||||||
set(GTEST_DEBUG_LIBRARIES
|
set(GTEST_DEBUG_LIBRARIES
|
||||||
"${GTEST_LOCATION}/${DEBUG_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
|
"${GTEST_LOCATION}/${DEBUG_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
"${CMAKE_THREAD_LIBS_INIT}")
|
||||||
SET(GTEST_RELEASE_LIBRARIES
|
SET(GTEST_RELEASE_LIBRARIES
|
||||||
"${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
|
"${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
"${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
if(MSVC_VERSION EQUAL 1700)
|
if(MSVC_VERSION EQUAL 1700)
|
||||||
add_definitions(-D_VARIADIC_MAX=10)
|
add_definitions(-D_VARIADIC_MAX=10)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ExternalProject_Get_Property(gtest source_dir)
|
ExternalProject_Get_Property(gtest source_dir)
|
||||||
include_directories(${source_dir}/include)
|
include_directories(${source_dir}/include)
|
||||||
include_directories(${source_dir}/gtest/include)
|
include_directories(${source_dir}/gtest/include)
|
||||||
|
|
||||||
ExternalProject_Get_Property(gtest binary_dir)
|
ExternalProject_Get_Property(gtest binary_dir)
|
||||||
link_directories(${binary_dir})
|
link_directories(${binary_dir})
|
||||||
endif(NOT GIT_FOUND)
|
endif(NOT GIT_FOUND)
|
||||||
|
|
|
@ -35,13 +35,13 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||||
"C:/Program Files (x86)/Microsoft DirectX SDK*"
|
"C:/Program Files (x86)/Microsoft DirectX SDK*"
|
||||||
"C:/apps/Microsoft DirectX SDK*"
|
"C:/apps/Microsoft DirectX SDK*"
|
||||||
"C:/Program Files/Microsoft DirectX SDK*"
|
"C:/Program Files/Microsoft DirectX SDK*"
|
||||||
"$ENV{ProgramFiles}/Microsoft DirectX SDK*"
|
"$ENV{ProgramFiles}/Microsoft DirectX SDK*"
|
||||||
)
|
)
|
||||||
create_search_paths(DirectX)
|
create_search_paths(DirectX)
|
||||||
# redo search if prefix path changed
|
# redo search if prefix path changed
|
||||||
clear_if_changed(DirectX_PREFIX_PATH
|
clear_if_changed(DirectX_PREFIX_PATH
|
||||||
DirectX_LIBRARY
|
DirectX_LIBRARY
|
||||||
DirectX_INCLUDE_DIR
|
DirectX_INCLUDE_DIR
|
||||||
)
|
)
|
||||||
|
|
||||||
find_path(DirectX_INCLUDE_DIR NAMES d3d9.h HINTS ${DirectX_INC_SEARCH_PATH})
|
find_path(DirectX_INCLUDE_DIR NAMES d3d9.h HINTS ${DirectX_INC_SEARCH_PATH})
|
||||||
|
@ -78,23 +78,23 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||||
# look for D3D11 components
|
# look for D3D11 components
|
||||||
if (DirectX_FOUND)
|
if (DirectX_FOUND)
|
||||||
find_path(DirectX_D3D11_INCLUDE_DIR NAMES D3D11Shader.h HINTS ${DirectX_INC_SEARCH_PATH})
|
find_path(DirectX_D3D11_INCLUDE_DIR NAMES D3D11Shader.h HINTS ${DirectX_INC_SEARCH_PATH})
|
||||||
get_filename_component(DirectX_LIBRARY_DIR "${DirectX_LIBRARY}" PATH)
|
get_filename_component(DirectX_LIBRARY_DIR "${DirectX_LIBRARY}" PATH)
|
||||||
message(STATUS "DX lib dir: ${DirectX_LIBRARY_DIR}")
|
message(STATUS "DX lib dir: ${DirectX_LIBRARY_DIR}")
|
||||||
find_library(DirectX_D3D11_LIBRARY NAMES d3d11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
find_library(DirectX_D3D11_LIBRARY NAMES d3d11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
||||||
find_library(DirectX_D3DX11_LIBRARY NAMES d3dx11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
find_library(DirectX_D3DX11_LIBRARY NAMES d3dx11 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
|
||||||
if (DirectX_D3D11_INCLUDE_DIR AND DirectX_D3D11_LIBRARY)
|
if (DirectX_D3D11_INCLUDE_DIR AND DirectX_D3D11_LIBRARY)
|
||||||
set(DirectX_D3D11_FOUND TRUE)
|
set(DirectX_D3D11_FOUND TRUE)
|
||||||
set(DirectX_D3D11_INCLUDE_DIR ${DirectX_D3D11_INCLUDE_DIR})
|
set(DirectX_D3D11_INCLUDE_DIR ${DirectX_D3D11_INCLUDE_DIR})
|
||||||
set(DirectX_D3D11_LIBRARIES ${DirectX_D3D11_LIBRARIES}
|
set(DirectX_D3D11_LIBRARIES ${DirectX_D3D11_LIBRARIES}
|
||||||
${DirectX_D3D11_LIBRARY}
|
${DirectX_D3D11_LIBRARY}
|
||||||
${DirectX_D3DX11_LIBRARY}
|
${DirectX_D3DX11_LIBRARY}
|
||||||
${DirectX_DXGI_LIBRARY}
|
${DirectX_DXGI_LIBRARY}
|
||||||
${DirectX_DXERR_LIBRARY}
|
${DirectX_DXERR_LIBRARY}
|
||||||
${DirectX_DXGUID_LIBRARY}
|
${DirectX_DXGUID_LIBRARY}
|
||||||
${DirectX_D3DCOMPILER_LIBRARY}
|
${DirectX_D3DCOMPILER_LIBRARY}
|
||||||
)
|
)
|
||||||
endif ()
|
endif ()
|
||||||
mark_as_advanced(DirectX_D3D11_INCLUDE_DIR DirectX_D3D11_LIBRARY DirectX_D3DX11_LIBRARY)
|
mark_as_advanced(DirectX_D3D11_INCLUDE_DIR DirectX_D3D11_LIBRARY DirectX_D3DX11_LIBRARY)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
FIND_PATH(
|
FIND_PATH(
|
||||||
assimp_INCLUDE_DIRS
|
assimp_INCLUDE_DIRS
|
||||||
NAMES postprocess.h scene.h version.h config.h cimport.h
|
NAMES postprocess.h scene.h version.h config.h cimport.h
|
||||||
PATHS /usr/local/include/
|
PATHS /usr/local/include/
|
||||||
)
|
)
|
||||||
|
|
||||||
FIND_LIBRARY(
|
FIND_LIBRARY(
|
||||||
assimp_LIBRARIES
|
assimp_LIBRARIES
|
||||||
NAMES assimp
|
NAMES assimp
|
||||||
PATHS /usr/local/lib/
|
PATHS /usr/local/lib/
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
IF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
||||||
SET(assimp_FOUND TRUE)
|
SET(assimp_FOUND TRUE)
|
||||||
ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
||||||
|
|
||||||
IF (assimp_FOUND)
|
IF (assimp_FOUND)
|
||||||
IF (NOT assimp_FIND_QUIETLY)
|
IF (NOT assimp_FIND_QUIETLY)
|
||||||
MESSAGE(STATUS "Found asset importer library: ${assimp_LIBRARIES}")
|
MESSAGE(STATUS "Found asset importer library: ${assimp_LIBRARIES}")
|
||||||
ENDIF (NOT assimp_FIND_QUIETLY)
|
ENDIF (NOT assimp_FIND_QUIETLY)
|
||||||
ELSE (assimp_FOUND)
|
ELSE (assimp_FOUND)
|
||||||
IF (assimp_FIND_REQUIRED)
|
IF (assimp_FIND_REQUIRED)
|
||||||
MESSAGE(FATAL_ERROR "Could not find asset importer library")
|
MESSAGE(FATAL_ERROR "Could not find asset importer library")
|
||||||
ENDIF (assimp_FIND_REQUIRED)
|
ENDIF (assimp_FIND_REQUIRED)
|
||||||
ENDIF (assimp_FOUND)
|
ENDIF (assimp_FOUND)
|
||||||
|
|
|
@ -5,18 +5,18 @@ MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar
|
||||||
SET(Sources ${${SourcesVar}})
|
SET(Sources ${${SourcesVar}})
|
||||||
|
|
||||||
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
|
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
|
||||||
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
|
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
|
||||||
OBJECT_OUTPUTS "${PrecompiledBinary}")
|
OBJECT_OUTPUTS "${PrecompiledBinary}")
|
||||||
|
|
||||||
# Do not consider .c files
|
# Do not consider .c files
|
||||||
foreach(fname ${Sources})
|
foreach(fname ${Sources})
|
||||||
GET_FILENAME_COMPONENT(fext ${fname} EXT)
|
GET_FILENAME_COMPONENT(fext ${fname} EXT)
|
||||||
if(fext STREQUAL ".cpp")
|
if(fext STREQUAL ".cpp")
|
||||||
SET_SOURCE_FILES_PROPERTIES(${fname}
|
SET_SOURCE_FILES_PROPERTIES(${fname}
|
||||||
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
|
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledBinary}\" /FI\"${PrecompiledBinary}\" /Fp\"${PrecompiledBinary}\""
|
||||||
OBJECT_DEPENDS "${PrecompiledBinary}")
|
OBJECT_DEPENDS "${PrecompiledBinary}")
|
||||||
endif(fext STREQUAL ".cpp")
|
endif(fext STREQUAL ".cpp")
|
||||||
endforeach(fname)
|
endforeach(fname)
|
||||||
|
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
# Add precompiled header to SourcesVar
|
# Add precompiled header to SourcesVar
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# See <http://EditorConfig.org> for details
|
||||||
|
|
||||||
|
[*.{h,hpp,c,cpp}]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -53,129 +53,129 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Scope utility to write a 3DS file chunk.
|
// Scope utility to write a 3DS file chunk.
|
||||||
//
|
//
|
||||||
// Upon construction, the chunk header is written with the chunk type (flags)
|
// Upon construction, the chunk header is written with the chunk type (flags)
|
||||||
// filled out, but the chunk size left empty. Upon destruction, the correct chunk
|
// filled out, but the chunk size left empty. Upon destruction, the correct chunk
|
||||||
// size based on the then-position of the output stream cursor is filled in.
|
// size based on the then-position of the output stream cursor is filled in.
|
||||||
class ChunkWriter {
|
class ChunkWriter {
|
||||||
enum {
|
enum {
|
||||||
CHUNK_SIZE_NOT_SET = 0xdeadbeef
|
CHUNK_SIZE_NOT_SET = 0xdeadbeef
|
||||||
, SIZE_OFFSET = 2
|
, SIZE_OFFSET = 2
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type)
|
ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type)
|
||||||
: writer(writer)
|
: writer(writer)
|
||||||
{
|
{
|
||||||
chunk_start_pos = writer.GetCurrentPos();
|
chunk_start_pos = writer.GetCurrentPos();
|
||||||
writer.PutU2(chunk_type);
|
writer.PutU2(chunk_type);
|
||||||
writer.PutU4(CHUNK_SIZE_NOT_SET);
|
writer.PutU4(CHUNK_SIZE_NOT_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ChunkWriter() {
|
~ChunkWriter() {
|
||||||
std::size_t head_pos = writer.GetCurrentPos();
|
std::size_t head_pos = writer.GetCurrentPos();
|
||||||
|
|
||||||
ai_assert(head_pos > chunk_start_pos);
|
ai_assert(head_pos > chunk_start_pos);
|
||||||
const std::size_t chunk_size = head_pos - chunk_start_pos;
|
const std::size_t chunk_size = head_pos - chunk_start_pos;
|
||||||
|
|
||||||
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
|
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
|
||||||
writer.PutU4(chunk_size);
|
writer.PutU4(chunk_size);
|
||||||
writer.SetCurrentPos(head_pos);
|
writer.SetCurrentPos(head_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StreamWriterLE& writer;
|
StreamWriterLE& writer;
|
||||||
std::size_t chunk_start_pos;
|
std::size_t chunk_start_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Return an unique name for a given |mesh| attached to |node| that
|
// Return an unique name for a given |mesh| attached to |node| that
|
||||||
// preserves the mesh's given name if it has one. |index| is the index
|
// preserves the mesh's given name if it has one. |index| is the index
|
||||||
// of the mesh in |aiScene::mMeshes|.
|
// of the mesh in |aiScene::mMeshes|.
|
||||||
std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) {
|
std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) {
|
||||||
static const std::string underscore = "_";
|
static const std::string underscore = "_";
|
||||||
char postfix[10] = {0};
|
char postfix[10] = {0};
|
||||||
ASSIMP_itoa10(postfix, index);
|
ASSIMP_itoa10(postfix, index);
|
||||||
|
|
||||||
std::string result = node.mName.C_Str();
|
std::string result = node.mName.C_Str();
|
||||||
if (mesh.mName.length > 0) {
|
if (mesh.mName.length > 0) {
|
||||||
result += underscore + mesh.mName.C_Str();
|
result += underscore + mesh.mName.C_Str();
|
||||||
}
|
}
|
||||||
return result + underscore + postfix;
|
return result + underscore + postfix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an unique name for a given |mat| with original position |index|
|
// Return an unique name for a given |mat| with original position |index|
|
||||||
// in |aiScene::mMaterials|. The name preserves the original material
|
// in |aiScene::mMaterials|. The name preserves the original material
|
||||||
// name if possible.
|
// name if possible.
|
||||||
std::string GetMaterialName(const aiMaterial& mat, unsigned int index) {
|
std::string GetMaterialName(const aiMaterial& mat, unsigned int index) {
|
||||||
static const std::string underscore = "_";
|
static const std::string underscore = "_";
|
||||||
char postfix[10] = {0};
|
char postfix[10] = {0};
|
||||||
ASSIMP_itoa10(postfix, index);
|
ASSIMP_itoa10(postfix, index);
|
||||||
|
|
||||||
aiString mat_name;
|
aiString mat_name;
|
||||||
if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
|
if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
|
||||||
return mat_name.C_Str() + underscore + postfix;
|
return mat_name.C_Str() + underscore + postfix;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Material" + underscore + postfix;
|
return "Material" + underscore + postfix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect world transformations for each node
|
// Collect world transformations for each node
|
||||||
void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) {
|
void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) {
|
||||||
const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
|
const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
|
||||||
trafos[node] = parent * node->mTransformation;
|
trafos[node] = parent * node->mTransformation;
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
|
||||||
CollectTrafos(node->mChildren[i], trafos);
|
CollectTrafos(node->mChildren[i], trafos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a flat list of the meshes (by index) assigned to each node
|
// Generate a flat list of the meshes (by index) assigned to each node
|
||||||
void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) {
|
void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) {
|
||||||
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
|
||||||
meshes.insert(std::make_pair(node, node->mMeshes[i]));
|
meshes.insert(std::make_pair(node, node->mMeshes[i]));
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
|
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
|
||||||
CollectMeshes(node->mChildren[i], meshes);
|
CollectMeshes(node->mChildren[i], meshes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
||||||
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
||||||
if(!outfile) {
|
if(!outfile) {
|
||||||
throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
|
throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This extra copy should be avoided and all of this made a preprocess
|
// TODO: This extra copy should be avoided and all of this made a preprocess
|
||||||
// requirement of the 3DS exporter.
|
// requirement of the 3DS exporter.
|
||||||
//
|
//
|
||||||
// 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively.
|
// 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively.
|
||||||
// SplitLargeMeshes can do this, but it requires the correct limit to be set
|
// SplitLargeMeshes can do this, but it requires the correct limit to be set
|
||||||
// which is not possible with the current way of specifying preprocess steps
|
// which is not possible with the current way of specifying preprocess steps
|
||||||
// in |Exporter::ExportFormatEntry|.
|
// in |Exporter::ExportFormatEntry|.
|
||||||
aiScene* scenecopy_tmp;
|
aiScene* scenecopy_tmp;
|
||||||
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
||||||
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
|
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
|
||||||
|
|
||||||
SplitLargeMeshesProcess_Triangle tri_splitter;
|
SplitLargeMeshesProcess_Triangle tri_splitter;
|
||||||
tri_splitter.SetLimit(0xffff);
|
tri_splitter.SetLimit(0xffff);
|
||||||
tri_splitter.Execute(scenecopy.get());
|
tri_splitter.Execute(scenecopy.get());
|
||||||
|
|
||||||
SplitLargeMeshesProcess_Vertex vert_splitter;
|
SplitLargeMeshesProcess_Vertex vert_splitter;
|
||||||
vert_splitter.SetLimit(0xffff);
|
vert_splitter.SetLimit(0xffff);
|
||||||
vert_splitter.Execute(scenecopy.get());
|
vert_splitter.Execute(scenecopy.get());
|
||||||
|
|
||||||
// Invoke the actual exporter
|
// Invoke the actual exporter
|
||||||
Discreet3DSExporter exporter(outfile, scenecopy.get());
|
Discreet3DSExporter exporter(outfile, scenecopy.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
@ -185,379 +185,379 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, c
|
||||||
: scene(scene)
|
: scene(scene)
|
||||||
, writer(outfile)
|
, writer(outfile)
|
||||||
{
|
{
|
||||||
CollectTrafos(scene->mRootNode, trafos);
|
CollectTrafos(scene->mRootNode, trafos);
|
||||||
CollectMeshes(scene->mRootNode, meshes);
|
CollectMeshes(scene->mRootNode, meshes);
|
||||||
|
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN);
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
||||||
WriteMaterials();
|
WriteMaterials();
|
||||||
WriteMeshes();
|
WriteMeshes();
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
|
||||||
writer.PutF4(1.0f);
|
writer.PutF4(1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
|
||||||
WriteHierarchy(*scene->mRootNode, -1, -1);
|
WriteHierarchy(*scene->mRootNode, -1, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level)
|
int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level)
|
||||||
{
|
{
|
||||||
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
|
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
|
||||||
|
|
||||||
// Assimp node names are unique and distinct from all mesh-node
|
// Assimp node names are unique and distinct from all mesh-node
|
||||||
// names we generate; thus we can use them as-is
|
// names we generate; thus we can use them as-is
|
||||||
WriteString(node.mName);
|
WriteString(node.mName);
|
||||||
|
|
||||||
// Two unknown int16 values - it is even unclear if 0 is a safe value
|
// Two unknown int16 values - it is even unclear if 0 is a safe value
|
||||||
// but luckily importers do not know better either.
|
// but luckily importers do not know better either.
|
||||||
writer.PutI4(0);
|
writer.PutI4(0);
|
||||||
|
|
||||||
int16_t hierarchy_pos = static_cast<int16_t>(seq);
|
int16_t hierarchy_pos = static_cast<int16_t>(seq);
|
||||||
if (sibling_level != -1) {
|
if (sibling_level != -1) {
|
||||||
hierarchy_pos = sibling_level;
|
hierarchy_pos = sibling_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the hierarchy position
|
// Write the hierarchy position
|
||||||
writer.PutI2(hierarchy_pos);
|
writer.PutI2(hierarchy_pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: write transformation chunks
|
// TODO: write transformation chunks
|
||||||
|
|
||||||
++seq;
|
++seq;
|
||||||
sibling_level = seq;
|
sibling_level = seq;
|
||||||
|
|
||||||
// Write all children
|
// Write all children
|
||||||
for (unsigned int i = 0; i < node.mNumChildren; ++i) {
|
for (unsigned int i = 0; i < node.mNumChildren; ++i) {
|
||||||
seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level);
|
seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write all meshes as separate nodes to be able to reference the meshes by name
|
// Write all meshes as separate nodes to be able to reference the meshes by name
|
||||||
for (unsigned int i = 0; i < node.mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < node.mNumMeshes; ++i) {
|
||||||
const bool first_child = node.mNumChildren == 0 && i == 0;
|
const bool first_child = node.mNumChildren == 0 && i == 0;
|
||||||
|
|
||||||
const unsigned int mesh_idx = node.mMeshes[i];
|
const unsigned int mesh_idx = node.mMeshes[i];
|
||||||
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
|
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
|
||||||
|
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
|
||||||
WriteString(GetMeshName(mesh, mesh_idx, node));
|
WriteString(GetMeshName(mesh, mesh_idx, node));
|
||||||
|
|
||||||
writer.PutI4(0);
|
writer.PutI4(0);
|
||||||
writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level));
|
writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level));
|
||||||
++seq;
|
++seq;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteMaterials()
|
void Discreet3DSExporter::WriteMaterials()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
|
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
|
||||||
const aiMaterial& mat = *scene->mMaterials[i];
|
const aiMaterial& mat = *scene->mMaterials[i];
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME);
|
||||||
const std::string& name = GetMaterialName(mat, i);
|
const std::string& name = GetMaterialName(mat, i);
|
||||||
WriteString(name);
|
WriteString(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
aiColor3D color;
|
aiColor3D color;
|
||||||
if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
|
||||||
WriteColor(color);
|
WriteColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
|
||||||
WriteColor(color);
|
WriteColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
|
||||||
WriteColor(color);
|
WriteColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
|
||||||
WriteColor(color);
|
WriteColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
aiShadingMode shading_mode = aiShadingMode_Flat;
|
aiShadingMode shading_mode = aiShadingMode_Flat;
|
||||||
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
|
||||||
|
|
||||||
Discreet3DS::shadetype3ds shading_mode_out;
|
Discreet3DS::shadetype3ds shading_mode_out;
|
||||||
switch(shading_mode) {
|
switch(shading_mode) {
|
||||||
case aiShadingMode_Flat:
|
case aiShadingMode_Flat:
|
||||||
case aiShadingMode_NoShading:
|
case aiShadingMode_NoShading:
|
||||||
shading_mode_out = Discreet3DS::Flat;
|
shading_mode_out = Discreet3DS::Flat;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aiShadingMode_Gouraud:
|
case aiShadingMode_Gouraud:
|
||||||
case aiShadingMode_Toon:
|
case aiShadingMode_Toon:
|
||||||
case aiShadingMode_OrenNayar:
|
case aiShadingMode_OrenNayar:
|
||||||
case aiShadingMode_Minnaert:
|
case aiShadingMode_Minnaert:
|
||||||
shading_mode_out = Discreet3DS::Gouraud;
|
shading_mode_out = Discreet3DS::Gouraud;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aiShadingMode_Phong:
|
case aiShadingMode_Phong:
|
||||||
case aiShadingMode_Blinn:
|
case aiShadingMode_Blinn:
|
||||||
case aiShadingMode_CookTorrance:
|
case aiShadingMode_CookTorrance:
|
||||||
case aiShadingMode_Fresnel:
|
case aiShadingMode_Fresnel:
|
||||||
shading_mode_out = Discreet3DS::Phong;
|
shading_mode_out = Discreet3DS::Phong;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
shading_mode_out = Discreet3DS::Flat;
|
shading_mode_out = Discreet3DS::Flat;
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
};
|
};
|
||||||
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
|
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float f;
|
float f;
|
||||||
if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
|
||||||
WritePercentChunk(f);
|
WritePercentChunk(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT);
|
||||||
WritePercentChunk(f);
|
WritePercentChunk(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
int twosided;
|
int twosided;
|
||||||
if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
|
if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
|
||||||
writer.PutI2(1);
|
writer.PutI2(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
|
WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
|
||||||
WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
|
WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
|
||||||
WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
|
WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
|
||||||
WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
|
WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
|
||||||
WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP);
|
WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP);
|
||||||
WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP);
|
WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP);
|
||||||
WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP);
|
WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags)
|
void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags)
|
||||||
{
|
{
|
||||||
aiString path;
|
aiString path;
|
||||||
aiTextureMapMode map_mode[2] = {
|
aiTextureMapMode map_mode[2] = {
|
||||||
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
|
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
|
||||||
};
|
};
|
||||||
float blend = 1.0f;
|
float blend = 1.0f;
|
||||||
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
|
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle embedded textures properly
|
// TODO: handle embedded textures properly
|
||||||
if (path.data[0] == '*') {
|
if (path.data[0] == '*') {
|
||||||
DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str()));
|
DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChunkWriter chunk(writer, chunk_flags);
|
ChunkWriter chunk(writer, chunk_flags);
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE);
|
||||||
WriteString(path);
|
WriteString(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
WritePercentChunk(blend);
|
WritePercentChunk(blend);
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
|
||||||
uint16_t val = 0; // WRAP
|
uint16_t val = 0; // WRAP
|
||||||
if (map_mode[0] == aiTextureMapMode_Mirror) {
|
if (map_mode[0] == aiTextureMapMode_Mirror) {
|
||||||
val = 0x2;
|
val = 0x2;
|
||||||
}
|
}
|
||||||
else if (map_mode[0] == aiTextureMapMode_Decal) {
|
else if (map_mode[0] == aiTextureMapMode_Decal) {
|
||||||
val = 0x10;
|
val = 0x10;
|
||||||
}
|
}
|
||||||
writer.PutU2(val);
|
writer.PutU2(val);
|
||||||
}
|
}
|
||||||
// TODO: export texture transformation (i.e. UV offset, scale, rotation)
|
// TODO: export texture transformation (i.e. UV offset, scale, rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteMeshes()
|
void Discreet3DSExporter::WriteMeshes()
|
||||||
{
|
{
|
||||||
// NOTE: 3DS allows for instances. However:
|
// NOTE: 3DS allows for instances. However:
|
||||||
// i) not all importers support reading them
|
// i) not all importers support reading them
|
||||||
// ii) instances are not as flexible as they are in assimp, in particular,
|
// ii) instances are not as flexible as they are in assimp, in particular,
|
||||||
// nodes can carry (and instance) only one mesh.
|
// nodes can carry (and instance) only one mesh.
|
||||||
//
|
//
|
||||||
// This exporter currently deep clones all instanced meshes, i.e. for each mesh
|
// This exporter currently deep clones all instanced meshes, i.e. for each mesh
|
||||||
// attached to a node a full TRIMESH chunk is written to the file.
|
// attached to a node a full TRIMESH chunk is written to the file.
|
||||||
//
|
//
|
||||||
// Furthermore, the TRIMESH is transformed into world space so that it will
|
// Furthermore, the TRIMESH is transformed into world space so that it will
|
||||||
// appear correctly if importers don't read the scene hierarchy at all.
|
// appear correctly if importers don't read the scene hierarchy at all.
|
||||||
for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
|
for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
|
||||||
const aiNode& node = *(*it).first;
|
const aiNode& node = *(*it).first;
|
||||||
const unsigned int mesh_idx = (*it).second;
|
const unsigned int mesh_idx = (*it).second;
|
||||||
|
|
||||||
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
|
const aiMesh& mesh = *scene->mMeshes[mesh_idx];
|
||||||
|
|
||||||
// This should not happen if the SLM step is correctly executed
|
// This should not happen if the SLM step is correctly executed
|
||||||
// before the scene is handed to the exporter
|
// before the scene is handed to the exporter
|
||||||
ai_assert(mesh.mNumVertices <= 0xffff);
|
ai_assert(mesh.mNumVertices <= 0xffff);
|
||||||
ai_assert(mesh.mNumFaces <= 0xffff);
|
ai_assert(mesh.mNumFaces <= 0xffff);
|
||||||
|
|
||||||
const aiMatrix4x4& trafo = trafos[&node];
|
const aiMatrix4x4& trafo = trafos[&node];
|
||||||
|
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK);
|
||||||
|
|
||||||
// Mesh name is tied to the node it is attached to so it can later be referenced
|
// Mesh name is tied to the node it is attached to so it can later be referenced
|
||||||
const std::string& name = GetMeshName(mesh, mesh_idx, node);
|
const std::string& name = GetMeshName(mesh, mesh_idx, node);
|
||||||
WriteString(name);
|
WriteString(name);
|
||||||
|
|
||||||
|
|
||||||
// TRIMESH chunk
|
// TRIMESH chunk
|
||||||
ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH);
|
ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH);
|
||||||
|
|
||||||
// Vertices in world space
|
// Vertices in world space
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST);
|
||||||
|
|
||||||
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
|
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
|
||||||
writer.PutU2(count);
|
writer.PutU2(count);
|
||||||
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
|
||||||
const aiVector3D& v = trafo * mesh.mVertices[i];
|
const aiVector3D& v = trafo * mesh.mVertices[i];
|
||||||
writer.PutF4(v.x);
|
writer.PutF4(v.x);
|
||||||
writer.PutF4(v.y);
|
writer.PutF4(v.y);
|
||||||
writer.PutF4(v.z);
|
writer.PutF4(v.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UV coordinates
|
// UV coordinates
|
||||||
if (mesh.HasTextureCoords(0)) {
|
if (mesh.HasTextureCoords(0)) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST);
|
||||||
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
|
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
|
||||||
writer.PutU2(count);
|
writer.PutU2(count);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
|
||||||
const aiVector3D& v = mesh.mTextureCoords[0][i];
|
const aiVector3D& v = mesh.mTextureCoords[0][i];
|
||||||
writer.PutF4(v.x);
|
writer.PutF4(v.x);
|
||||||
writer.PutF4(v.y);
|
writer.PutF4(v.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faces (indices)
|
// Faces (indices)
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST);
|
||||||
|
|
||||||
ai_assert(mesh.mNumFaces <= 0xffff);
|
ai_assert(mesh.mNumFaces <= 0xffff);
|
||||||
|
|
||||||
// Count triangles, discard lines and points
|
// Count triangles, discard lines and points
|
||||||
uint16_t count = 0;
|
uint16_t count = 0;
|
||||||
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
|
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
|
||||||
const aiFace& f = mesh.mFaces[i];
|
const aiFace& f = mesh.mFaces[i];
|
||||||
if (f.mNumIndices < 3) {
|
if (f.mNumIndices < 3) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TRIANGULATE step is a pre-requisite so we should not see polys here
|
// TRIANGULATE step is a pre-requisite so we should not see polys here
|
||||||
ai_assert(f.mNumIndices == 3);
|
ai_assert(f.mNumIndices == 3);
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.PutU2(count);
|
writer.PutU2(count);
|
||||||
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
|
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
|
||||||
const aiFace& f = mesh.mFaces[i];
|
const aiFace& f = mesh.mFaces[i];
|
||||||
if (f.mNumIndices < 3) {
|
if (f.mNumIndices < 3) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int j = 0; j < 3; ++j) {
|
for (unsigned int j = 0; j < 3; ++j) {
|
||||||
ai_assert(f.mIndices[j] <= 0xffff);
|
ai_assert(f.mIndices[j] <= 0xffff);
|
||||||
writer.PutI2(static_cast<uint16_t>(f.mIndices[j]));
|
writer.PutI2(static_cast<uint16_t>(f.mIndices[j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edge visibility flag
|
// Edge visibility flag
|
||||||
writer.PutI2(0x0);
|
writer.PutI2(0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: write smoothing groups (CHUNK_SMOOLIST)
|
// TODO: write smoothing groups (CHUNK_SMOOLIST)
|
||||||
|
|
||||||
WriteFaceMaterialChunk(mesh);
|
WriteFaceMaterialChunk(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transformation matrix by which the mesh vertices have been pre-transformed with.
|
// Transformation matrix by which the mesh vertices have been pre-transformed with.
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX);
|
||||||
for (unsigned int r = 0; r < 4; ++r) {
|
for (unsigned int r = 0; r < 4; ++r) {
|
||||||
for (unsigned int c = 0; c < 3; ++c) {
|
for (unsigned int c = 0; c < 3; ++c) {
|
||||||
writer.PutF4(trafo[r][c]);
|
writer.PutF4(trafo[r][c]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
|
void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT);
|
||||||
const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
|
const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
|
||||||
WriteString(name);
|
WriteString(name);
|
||||||
|
|
||||||
// Because assimp splits meshes by material, only a single
|
// Because assimp splits meshes by material, only a single
|
||||||
// FACEMAT chunk needs to be written
|
// FACEMAT chunk needs to be written
|
||||||
ai_assert(mesh.mNumFaces <= 0xffff);
|
ai_assert(mesh.mNumFaces <= 0xffff);
|
||||||
const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces);
|
const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces);
|
||||||
writer.PutU2(count);
|
writer.PutU2(count);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
|
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
|
||||||
writer.PutU2(static_cast<uint16_t>(i));
|
writer.PutU2(static_cast<uint16_t>(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteString(const std::string& s) {
|
void Discreet3DSExporter::WriteString(const std::string& s) {
|
||||||
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
writer.PutI1(*it);
|
writer.PutI1(*it);
|
||||||
}
|
}
|
||||||
writer.PutI1('\0');
|
writer.PutI1('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteString(const aiString& s) {
|
void Discreet3DSExporter::WriteString(const aiString& s) {
|
||||||
for (std::size_t i = 0; i < s.length; ++i) {
|
for (std::size_t i = 0; i < s.length; ++i) {
|
||||||
writer.PutI1(s.data[i]);
|
writer.PutI1(s.data[i]);
|
||||||
}
|
}
|
||||||
writer.PutI1('\0');
|
writer.PutI1('\0');
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
|
void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF);
|
||||||
writer.PutF4(color.r);
|
writer.PutF4(color.r);
|
||||||
writer.PutF4(color.g);
|
writer.PutF4(color.g);
|
||||||
writer.PutF4(color.b);
|
writer.PutF4(color.b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Discreet3DSExporter::WritePercentChunk(float f) {
|
void Discreet3DSExporter::WritePercentChunk(float f) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF);
|
||||||
writer.PutF4(f);
|
writer.PutF4(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -64,32 +64,32 @@ namespace Assimp
|
||||||
class Discreet3DSExporter
|
class Discreet3DSExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* pScene);
|
Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* pScene);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void WriteMeshes();
|
void WriteMeshes();
|
||||||
void WriteMaterials();
|
void WriteMaterials();
|
||||||
void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
|
void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
|
||||||
|
|
||||||
void WriteFaceMaterialChunk(const aiMesh& mesh);
|
void WriteFaceMaterialChunk(const aiMesh& mesh);
|
||||||
|
|
||||||
int WriteHierarchy(const aiNode& node, int level, int sibling_level);
|
int WriteHierarchy(const aiNode& node, int level, int sibling_level);
|
||||||
|
|
||||||
void WriteString(const std::string& s);
|
void WriteString(const std::string& s);
|
||||||
void WriteString(const aiString& s);
|
void WriteString(const aiString& s);
|
||||||
void WriteColor(const aiColor3D& color);
|
void WriteColor(const aiColor3D& color);
|
||||||
void WritePercentChunk(float f);
|
void WritePercentChunk(float f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const aiScene* const scene;
|
const aiScene* const scene;
|
||||||
StreamWriterLE writer;
|
StreamWriterLE writer;
|
||||||
|
|
||||||
std::map<const aiNode*, aiMatrix4x4> trafos;
|
std::map<const aiNode*, aiMatrix4x4> trafos;
|
||||||
|
|
||||||
typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
|
typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
|
||||||
MeshesByNodeMap meshes;
|
MeshesByNodeMap meshes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
765
code/3DSHelper.h
765
code/3DSHelper.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -53,8 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "./../include/assimp/anim.h"
|
#include "./../include/assimp/anim.h"
|
||||||
#include <stdio.h> //sprintf
|
#include <stdio.h> //sprintf
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace D3DS {
|
namespace D3DS {
|
||||||
|
|
||||||
#include "./../include/assimp/Compiler/pushpack1.h"
|
#include "./../include/assimp/Compiler/pushpack1.h"
|
||||||
|
|
||||||
|
@ -65,253 +65,253 @@ namespace D3DS {
|
||||||
class Discreet3DS
|
class Discreet3DS
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
inline Discreet3DS() {}
|
inline Discreet3DS() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! data structure for a single chunk in a .3ds file
|
//! data structure for a single chunk in a .3ds file
|
||||||
struct Chunk
|
struct Chunk
|
||||||
{
|
{
|
||||||
uint16_t Flag;
|
uint16_t Flag;
|
||||||
uint32_t Size;
|
uint32_t Size;
|
||||||
} PACK_STRUCT;
|
} PACK_STRUCT;
|
||||||
|
|
||||||
|
|
||||||
//! Used for shading field in material3ds structure
|
//! Used for shading field in material3ds structure
|
||||||
//! From AutoDesk 3ds SDK
|
//! From AutoDesk 3ds SDK
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
// translated to gouraud shading with wireframe active
|
// translated to gouraud shading with wireframe active
|
||||||
Wire = 0x0,
|
Wire = 0x0,
|
||||||
|
|
||||||
// if this material is set, no vertex normals will
|
// if this material is set, no vertex normals will
|
||||||
// be calculated for the model. Face normals + gouraud
|
// be calculated for the model. Face normals + gouraud
|
||||||
Flat = 0x1,
|
Flat = 0x1,
|
||||||
|
|
||||||
// standard gouraud shading
|
// standard gouraud shading
|
||||||
Gouraud = 0x2,
|
Gouraud = 0x2,
|
||||||
|
|
||||||
// phong shading
|
// phong shading
|
||||||
Phong = 0x3,
|
Phong = 0x3,
|
||||||
|
|
||||||
// cooktorrance or anistropic phong shading ...
|
// cooktorrance or anistropic phong shading ...
|
||||||
// the exact meaning is unknown, if you know it
|
// the exact meaning is unknown, if you know it
|
||||||
// feel free to tell me ;-)
|
// feel free to tell me ;-)
|
||||||
Metal = 0x4,
|
Metal = 0x4,
|
||||||
|
|
||||||
// required by the ASE loader
|
// required by the ASE loader
|
||||||
Blinn = 0x5
|
Blinn = 0x5
|
||||||
} shadetype3ds;
|
} shadetype3ds;
|
||||||
|
|
||||||
// Flags for animated keys
|
// Flags for animated keys
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
KEY_USE_TENS = 0x1,
|
KEY_USE_TENS = 0x1,
|
||||||
KEY_USE_CONT = 0x2,
|
KEY_USE_CONT = 0x2,
|
||||||
KEY_USE_BIAS = 0x4,
|
KEY_USE_BIAS = 0x4,
|
||||||
KEY_USE_EASE_TO = 0x8,
|
KEY_USE_EASE_TO = 0x8,
|
||||||
KEY_USE_EASE_FROM = 0x10
|
KEY_USE_EASE_FROM = 0x10
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
// Basic chunks which can be found everywhere in the file
|
// Basic chunks which can be found everywhere in the file
|
||||||
CHUNK_VERSION = 0x0002,
|
CHUNK_VERSION = 0x0002,
|
||||||
CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
|
CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
|
||||||
CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
|
CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
|
||||||
|
|
||||||
// Linear color values (gamma = 2.2?)
|
// Linear color values (gamma = 2.2?)
|
||||||
CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
|
CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
|
||||||
CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
|
CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
|
||||||
|
|
||||||
CHUNK_PERCENTW = 0x0030, // int2 percentage
|
CHUNK_PERCENTW = 0x0030, // int2 percentage
|
||||||
CHUNK_PERCENTF = 0x0031, // float4 percentage
|
CHUNK_PERCENTF = 0x0031, // float4 percentage
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
|
|
||||||
// Prj master chunk
|
// Prj master chunk
|
||||||
CHUNK_PRJ = 0xC23D,
|
CHUNK_PRJ = 0xC23D,
|
||||||
|
|
||||||
// MDLI master chunk
|
// MDLI master chunk
|
||||||
CHUNK_MLI = 0x3DAA,
|
CHUNK_MLI = 0x3DAA,
|
||||||
|
|
||||||
// Primary main chunk of the .3ds file
|
// Primary main chunk of the .3ds file
|
||||||
CHUNK_MAIN = 0x4D4D,
|
CHUNK_MAIN = 0x4D4D,
|
||||||
|
|
||||||
// Mesh main chunk
|
// Mesh main chunk
|
||||||
CHUNK_OBJMESH = 0x3D3D,
|
CHUNK_OBJMESH = 0x3D3D,
|
||||||
|
|
||||||
// Specifies the background color of the .3ds file
|
// Specifies the background color of the .3ds file
|
||||||
// This is passed through the material system for
|
// This is passed through the material system for
|
||||||
// viewing purposes.
|
// viewing purposes.
|
||||||
CHUNK_BKGCOLOR = 0x1200,
|
CHUNK_BKGCOLOR = 0x1200,
|
||||||
|
|
||||||
// Specifies the ambient base color of the scene.
|
// Specifies the ambient base color of the scene.
|
||||||
// This is added to all materials in the file
|
// This is added to all materials in the file
|
||||||
CHUNK_AMBCOLOR = 0x2100,
|
CHUNK_AMBCOLOR = 0x2100,
|
||||||
|
|
||||||
// Specifies the background image for the whole scene
|
// Specifies the background image for the whole scene
|
||||||
// This value is passed through the material system
|
// This value is passed through the material system
|
||||||
// to the viewer
|
// to the viewer
|
||||||
CHUNK_BIT_MAP = 0x1100,
|
CHUNK_BIT_MAP = 0x1100,
|
||||||
CHUNK_BIT_MAP_EXISTS = 0x1101,
|
CHUNK_BIT_MAP_EXISTS = 0x1101,
|
||||||
|
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
// Viewport related stuff. Ignored
|
// Viewport related stuff. Ignored
|
||||||
CHUNK_DEFAULT_VIEW = 0x3000,
|
CHUNK_DEFAULT_VIEW = 0x3000,
|
||||||
CHUNK_VIEW_TOP = 0x3010,
|
CHUNK_VIEW_TOP = 0x3010,
|
||||||
CHUNK_VIEW_BOTTOM = 0x3020,
|
CHUNK_VIEW_BOTTOM = 0x3020,
|
||||||
CHUNK_VIEW_LEFT = 0x3030,
|
CHUNK_VIEW_LEFT = 0x3030,
|
||||||
CHUNK_VIEW_RIGHT = 0x3040,
|
CHUNK_VIEW_RIGHT = 0x3040,
|
||||||
CHUNK_VIEW_FRONT = 0x3050,
|
CHUNK_VIEW_FRONT = 0x3050,
|
||||||
CHUNK_VIEW_BACK = 0x3060,
|
CHUNK_VIEW_BACK = 0x3060,
|
||||||
CHUNK_VIEW_USER = 0x3070,
|
CHUNK_VIEW_USER = 0x3070,
|
||||||
CHUNK_VIEW_CAMERA = 0x3080,
|
CHUNK_VIEW_CAMERA = 0x3080,
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
|
|
||||||
// Mesh chunks
|
// Mesh chunks
|
||||||
CHUNK_OBJBLOCK = 0x4000,
|
CHUNK_OBJBLOCK = 0x4000,
|
||||||
CHUNK_TRIMESH = 0x4100,
|
CHUNK_TRIMESH = 0x4100,
|
||||||
CHUNK_VERTLIST = 0x4110,
|
CHUNK_VERTLIST = 0x4110,
|
||||||
CHUNK_VERTFLAGS = 0x4111,
|
CHUNK_VERTFLAGS = 0x4111,
|
||||||
CHUNK_FACELIST = 0x4120,
|
CHUNK_FACELIST = 0x4120,
|
||||||
CHUNK_FACEMAT = 0x4130,
|
CHUNK_FACEMAT = 0x4130,
|
||||||
CHUNK_MAPLIST = 0x4140,
|
CHUNK_MAPLIST = 0x4140,
|
||||||
CHUNK_SMOOLIST = 0x4150,
|
CHUNK_SMOOLIST = 0x4150,
|
||||||
CHUNK_TRMATRIX = 0x4160,
|
CHUNK_TRMATRIX = 0x4160,
|
||||||
CHUNK_MESHCOLOR = 0x4165,
|
CHUNK_MESHCOLOR = 0x4165,
|
||||||
CHUNK_TXTINFO = 0x4170,
|
CHUNK_TXTINFO = 0x4170,
|
||||||
CHUNK_LIGHT = 0x4600,
|
CHUNK_LIGHT = 0x4600,
|
||||||
CHUNK_CAMERA = 0x4700,
|
CHUNK_CAMERA = 0x4700,
|
||||||
CHUNK_HIERARCHY = 0x4F00,
|
CHUNK_HIERARCHY = 0x4F00,
|
||||||
|
|
||||||
// Specifies the global scaling factor. This is applied
|
// Specifies the global scaling factor. This is applied
|
||||||
// to the root node's transformation matrix
|
// to the root node's transformation matrix
|
||||||
CHUNK_MASTER_SCALE = 0x0100,
|
CHUNK_MASTER_SCALE = 0x0100,
|
||||||
|
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
// Material chunks
|
// Material chunks
|
||||||
CHUNK_MAT_MATERIAL = 0xAFFF,
|
CHUNK_MAT_MATERIAL = 0xAFFF,
|
||||||
|
|
||||||
// asciiz containing the name of the material
|
// asciiz containing the name of the material
|
||||||
CHUNK_MAT_MATNAME = 0xA000,
|
CHUNK_MAT_MATNAME = 0xA000,
|
||||||
CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
|
CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
|
||||||
CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
|
CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
|
||||||
CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
|
CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
|
||||||
|
|
||||||
// Specifies the shininess of the material
|
// Specifies the shininess of the material
|
||||||
// followed by percentage chunk
|
// followed by percentage chunk
|
||||||
CHUNK_MAT_SHININESS = 0xA040,
|
CHUNK_MAT_SHININESS = 0xA040,
|
||||||
CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
|
CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
|
||||||
|
|
||||||
// Specifies the shading mode to be used
|
// Specifies the shading mode to be used
|
||||||
// followed by a short
|
// followed by a short
|
||||||
CHUNK_MAT_SHADING = 0xA100,
|
CHUNK_MAT_SHADING = 0xA100,
|
||||||
|
|
||||||
// NOTE: Emissive color (self illumination) seems not
|
// NOTE: Emissive color (self illumination) seems not
|
||||||
// to be a color but a single value, type is unknown.
|
// to be a color but a single value, type is unknown.
|
||||||
// Make the parser accept both of them.
|
// Make the parser accept both of them.
|
||||||
// followed by percentage chunk (?)
|
// followed by percentage chunk (?)
|
||||||
CHUNK_MAT_SELF_ILLUM = 0xA080,
|
CHUNK_MAT_SELF_ILLUM = 0xA080,
|
||||||
|
|
||||||
// Always followed by percentage chunk (?)
|
// Always followed by percentage chunk (?)
|
||||||
CHUNK_MAT_SELF_ILPCT = 0xA084,
|
CHUNK_MAT_SELF_ILPCT = 0xA084,
|
||||||
|
|
||||||
// Always followed by percentage chunk
|
// Always followed by percentage chunk
|
||||||
CHUNK_MAT_TRANSPARENCY = 0xA050,
|
CHUNK_MAT_TRANSPARENCY = 0xA050,
|
||||||
|
|
||||||
// Diffuse texture channel 0
|
// Diffuse texture channel 0
|
||||||
CHUNK_MAT_TEXTURE = 0xA200,
|
CHUNK_MAT_TEXTURE = 0xA200,
|
||||||
|
|
||||||
// Contains opacity information for each texel
|
// Contains opacity information for each texel
|
||||||
CHUNK_MAT_OPACMAP = 0xA210,
|
CHUNK_MAT_OPACMAP = 0xA210,
|
||||||
|
|
||||||
// Contains a reflection map to be used to reflect
|
// Contains a reflection map to be used to reflect
|
||||||
// the environment. This is partially supported.
|
// the environment. This is partially supported.
|
||||||
CHUNK_MAT_REFLMAP = 0xA220,
|
CHUNK_MAT_REFLMAP = 0xA220,
|
||||||
|
|
||||||
// Self Illumination map (emissive colors)
|
// Self Illumination map (emissive colors)
|
||||||
CHUNK_MAT_SELFIMAP = 0xA33d,
|
CHUNK_MAT_SELFIMAP = 0xA33d,
|
||||||
|
|
||||||
// Bumpmap. Not specified whether it is a heightmap
|
// Bumpmap. Not specified whether it is a heightmap
|
||||||
// or a normal map. Assme it is a heightmap since
|
// or a normal map. Assme it is a heightmap since
|
||||||
// artist normally prefer this format.
|
// artist normally prefer this format.
|
||||||
CHUNK_MAT_BUMPMAP = 0xA230,
|
CHUNK_MAT_BUMPMAP = 0xA230,
|
||||||
|
|
||||||
// Specular map. Seems to influence the specular color
|
// Specular map. Seems to influence the specular color
|
||||||
CHUNK_MAT_SPECMAP = 0xA204,
|
CHUNK_MAT_SPECMAP = 0xA204,
|
||||||
|
|
||||||
// Holds shininess data.
|
// Holds shininess data.
|
||||||
CHUNK_MAT_MAT_SHINMAP = 0xA33C,
|
CHUNK_MAT_MAT_SHINMAP = 0xA33C,
|
||||||
|
|
||||||
// Scaling in U/V direction.
|
// Scaling in U/V direction.
|
||||||
// (need to gen separate UV coordinate set
|
// (need to gen separate UV coordinate set
|
||||||
// and do this by hand)
|
// and do this by hand)
|
||||||
CHUNK_MAT_MAP_USCALE = 0xA354,
|
CHUNK_MAT_MAP_USCALE = 0xA354,
|
||||||
CHUNK_MAT_MAP_VSCALE = 0xA356,
|
CHUNK_MAT_MAP_VSCALE = 0xA356,
|
||||||
|
|
||||||
// Translation in U/V direction.
|
// Translation in U/V direction.
|
||||||
// (need to gen separate UV coordinate set
|
// (need to gen separate UV coordinate set
|
||||||
// and do this by hand)
|
// and do this by hand)
|
||||||
CHUNK_MAT_MAP_UOFFSET = 0xA358,
|
CHUNK_MAT_MAP_UOFFSET = 0xA358,
|
||||||
CHUNK_MAT_MAP_VOFFSET = 0xA35a,
|
CHUNK_MAT_MAP_VOFFSET = 0xA35a,
|
||||||
|
|
||||||
// UV-coordinates rotation around the z-axis
|
// UV-coordinates rotation around the z-axis
|
||||||
// Assumed to be in radians.
|
// Assumed to be in radians.
|
||||||
CHUNK_MAT_MAP_ANG = 0xA35C,
|
CHUNK_MAT_MAP_ANG = 0xA35C,
|
||||||
|
|
||||||
// Tiling flags for 3DS files
|
// Tiling flags for 3DS files
|
||||||
CHUNK_MAT_MAP_TILING = 0xa351,
|
CHUNK_MAT_MAP_TILING = 0xa351,
|
||||||
|
|
||||||
// Specifies the file name of a texture
|
// Specifies the file name of a texture
|
||||||
CHUNK_MAPFILE = 0xA300,
|
CHUNK_MAPFILE = 0xA300,
|
||||||
|
|
||||||
// Specifies whether a materail requires two-sided rendering
|
// Specifies whether a materail requires two-sided rendering
|
||||||
CHUNK_MAT_TWO_SIDE = 0xA081,
|
CHUNK_MAT_TWO_SIDE = 0xA081,
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
|
|
||||||
// Main keyframer chunk. Contains translation/rotation/scaling data
|
// Main keyframer chunk. Contains translation/rotation/scaling data
|
||||||
CHUNK_KEYFRAMER = 0xB000,
|
CHUNK_KEYFRAMER = 0xB000,
|
||||||
|
|
||||||
// Supported sub chunks
|
// Supported sub chunks
|
||||||
CHUNK_TRACKINFO = 0xB002,
|
CHUNK_TRACKINFO = 0xB002,
|
||||||
CHUNK_TRACKOBJNAME = 0xB010,
|
CHUNK_TRACKOBJNAME = 0xB010,
|
||||||
CHUNK_TRACKDUMMYOBJNAME = 0xB011,
|
CHUNK_TRACKDUMMYOBJNAME = 0xB011,
|
||||||
CHUNK_TRACKPIVOT = 0xB013,
|
CHUNK_TRACKPIVOT = 0xB013,
|
||||||
CHUNK_TRACKPOS = 0xB020,
|
CHUNK_TRACKPOS = 0xB020,
|
||||||
CHUNK_TRACKROTATE = 0xB021,
|
CHUNK_TRACKROTATE = 0xB021,
|
||||||
CHUNK_TRACKSCALE = 0xB022,
|
CHUNK_TRACKSCALE = 0xB022,
|
||||||
|
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
// Keyframes for various other stuff in the file
|
// Keyframes for various other stuff in the file
|
||||||
// Partially ignored
|
// Partially ignored
|
||||||
CHUNK_AMBIENTKEY = 0xB001,
|
CHUNK_AMBIENTKEY = 0xB001,
|
||||||
CHUNK_TRACKMORPH = 0xB026,
|
CHUNK_TRACKMORPH = 0xB026,
|
||||||
CHUNK_TRACKHIDE = 0xB029,
|
CHUNK_TRACKHIDE = 0xB029,
|
||||||
CHUNK_OBJNUMBER = 0xB030,
|
CHUNK_OBJNUMBER = 0xB030,
|
||||||
CHUNK_TRACKCAMERA = 0xB003,
|
CHUNK_TRACKCAMERA = 0xB003,
|
||||||
CHUNK_TRACKFOV = 0xB023,
|
CHUNK_TRACKFOV = 0xB023,
|
||||||
CHUNK_TRACKROLL = 0xB024,
|
CHUNK_TRACKROLL = 0xB024,
|
||||||
CHUNK_TRACKCAMTGT = 0xB004,
|
CHUNK_TRACKCAMTGT = 0xB004,
|
||||||
CHUNK_TRACKLIGHT = 0xB005,
|
CHUNK_TRACKLIGHT = 0xB005,
|
||||||
CHUNK_TRACKLIGTGT = 0xB006,
|
CHUNK_TRACKLIGTGT = 0xB006,
|
||||||
CHUNK_TRACKSPOTL = 0xB007,
|
CHUNK_TRACKSPOTL = 0xB007,
|
||||||
CHUNK_FRAMES = 0xB008,
|
CHUNK_FRAMES = 0xB008,
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
|
|
||||||
// light sub-chunks
|
// light sub-chunks
|
||||||
CHUNK_DL_OFF = 0x4620,
|
CHUNK_DL_OFF = 0x4620,
|
||||||
CHUNK_DL_OUTER_RANGE = 0x465A,
|
CHUNK_DL_OUTER_RANGE = 0x465A,
|
||||||
CHUNK_DL_INNER_RANGE = 0x4659,
|
CHUNK_DL_INNER_RANGE = 0x4659,
|
||||||
CHUNK_DL_MULTIPLIER = 0x465B,
|
CHUNK_DL_MULTIPLIER = 0x465B,
|
||||||
CHUNK_DL_EXCLUDE = 0x4654,
|
CHUNK_DL_EXCLUDE = 0x4654,
|
||||||
CHUNK_DL_ATTENUATE = 0x4625,
|
CHUNK_DL_ATTENUATE = 0x4625,
|
||||||
CHUNK_DL_SPOTLIGHT = 0x4610,
|
CHUNK_DL_SPOTLIGHT = 0x4610,
|
||||||
|
|
||||||
// camera sub-chunks
|
// camera sub-chunks
|
||||||
CHUNK_CAM_RANGES = 0x4720
|
CHUNK_CAM_RANGES = 0x4720
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -324,38 +324,39 @@ struct Face : public FaceWithSmoothingGroup
|
||||||
/** Helper structure representing a texture */
|
/** Helper structure representing a texture */
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Texture()
|
Texture()
|
||||||
: mOffsetU (0.0f)
|
: mOffsetU (0.0f)
|
||||||
, mOffsetV (0.0f)
|
, mOffsetV (0.0f)
|
||||||
, mScaleU (1.0f)
|
, mScaleU (1.0f)
|
||||||
, mScaleV (1.0f)
|
, mScaleV (1.0f)
|
||||||
, mRotation (0.0f)
|
, mRotation (0.0f)
|
||||||
, mMapMode (aiTextureMapMode_Wrap)
|
, mMapMode (aiTextureMapMode_Wrap)
|
||||||
, iUVSrc (0)
|
, bPrivate()
|
||||||
{
|
, iUVSrc (0)
|
||||||
mTextureBlend = get_qnan();
|
{
|
||||||
}
|
mTextureBlend = get_qnan();
|
||||||
|
}
|
||||||
|
|
||||||
//! Specifies the blend factor for the texture
|
//! Specifies the blend factor for the texture
|
||||||
float mTextureBlend;
|
float mTextureBlend;
|
||||||
|
|
||||||
//! Specifies the filename of the texture
|
//! Specifies the filename of the texture
|
||||||
std::string mMapName;
|
std::string mMapName;
|
||||||
|
|
||||||
//! Specifies texture coordinate offsets/scaling/rotations
|
//! Specifies texture coordinate offsets/scaling/rotations
|
||||||
float mOffsetU;
|
float mOffsetU;
|
||||||
float mOffsetV;
|
float mOffsetV;
|
||||||
float mScaleU;
|
float mScaleU;
|
||||||
float mScaleV;
|
float mScaleV;
|
||||||
float mRotation;
|
float mRotation;
|
||||||
|
|
||||||
//! Specifies the mapping mode to be used for the texture
|
//! Specifies the mapping mode to be used for the texture
|
||||||
aiTextureMapMode mMapMode;
|
aiTextureMapMode mMapMode;
|
||||||
|
|
||||||
//! Used internally
|
//! Used internally
|
||||||
bool bPrivate;
|
bool bPrivate;
|
||||||
int iUVSrc;
|
int iUVSrc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "./../include/assimp/Compiler/poppack1.h"
|
#include "./../include/assimp/Compiler/poppack1.h"
|
||||||
|
@ -364,91 +365,91 @@ struct Texture
|
||||||
/** Helper structure representing a 3ds material */
|
/** Helper structure representing a 3ds material */
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
//! Default constructor. Builds a default name for the material
|
//! Default constructor. Builds a default name for the material
|
||||||
Material()
|
Material()
|
||||||
:
|
:
|
||||||
mDiffuse (0.6f,0.6f,0.6f), // FIX ... we won't want object to be black
|
mDiffuse (0.6f,0.6f,0.6f), // FIX ... we won't want object to be black
|
||||||
mSpecularExponent (0.0f),
|
mSpecularExponent (0.0f),
|
||||||
mShininessStrength (1.0f),
|
mShininessStrength (1.0f),
|
||||||
mShading(Discreet3DS::Gouraud),
|
mShading(Discreet3DS::Gouraud),
|
||||||
mTransparency (1.0f),
|
mTransparency (1.0f),
|
||||||
mBumpHeight (1.0f),
|
mBumpHeight (1.0f),
|
||||||
mTwoSided (false)
|
mTwoSided (false)
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
|
|
||||||
char szTemp[128];
|
char szTemp[128];
|
||||||
sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Name of the material
|
//! Name of the material
|
||||||
std::string mName;
|
std::string mName;
|
||||||
//! Diffuse color of the material
|
//! Diffuse color of the material
|
||||||
aiColor3D mDiffuse;
|
aiColor3D mDiffuse;
|
||||||
//! Specular exponent
|
//! Specular exponent
|
||||||
float mSpecularExponent;
|
float mSpecularExponent;
|
||||||
//! Shininess strength, in percent
|
//! Shininess strength, in percent
|
||||||
float mShininessStrength;
|
float mShininessStrength;
|
||||||
//! Specular color of the material
|
//! Specular color of the material
|
||||||
aiColor3D mSpecular;
|
aiColor3D mSpecular;
|
||||||
//! Ambient color of the material
|
//! Ambient color of the material
|
||||||
aiColor3D mAmbient;
|
aiColor3D mAmbient;
|
||||||
//! Shading type to be used
|
//! Shading type to be used
|
||||||
Discreet3DS::shadetype3ds mShading;
|
Discreet3DS::shadetype3ds mShading;
|
||||||
//! Opacity of the material
|
//! Opacity of the material
|
||||||
float mTransparency;
|
float mTransparency;
|
||||||
//! Diffuse texture channel
|
//! Diffuse texture channel
|
||||||
Texture sTexDiffuse;
|
Texture sTexDiffuse;
|
||||||
//! Opacity texture channel
|
//! Opacity texture channel
|
||||||
Texture sTexOpacity;
|
Texture sTexOpacity;
|
||||||
//! Specular texture channel
|
//! Specular texture channel
|
||||||
Texture sTexSpecular;
|
Texture sTexSpecular;
|
||||||
//! Reflective texture channel
|
//! Reflective texture channel
|
||||||
Texture sTexReflective;
|
Texture sTexReflective;
|
||||||
//! Bump texture channel
|
//! Bump texture channel
|
||||||
Texture sTexBump;
|
Texture sTexBump;
|
||||||
//! Emissive texture channel
|
//! Emissive texture channel
|
||||||
Texture sTexEmissive;
|
Texture sTexEmissive;
|
||||||
//! Shininess texture channel
|
//! Shininess texture channel
|
||||||
Texture sTexShininess;
|
Texture sTexShininess;
|
||||||
//! Scaling factor for the bump values
|
//! Scaling factor for the bump values
|
||||||
float mBumpHeight;
|
float mBumpHeight;
|
||||||
//! Emissive color
|
//! Emissive color
|
||||||
aiColor3D mEmissive;
|
aiColor3D mEmissive;
|
||||||
//! Ambient texture channel
|
//! Ambient texture channel
|
||||||
//! (used by the ASE format)
|
//! (used by the ASE format)
|
||||||
Texture sTexAmbient;
|
Texture sTexAmbient;
|
||||||
//! True if the material must be rendered from two sides
|
//! True if the material must be rendered from two sides
|
||||||
bool mTwoSided;
|
bool mTwoSided;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure to represent a 3ds file mesh */
|
/** Helper structure to represent a 3ds file mesh */
|
||||||
struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
||||||
{
|
{
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Mesh()
|
Mesh()
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
|
|
||||||
// Generate a default name for the mesh
|
// Generate a default name for the mesh
|
||||||
char szTemp[128];
|
char szTemp[128];
|
||||||
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Name of the mesh
|
//! Name of the mesh
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
//! Texture coordinates
|
//! Texture coordinates
|
||||||
std::vector<aiVector3D> mTexCoords;
|
std::vector<aiVector3D> mTexCoords;
|
||||||
|
|
||||||
//! Face materials
|
//! Face materials
|
||||||
std::vector<unsigned int> mFaceMaterials;
|
std::vector<unsigned int> mFaceMaterials;
|
||||||
|
|
||||||
//! Local transformation matrix
|
//! Local transformation matrix
|
||||||
aiMatrix4x4 mMat;
|
aiMatrix4x4 mMat;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -456,25 +457,25 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
||||||
C-API, so it would be difficult to make them a template. */
|
C-API, so it would be difficult to make them a template. */
|
||||||
struct aiFloatKey
|
struct aiFloatKey
|
||||||
{
|
{
|
||||||
double mTime; ///< The time of this key
|
double mTime; ///< The time of this key
|
||||||
float mValue; ///< The value of this key
|
float mValue; ///< The value of this key
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
// time is not compared
|
// time is not compared
|
||||||
bool operator == (const aiFloatKey& o) const
|
bool operator == (const aiFloatKey& o) const
|
||||||
{return o.mValue == this->mValue;}
|
{return o.mValue == this->mValue;}
|
||||||
|
|
||||||
bool operator != (const aiFloatKey& o) const
|
bool operator != (const aiFloatKey& o) const
|
||||||
{return o.mValue != this->mValue;}
|
{return o.mValue != this->mValue;}
|
||||||
|
|
||||||
// Only time is compared. This operator is defined
|
// Only time is compared. This operator is defined
|
||||||
// for use with std::sort
|
// for use with std::sort
|
||||||
bool operator < (const aiFloatKey& o) const
|
bool operator < (const aiFloatKey& o) const
|
||||||
{return mTime < o.mTime;}
|
{return mTime < o.mTime;}
|
||||||
|
|
||||||
bool operator > (const aiFloatKey& o) const
|
bool operator > (const aiFloatKey& o) const
|
||||||
{return mTime > o.mTime;}
|
{return mTime > o.mTime;}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -483,104 +484,104 @@ struct aiFloatKey
|
||||||
/** Helper structure to represent a 3ds file node */
|
/** Helper structure to represent a 3ds file node */
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
Node()
|
Node()
|
||||||
|
: mParent()
|
||||||
|
, mInstanceNumber()
|
||||||
|
, mHierarchyPos (0)
|
||||||
|
, mHierarchyIndex (0)
|
||||||
|
, mInstanceCount (1)
|
||||||
|
{
|
||||||
|
static int iCnt = 0;
|
||||||
|
|
||||||
: mHierarchyPos (0)
|
// Generate a default name for the node
|
||||||
, mHierarchyIndex (0)
|
char szTemp[128];
|
||||||
, mInstanceCount (1)
|
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
||||||
|
mName = szTemp;
|
||||||
|
|
||||||
{
|
aRotationKeys.reserve (20);
|
||||||
static int iCnt = 0;
|
aPositionKeys.reserve (20);
|
||||||
|
aScalingKeys.reserve (20);
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a default name for the node
|
~Node()
|
||||||
char szTemp[128];
|
{
|
||||||
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
for (unsigned int i = 0; i < mChildren.size();++i)
|
||||||
mName = szTemp;
|
delete mChildren[i];
|
||||||
|
}
|
||||||
|
|
||||||
aRotationKeys.reserve (20);
|
//! Pointer to the parent node
|
||||||
aPositionKeys.reserve (20);
|
Node* mParent;
|
||||||
aScalingKeys.reserve (20);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Node()
|
//! Holds all child nodes
|
||||||
{
|
std::vector<Node*> mChildren;
|
||||||
for (unsigned int i = 0; i < mChildren.size();++i)
|
|
||||||
delete mChildren[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Pointer to the parent node
|
//! Name of the node
|
||||||
Node* mParent;
|
std::string mName;
|
||||||
|
|
||||||
//! Holds all child nodes
|
//! InstanceNumber of the node
|
||||||
std::vector<Node*> mChildren;
|
int32_t mInstanceNumber;
|
||||||
|
|
||||||
//! Name of the node
|
//! Dummy nodes: real name to be combined with the $$$DUMMY
|
||||||
std::string mName;
|
std::string mDummyName;
|
||||||
|
|
||||||
//! InstanceNumber of the node
|
//! Position of the node in the hierarchy (tree depth)
|
||||||
int32_t mInstanceNumber;
|
int16_t mHierarchyPos;
|
||||||
|
|
||||||
//! Dummy nodes: real name to be combined with the $$$DUMMY
|
//! Index of the node
|
||||||
std::string mDummyName;
|
int16_t mHierarchyIndex;
|
||||||
|
|
||||||
//! Position of the node in the hierarchy (tree depth)
|
//! Rotation keys loaded from the file
|
||||||
int16_t mHierarchyPos;
|
std::vector<aiQuatKey> aRotationKeys;
|
||||||
|
|
||||||
//! Index of the node
|
//! Position keys loaded from the file
|
||||||
int16_t mHierarchyIndex;
|
std::vector<aiVectorKey> aPositionKeys;
|
||||||
|
|
||||||
//! Rotation keys loaded from the file
|
//! Scaling keys loaded from the file
|
||||||
std::vector<aiQuatKey> aRotationKeys;
|
std::vector<aiVectorKey> aScalingKeys;
|
||||||
|
|
||||||
//! Position keys loaded from the file
|
|
||||||
std::vector<aiVectorKey> aPositionKeys;
|
|
||||||
|
|
||||||
//! Scaling keys loaded from the file
|
|
||||||
std::vector<aiVectorKey> aScalingKeys;
|
|
||||||
|
|
||||||
|
|
||||||
// For target lights (spot lights and directional lights):
|
// For target lights (spot lights and directional lights):
|
||||||
// The position of the target
|
// The position of the target
|
||||||
std::vector< aiVectorKey > aTargetPositionKeys;
|
std::vector< aiVectorKey > aTargetPositionKeys;
|
||||||
|
|
||||||
// For cameras: the camera roll angle
|
// For cameras: the camera roll angle
|
||||||
std::vector< aiFloatKey > aCameraRollKeys;
|
std::vector< aiFloatKey > aCameraRollKeys;
|
||||||
|
|
||||||
//! Pivot position loaded from the file
|
//! Pivot position loaded from the file
|
||||||
aiVector3D vPivot;
|
aiVector3D vPivot;
|
||||||
|
|
||||||
//instance count, will be kept only for the first node
|
//instance count, will be kept only for the first node
|
||||||
int32_t mInstanceCount;
|
int32_t mInstanceCount;
|
||||||
|
|
||||||
//! Add a child node, setup the right parent node for it
|
//! Add a child node, setup the right parent node for it
|
||||||
//! \param pc Node to be 'adopted'
|
//! \param pc Node to be 'adopted'
|
||||||
inline Node& push_back(Node* pc)
|
inline Node& push_back(Node* pc)
|
||||||
{
|
{
|
||||||
mChildren.push_back(pc);
|
mChildren.push_back(pc);
|
||||||
pc->mParent = this;
|
pc->mParent = this;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure analogue to aiScene */
|
/** Helper structure analogue to aiScene */
|
||||||
struct Scene
|
struct Scene
|
||||||
{
|
{
|
||||||
//! List of all materials loaded
|
//! List of all materials loaded
|
||||||
//! NOTE: 3ds references materials globally
|
//! NOTE: 3ds references materials globally
|
||||||
std::vector<Material> mMaterials;
|
std::vector<Material> mMaterials;
|
||||||
|
|
||||||
//! List of all meshes loaded
|
//! List of all meshes loaded
|
||||||
std::vector<Mesh> mMeshes;
|
std::vector<Mesh> mMeshes;
|
||||||
|
|
||||||
//! List of all cameras loaded
|
//! List of all cameras loaded
|
||||||
std::vector<aiCamera*> mCameras;
|
std::vector<aiCamera*> mCameras;
|
||||||
|
|
||||||
//! List of all lights loaded
|
//! List of all lights loaded
|
||||||
std::vector<aiLight*> mLights;
|
std::vector<aiLight*> mLights;
|
||||||
|
|
||||||
//! Pointer to the root node of the scene
|
//! Pointer to the root node of the scene
|
||||||
// --- moved to main class
|
// --- moved to main class
|
||||||
// Node* pcRootNode;
|
// Node* pcRootNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
2022
code/3DSLoader.cpp
2022
code/3DSLoader.cpp
File diff suppressed because it is too large
Load Diff
324
code/3DSLoader.h
324
code/3DSLoader.h
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
|
||||||
using namespace D3DS;
|
using namespace D3DS;
|
||||||
|
@ -67,212 +67,212 @@ class Discreet3DSImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Discreet3DSImporter();
|
Discreet3DSImporter();
|
||||||
~Discreet3DSImporter();
|
~Discreet3DSImporter();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details.
|
* See BaseImporter::CanRead() for details.
|
||||||
*/
|
*/
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ReadFile().
|
/** Called prior to ReadFile().
|
||||||
* The function is a request to the importer to update its configuration
|
* The function is a request to the importer to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
*/
|
*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details
|
* See BaseImporter::InternReadFile() for details
|
||||||
*/
|
*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Converts a temporary material to the outer representation
|
/** Converts a temporary material to the outer representation
|
||||||
*/
|
*/
|
||||||
void ConvertMaterial(D3DS::Material& p_cMat,
|
void ConvertMaterial(D3DS::Material& p_cMat,
|
||||||
aiMaterial& p_pcOut);
|
aiMaterial& p_pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Read a chunk
|
/** Read a chunk
|
||||||
*
|
*
|
||||||
* @param pcOut Receives the current chunk
|
* @param pcOut Receives the current chunk
|
||||||
*/
|
*/
|
||||||
void ReadChunk(Discreet3DS::Chunk* pcOut);
|
void ReadChunk(Discreet3DS::Chunk* pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a percentage chunk. mCurrent will point to the next
|
/** Parse a percentage chunk. mCurrent will point to the next
|
||||||
* chunk behind afterwards. If no percentage chunk is found
|
* chunk behind afterwards. If no percentage chunk is found
|
||||||
* QNAN is returned.
|
* QNAN is returned.
|
||||||
*/
|
*/
|
||||||
float ParsePercentageChunk();
|
float ParsePercentageChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a color chunk. mCurrent will point to the next
|
/** Parse a color chunk. mCurrent will point to the next
|
||||||
* chunk behind afterwards. If no color chunk is found
|
* chunk behind afterwards. If no color chunk is found
|
||||||
* QNAN is returned in all members.
|
* QNAN is returned in all members.
|
||||||
*/
|
*/
|
||||||
void ParseColorChunk(aiColor3D* p_pcOut,
|
void ParseColorChunk(aiColor3D* p_pcOut,
|
||||||
bool p_bAcceptPercent = true);
|
bool p_bAcceptPercent = true);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Skip a chunk in the file
|
/** Skip a chunk in the file
|
||||||
*/
|
*/
|
||||||
void SkipChunk();
|
void SkipChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Generate the nodegraph
|
/** Generate the nodegraph
|
||||||
*/
|
*/
|
||||||
void GenerateNodeGraph(aiScene* pcOut);
|
void GenerateNodeGraph(aiScene* pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a main top-level chunk in the file
|
/** Parse a main top-level chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseMainChunk();
|
void ParseMainChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a top-level chunk in the file
|
/** Parse a top-level chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseChunk(const char* name, unsigned int num);
|
void ParseChunk(const char* name, unsigned int num);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a top-level editor chunk in the file
|
/** Parse a top-level editor chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseEditorChunk();
|
void ParseEditorChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a top-level object chunk in the file
|
/** Parse a top-level object chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseObjectChunk();
|
void ParseObjectChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a material chunk in the file
|
/** Parse a material chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseMaterialChunk();
|
void ParseMaterialChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a mesh chunk in the file
|
/** Parse a mesh chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseMeshChunk();
|
void ParseMeshChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a light chunk in the file
|
/** Parse a light chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseLightChunk();
|
void ParseLightChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a camera chunk in the file
|
/** Parse a camera chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseCameraChunk();
|
void ParseCameraChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a face list chunk in the file
|
/** Parse a face list chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseFaceChunk();
|
void ParseFaceChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a keyframe chunk in the file
|
/** Parse a keyframe chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseKeyframeChunk();
|
void ParseKeyframeChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a hierarchy chunk in the file
|
/** Parse a hierarchy chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseHierarchyChunk(uint16_t parent);
|
void ParseHierarchyChunk(uint16_t parent);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a texture chunk in the file
|
/** Parse a texture chunk in the file
|
||||||
*/
|
*/
|
||||||
void ParseTextureChunk(D3DS::Texture* pcOut);
|
void ParseTextureChunk(D3DS::Texture* pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Convert the meshes in the file
|
/** Convert the meshes in the file
|
||||||
*/
|
*/
|
||||||
void ConvertMeshes(aiScene* pcOut);
|
void ConvertMeshes(aiScene* pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Replace the default material in the scene
|
/** Replace the default material in the scene
|
||||||
*/
|
*/
|
||||||
void ReplaceDefaultMaterial();
|
void ReplaceDefaultMaterial();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Convert the whole scene
|
/** Convert the whole scene
|
||||||
*/
|
*/
|
||||||
void ConvertScene(aiScene* pcOut);
|
void ConvertScene(aiScene* pcOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** generate unique vertices for a mesh
|
/** generate unique vertices for a mesh
|
||||||
*/
|
*/
|
||||||
void MakeUnique(D3DS::Mesh& sMesh);
|
void MakeUnique(D3DS::Mesh& sMesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Add a node to the node graph
|
/** Add a node to the node graph
|
||||||
*/
|
*/
|
||||||
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
|
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
|
||||||
aiMatrix4x4& absTrafo);
|
aiMatrix4x4& absTrafo);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Search for a node in the graph.
|
/** Search for a node in the graph.
|
||||||
* Called recursively
|
* Called recursively
|
||||||
*/
|
*/
|
||||||
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
|
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Apply the master scaling factor to the mesh
|
/** Apply the master scaling factor to the mesh
|
||||||
*/
|
*/
|
||||||
void ApplyMasterScale(aiScene* pScene);
|
void ApplyMasterScale(aiScene* pScene);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Clamp all indices in the file to a valid range
|
/** Clamp all indices in the file to a valid range
|
||||||
*/
|
*/
|
||||||
void CheckIndices(D3DS::Mesh& sMesh);
|
void CheckIndices(D3DS::Mesh& sMesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Skip the TCB info in a track key
|
/** Skip the TCB info in a track key
|
||||||
*/
|
*/
|
||||||
void SkipTCBInfo();
|
void SkipTCBInfo();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Stream to read from */
|
/** Stream to read from */
|
||||||
StreamReaderLE* stream;
|
StreamReaderLE* stream;
|
||||||
|
|
||||||
/** Last touched node index */
|
/** Last touched node index */
|
||||||
short mLastNodeIndex;
|
short mLastNodeIndex;
|
||||||
|
|
||||||
/** Current node, root node */
|
/** Current node, root node */
|
||||||
D3DS::Node* mCurrentNode, *mRootNode;
|
D3DS::Node* mCurrentNode, *mRootNode;
|
||||||
|
|
||||||
/** Scene under construction */
|
/** Scene under construction */
|
||||||
D3DS::Scene* mScene;
|
D3DS::Scene* mScene;
|
||||||
|
|
||||||
/** Ambient base color of the scene */
|
/** Ambient base color of the scene */
|
||||||
aiColor3D mClrAmbient;
|
aiColor3D mClrAmbient;
|
||||||
|
|
||||||
/** Master scaling factor of the scene */
|
/** Master scaling factor of the scene */
|
||||||
float mMasterScale;
|
float mMasterScale;
|
||||||
|
|
||||||
/** Path to the background image of the scene */
|
/** Path to the background image of the scene */
|
||||||
std::string mBackgroundImage;
|
std::string mBackgroundImage;
|
||||||
bool bHasBG;
|
bool bHasBG;
|
||||||
|
|
||||||
/** true if PRJ file */
|
/** true if PRJ file */
|
||||||
bool bIsPrj;
|
bool bIsPrj;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
1303
code/ACLoader.cpp
1303
code/ACLoader.cpp
File diff suppressed because it is too large
Load Diff
311
code/ACLoader.h
311
code/ACLoader.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -55,7 +55,7 @@ struct aiMaterial;
|
||||||
struct aiLight;
|
struct aiLight;
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** AC3D (*.ac) importer class
|
/** AC3D (*.ac) importer class
|
||||||
|
@ -63,209 +63,210 @@ namespace Assimp {
|
||||||
class AC3DImporter : public BaseImporter
|
class AC3DImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AC3DImporter();
|
AC3DImporter();
|
||||||
~AC3DImporter();
|
~AC3DImporter();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Represents an AC3D material
|
// Represents an AC3D material
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
Material()
|
Material()
|
||||||
: rgb (0.6f,0.6f,0.6f)
|
: rgb (0.6f,0.6f,0.6f)
|
||||||
, spec (1.f,1.f,1.f)
|
, spec (1.f,1.f,1.f)
|
||||||
, shin (0.f)
|
, shin (0.f)
|
||||||
, trans (0.f)
|
, trans (0.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// base color of the material
|
// base color of the material
|
||||||
aiColor3D rgb;
|
aiColor3D rgb;
|
||||||
|
|
||||||
// ambient color of the material
|
// ambient color of the material
|
||||||
aiColor3D amb;
|
aiColor3D amb;
|
||||||
|
|
||||||
// emissive color of the material
|
// emissive color of the material
|
||||||
aiColor3D emis;
|
aiColor3D emis;
|
||||||
|
|
||||||
// specular color of the material
|
// specular color of the material
|
||||||
aiColor3D spec;
|
aiColor3D spec;
|
||||||
|
|
||||||
// shininess exponent
|
// shininess exponent
|
||||||
float shin;
|
float shin;
|
||||||
|
|
||||||
// transparency. 0 == opaque
|
// transparency. 0 == opaque
|
||||||
float trans;
|
float trans;
|
||||||
|
|
||||||
// name of the material. optional.
|
// name of the material. optional.
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents an AC3D surface
|
// Represents an AC3D surface
|
||||||
struct Surface
|
struct Surface
|
||||||
{
|
{
|
||||||
Surface()
|
Surface()
|
||||||
: mat (0)
|
: mat (0)
|
||||||
, flags (0)
|
, flags (0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
unsigned int mat,flags;
|
unsigned int mat,flags;
|
||||||
|
|
||||||
typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
|
typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
|
||||||
std::vector< SurfaceEntry > entries;
|
std::vector< SurfaceEntry > entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents an AC3D object
|
// Represents an AC3D object
|
||||||
struct Object
|
struct Object
|
||||||
{
|
{
|
||||||
Object()
|
Object()
|
||||||
: type (World)
|
: type (World)
|
||||||
, name( "" )
|
, name( "" )
|
||||||
, children()
|
, children()
|
||||||
, texture( "" )
|
, texture( "" )
|
||||||
, texRepeat( 1.f, 1.f )
|
, texRepeat( 1.f, 1.f )
|
||||||
, texOffset( 0.0f, 0.0f )
|
, texOffset( 0.0f, 0.0f )
|
||||||
, rotation()
|
, rotation()
|
||||||
, translation()
|
, translation()
|
||||||
, vertices()
|
, vertices()
|
||||||
, surfaces()
|
, surfaces()
|
||||||
, numRefs (0)
|
, numRefs (0)
|
||||||
, subDiv (0)
|
, subDiv (0)
|
||||||
{}
|
, crease()
|
||||||
|
{}
|
||||||
|
|
||||||
// Type description
|
// Type description
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
World = 0x0,
|
World = 0x0,
|
||||||
Poly = 0x1,
|
Poly = 0x1,
|
||||||
Group = 0x2,
|
Group = 0x2,
|
||||||
Light = 0x4
|
Light = 0x4
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
// name of the object
|
// name of the object
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
// object children
|
// object children
|
||||||
std::vector<Object> children;
|
std::vector<Object> children;
|
||||||
|
|
||||||
// texture to be assigned to all surfaces of the object
|
// texture to be assigned to all surfaces of the object
|
||||||
std::string texture;
|
std::string texture;
|
||||||
|
|
||||||
// texture repat factors (scaling for all coordinates)
|
// texture repat factors (scaling for all coordinates)
|
||||||
aiVector2D texRepeat, texOffset;
|
aiVector2D texRepeat, texOffset;
|
||||||
|
|
||||||
// rotation matrix
|
// rotation matrix
|
||||||
aiMatrix3x3 rotation;
|
aiMatrix3x3 rotation;
|
||||||
|
|
||||||
// translation vector
|
// translation vector
|
||||||
aiVector3D translation;
|
aiVector3D translation;
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
std::vector<aiVector3D> vertices;
|
std::vector<aiVector3D> vertices;
|
||||||
|
|
||||||
// surfaces
|
// surfaces
|
||||||
std::vector<Surface> surfaces;
|
std::vector<Surface> surfaces;
|
||||||
|
|
||||||
// number of indices (= num verts in verbose format)
|
// number of indices (= num verts in verbose format)
|
||||||
unsigned int numRefs;
|
unsigned int numRefs;
|
||||||
|
|
||||||
// number of subdivisions to be performed on the
|
// number of subdivisions to be performed on the
|
||||||
// imported data
|
// imported data
|
||||||
unsigned int subDiv;
|
unsigned int subDiv;
|
||||||
|
|
||||||
// max angle limit for smoothing
|
// max angle limit for smoothing
|
||||||
float crease;
|
float crease;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details.
|
* See BaseImporter::CanRead() for details.
|
||||||
*/
|
*/
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details */
|
* See #BaseImporter::GetInfo for the details */
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details*/
|
* See BaseImporter::InternReadFile() for details*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ReadFile().
|
/** Called prior to ReadFile().
|
||||||
* The function is a request to the importer to update its configuration
|
* The function is a request to the importer to update its configuration
|
||||||
* basing on the Importer's configuration property list.*/
|
* basing on the Importer's configuration property list.*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Get the next line from the file.
|
/** Get the next line from the file.
|
||||||
* @return false if the end of the file was reached*/
|
* @return false if the end of the file was reached*/
|
||||||
bool GetNextLine();
|
bool GetNextLine();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Load the object section. This method is called recursively to
|
/** Load the object section. This method is called recursively to
|
||||||
* load subobjects, the method returns after a 'kids 0' was
|
* load subobjects, the method returns after a 'kids 0' was
|
||||||
* encountered.
|
* encountered.
|
||||||
* @objects List of output objects*/
|
* @objects List of output objects*/
|
||||||
void LoadObjectSection(std::vector<Object>& objects);
|
void LoadObjectSection(std::vector<Object>& objects);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Convert all objects into meshes and nodes.
|
/** Convert all objects into meshes and nodes.
|
||||||
* @param object Current object to work on
|
* @param object Current object to work on
|
||||||
* @param meshes Pointer to the list of output meshes
|
* @param meshes Pointer to the list of output meshes
|
||||||
* @param outMaterials List of output materials
|
* @param outMaterials List of output materials
|
||||||
* @param materials Material list
|
* @param materials Material list
|
||||||
* @param Scenegraph node for the object */
|
* @param Scenegraph node for the object */
|
||||||
aiNode* ConvertObjectSection(Object& object,
|
aiNode* ConvertObjectSection(Object& object,
|
||||||
std::vector<aiMesh*>& meshes,
|
std::vector<aiMesh*>& meshes,
|
||||||
std::vector<aiMaterial*>& outMaterials,
|
std::vector<aiMaterial*>& outMaterials,
|
||||||
const std::vector<Material>& materials,
|
const std::vector<Material>& materials,
|
||||||
aiNode* parent = NULL);
|
aiNode* parent = NULL);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Convert a material
|
/** Convert a material
|
||||||
* @param object Current object
|
* @param object Current object
|
||||||
* @param matSrc Source material description
|
* @param matSrc Source material description
|
||||||
* @param matDest Destination material to be filled */
|
* @param matDest Destination material to be filled */
|
||||||
void ConvertMaterial(const Object& object,
|
void ConvertMaterial(const Object& object,
|
||||||
const Material& matSrc,
|
const Material& matSrc,
|
||||||
aiMaterial& matDest);
|
aiMaterial& matDest);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
// points to the next data line
|
// points to the next data line
|
||||||
const char* buffer;
|
const char* buffer;
|
||||||
|
|
||||||
// Configuration option: if enabled, up to two meshes
|
// Configuration option: if enabled, up to two meshes
|
||||||
// are generated per material: those faces who have
|
// are generated per material: those faces who have
|
||||||
// their bf cull flags set are separated.
|
// their bf cull flags set are separated.
|
||||||
bool configSplitBFCull;
|
bool configSplitBFCull;
|
||||||
|
|
||||||
// Configuration switch: subdivision surfaces are only
|
// Configuration switch: subdivision surfaces are only
|
||||||
// evaluated if the value is true.
|
// evaluated if the value is true.
|
||||||
bool configEvalSubdivision;
|
bool configEvalSubdivision;
|
||||||
|
|
||||||
// counts how many objects we have in the tree.
|
// counts how many objects we have in the tree.
|
||||||
// basing on this information we can find a
|
// basing on this information we can find a
|
||||||
// good estimate how many meshes we'll have in the final scene.
|
// good estimate how many meshes we'll have in the final scene.
|
||||||
unsigned int mNumMeshes;
|
unsigned int mNumMeshes;
|
||||||
|
|
||||||
// current list of light sources
|
// current list of light sources
|
||||||
std::vector<aiLight*>* mLights;
|
std::vector<aiLight*>* mLights;
|
||||||
|
|
||||||
// name counters
|
// name counters
|
||||||
unsigned int lights, groups, polys, worlds;
|
unsigned int lights, groups, polys, worlds;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
1950
code/ASELoader.cpp
1950
code/ASELoader.cpp
File diff suppressed because it is too large
Load Diff
198
code/ASELoader.h
198
code/ASELoader.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -57,147 +57,147 @@ namespace Assimp {
|
||||||
/** Importer class for the 3DS ASE ASCII format.
|
/** Importer class for the 3DS ASE ASCII format.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ASEImporter : public BaseImporter {
|
class ASEImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
ASEImporter();
|
ASEImporter();
|
||||||
~ASEImporter();
|
~ASEImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details.
|
* See BaseImporter::CanRead() for details.
|
||||||
*/
|
*/
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
*/
|
*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details
|
* See BaseImporter::InternReadFile() for details
|
||||||
*/
|
*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ReadFile().
|
/** Called prior to ReadFile().
|
||||||
* The function is a request to the importer to update its configuration
|
* The function is a request to the importer to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Generate normal vectors basing on smoothing groups
|
/** Generate normal vectors basing on smoothing groups
|
||||||
* (in some cases the normal are already contained in the file)
|
* (in some cases the normal are already contained in the file)
|
||||||
* \param mesh Mesh to work on
|
* \param mesh Mesh to work on
|
||||||
* \return false if the normals have been recomputed
|
* \return false if the normals have been recomputed
|
||||||
*/
|
*/
|
||||||
bool GenerateNormals(ASE::Mesh& mesh);
|
bool GenerateNormals(ASE::Mesh& mesh);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Create valid vertex/normal/UV/color/face lists.
|
/** Create valid vertex/normal/UV/color/face lists.
|
||||||
* All elements are unique, faces have only one set of indices
|
* All elements are unique, faces have only one set of indices
|
||||||
* after this step occurs.
|
* after this step occurs.
|
||||||
* \param mesh Mesh to work on
|
* \param mesh Mesh to work on
|
||||||
*/
|
*/
|
||||||
void BuildUniqueRepresentation(ASE::Mesh& mesh);
|
void BuildUniqueRepresentation(ASE::Mesh& mesh);
|
||||||
|
|
||||||
|
|
||||||
/** Create one-material-per-mesh meshes ;-)
|
/** Create one-material-per-mesh meshes ;-)
|
||||||
* \param mesh Mesh to work with
|
* \param mesh Mesh to work with
|
||||||
* \param Receives the list of all created meshes
|
* \param Receives the list of all created meshes
|
||||||
*/
|
*/
|
||||||
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
|
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Convert a material to a aiMaterial object
|
/** Convert a material to a aiMaterial object
|
||||||
* \param mat Input material
|
* \param mat Input material
|
||||||
*/
|
*/
|
||||||
void ConvertMaterial(ASE::Material& mat);
|
void ConvertMaterial(ASE::Material& mat);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Setup the final material indices for each mesh
|
/** Setup the final material indices for each mesh
|
||||||
*/
|
*/
|
||||||
void BuildMaterialIndices();
|
void BuildMaterialIndices();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Build the node graph
|
/** Build the node graph
|
||||||
*/
|
*/
|
||||||
void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
|
void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Build output cameras
|
/** Build output cameras
|
||||||
*/
|
*/
|
||||||
void BuildCameras();
|
void BuildCameras();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Build output lights
|
/** Build output lights
|
||||||
*/
|
*/
|
||||||
void BuildLights();
|
void BuildLights();
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Build output animations
|
/** Build output animations
|
||||||
*/
|
*/
|
||||||
void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
|
void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Add sub nodes to a node
|
/** Add sub nodes to a node
|
||||||
* \param pcParent parent node to be filled
|
* \param pcParent parent node to be filled
|
||||||
* \param szName Name of the parent node
|
* \param szName Name of the parent node
|
||||||
* \param matrix Current transform
|
* \param matrix Current transform
|
||||||
*/
|
*/
|
||||||
void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
|
void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
|
||||||
aiNode* pcParent,const char* szName);
|
aiNode* pcParent,const char* szName);
|
||||||
|
|
||||||
void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
|
void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
|
||||||
aiNode* pcParent,const char* szName,
|
aiNode* pcParent,const char* szName,
|
||||||
const aiMatrix4x4& matrix);
|
const aiMatrix4x4& matrix);
|
||||||
|
|
||||||
void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
|
void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Generate a default material and add it to the parser's list
|
/** Generate a default material and add it to the parser's list
|
||||||
* Called if no material has been found in the file (rare for ASE,
|
* Called if no material has been found in the file (rare for ASE,
|
||||||
* but not impossible)
|
* but not impossible)
|
||||||
*/
|
*/
|
||||||
void GenerateDefaultMaterial();
|
void GenerateDefaultMaterial();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Parser instance */
|
/** Parser instance */
|
||||||
ASE::Parser* mParser;
|
ASE::Parser* mParser;
|
||||||
|
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
char* mBuffer;
|
char* mBuffer;
|
||||||
|
|
||||||
/** Scene to be filled */
|
/** Scene to be filled */
|
||||||
aiScene* pcScene;
|
aiScene* pcScene;
|
||||||
|
|
||||||
/** Config options: Recompute the normals in every case - WA
|
/** Config options: Recompute the normals in every case - WA
|
||||||
for 3DS Max broken ASE normal export */
|
for 3DS Max broken ASE normal export */
|
||||||
bool configRecomputeNormals;
|
bool configRecomputeNormals;
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
3524
code/ASEParser.cpp
3524
code/ASEParser.cpp
File diff suppressed because it is too large
Load Diff
828
code/ASEParser.h
828
code/ASEParser.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -61,7 +61,7 @@ struct aiCamera;
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
/** Importer class for 3D Studio r3 and r4 3DS files
|
/** Importer class for 3D Studio r3 and r4 3DS files
|
||||||
|
|
588
code/Assimp.cpp
588
code/Assimp.cpp
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -59,39 +59,39 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
# include <boost/thread/thread.hpp>
|
# include <boost/thread/thread.hpp>
|
||||||
# include <boost/thread/mutex.hpp>
|
# include <boost/thread/mutex.hpp>
|
||||||
#endif
|
#endif
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
// underlying structure for aiPropertyStore
|
// underlying structure for aiPropertyStore
|
||||||
typedef BatchLoader::PropertyMap PropertyMap;
|
typedef BatchLoader::PropertyMap PropertyMap;
|
||||||
|
|
||||||
/** Stores the LogStream objects for all active C log streams */
|
/** Stores the LogStream objects for all active C log streams */
|
||||||
struct mpred {
|
struct mpred {
|
||||||
bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
|
bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
|
||||||
return s0.callback<s1.callback&&s0.user<s1.user;
|
return s0.callback<s1.callback&&s0.user<s1.user;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
|
typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
|
||||||
|
|
||||||
/** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
|
/** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
|
||||||
typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
|
typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
|
||||||
|
|
||||||
/** Local storage of all active log streams */
|
/** Local storage of all active log streams */
|
||||||
static LogStreamMap gActiveLogStreams;
|
static LogStreamMap gActiveLogStreams;
|
||||||
|
|
||||||
/** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
|
/** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
|
||||||
static PredefLogStreamMap gPredefinedStreams;
|
static PredefLogStreamMap gPredefinedStreams;
|
||||||
|
|
||||||
/** Error message of the last failed import process */
|
/** Error message of the last failed import process */
|
||||||
static std::string gLastErrorString;
|
static std::string gLastErrorString;
|
||||||
|
|
||||||
/** Verbose logging active or not? */
|
/** Verbose logging active or not? */
|
||||||
static aiBool gVerboseLogging = false;
|
static aiBool gVerboseLogging = false;
|
||||||
|
|
||||||
/** will return all registered importers. */
|
/** will return all registered importers. */
|
||||||
void GetImporterInstanceList(std::vector< BaseImporter* >& out);
|
void GetImporterInstanceList(std::vector< BaseImporter* >& out);
|
||||||
|
@ -110,331 +110,331 @@ static boost::mutex gLogStreamMutex;
|
||||||
class LogToCallbackRedirector : public LogStream
|
class LogToCallbackRedirector : public LogStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LogToCallbackRedirector(const aiLogStream& s)
|
LogToCallbackRedirector(const aiLogStream& s)
|
||||||
: stream (s) {
|
: stream (s) {
|
||||||
ai_assert(NULL != s.callback);
|
ai_assert(NULL != s.callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
~LogToCallbackRedirector() {
|
~LogToCallbackRedirector() {
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
// (HACK) Check whether the 'stream.user' pointer points to a
|
// (HACK) Check whether the 'stream.user' pointer points to a
|
||||||
// custom LogStream allocated by #aiGetPredefinedLogStream.
|
// custom LogStream allocated by #aiGetPredefinedLogStream.
|
||||||
// In this case, we need to delete it, too. Of course, this
|
// In this case, we need to delete it, too. Of course, this
|
||||||
// might cause strange problems, but the chance is quite low.
|
// might cause strange problems, but the chance is quite low.
|
||||||
|
|
||||||
PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
|
PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
|
||||||
gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
|
gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
|
||||||
|
|
||||||
if (it != gPredefinedStreams.end()) {
|
if (it != gPredefinedStreams.end()) {
|
||||||
delete *it;
|
delete *it;
|
||||||
gPredefinedStreams.erase(it);
|
gPredefinedStreams.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @copydoc LogStream::write */
|
/** @copydoc LogStream::write */
|
||||||
void write(const char* message) {
|
void write(const char* message) {
|
||||||
stream.callback(message,stream.user);
|
stream.callback(message,stream.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
aiLogStream stream;
|
aiLogStream stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ReportSceneNotFoundError()
|
void ReportSceneNotFoundError()
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
|
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
|
||||||
"The C-API does not accept scenes produced by the C++ API and vice versa");
|
"The C-API does not accept scenes produced by the C++ API and vice versa");
|
||||||
|
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the given file and returns its content.
|
// Reads the given file and returns its content.
|
||||||
const aiScene* aiImportFile( const char* pFile, unsigned int pFlags)
|
const aiScene* aiImportFile( const char* pFile, unsigned int pFlags)
|
||||||
{
|
{
|
||||||
return aiImportFileEx(pFile,pFlags,NULL);
|
return aiImportFileEx(pFile,pFlags,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS)
|
const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS)
|
||||||
{
|
{
|
||||||
return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
|
return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
|
||||||
aiFileIO* pFS,
|
aiFileIO* pFS,
|
||||||
const aiPropertyStore* props)
|
const aiPropertyStore* props)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pFile);
|
ai_assert(NULL != pFile);
|
||||||
|
|
||||||
const aiScene* scene = NULL;
|
const aiScene* scene = NULL;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// create an Importer for this file
|
// create an Importer for this file
|
||||||
Assimp::Importer* imp = new Assimp::Importer();
|
Assimp::Importer* imp = new Assimp::Importer();
|
||||||
|
|
||||||
// copy properties
|
// copy properties
|
||||||
if(props) {
|
if(props) {
|
||||||
const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
|
const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
|
||||||
ImporterPimpl* pimpl = imp->Pimpl();
|
ImporterPimpl* pimpl = imp->Pimpl();
|
||||||
pimpl->mIntProperties = pp->ints;
|
pimpl->mIntProperties = pp->ints;
|
||||||
pimpl->mFloatProperties = pp->floats;
|
pimpl->mFloatProperties = pp->floats;
|
||||||
pimpl->mStringProperties = pp->strings;
|
pimpl->mStringProperties = pp->strings;
|
||||||
pimpl->mMatrixProperties = pp->matrices;
|
pimpl->mMatrixProperties = pp->matrices;
|
||||||
}
|
}
|
||||||
// setup a custom IO system if necessary
|
// setup a custom IO system if necessary
|
||||||
if (pFS) {
|
if (pFS) {
|
||||||
imp->SetIOHandler( new CIOSystemWrapper (pFS) );
|
imp->SetIOHandler( new CIOSystemWrapper (pFS) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// and have it read the file
|
// and have it read the file
|
||||||
scene = imp->ReadFile( pFile, pFlags);
|
scene = imp->ReadFile( pFile, pFlags);
|
||||||
|
|
||||||
// if succeeded, store the importer in the scene and keep it alive
|
// if succeeded, store the importer in the scene and keep it alive
|
||||||
if( scene) {
|
if( scene) {
|
||||||
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
||||||
priv->mOrigImporter = imp;
|
priv->mOrigImporter = imp;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if failed, extract error code and destroy the import
|
// if failed, extract error code and destroy the import
|
||||||
gLastErrorString = imp->GetErrorString();
|
gLastErrorString = imp->GetErrorString();
|
||||||
delete imp;
|
delete imp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return imported data. If the import failed the pointer is NULL anyways
|
// return imported data. If the import failed the pointer is NULL anyways
|
||||||
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiScene* aiImportFileFromMemory(
|
const aiScene* aiImportFileFromMemory(
|
||||||
const char* pBuffer,
|
const char* pBuffer,
|
||||||
unsigned int pLength,
|
unsigned int pLength,
|
||||||
unsigned int pFlags,
|
unsigned int pFlags,
|
||||||
const char* pHint)
|
const char* pHint)
|
||||||
{
|
{
|
||||||
return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
|
return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiScene* aiImportFileFromMemoryWithProperties(
|
const aiScene* aiImportFileFromMemoryWithProperties(
|
||||||
const char* pBuffer,
|
const char* pBuffer,
|
||||||
unsigned int pLength,
|
unsigned int pLength,
|
||||||
unsigned int pFlags,
|
unsigned int pFlags,
|
||||||
const char* pHint,
|
const char* pHint,
|
||||||
const aiPropertyStore* props)
|
const aiPropertyStore* props)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pBuffer && 0 != pLength);
|
ai_assert(NULL != pBuffer && 0 != pLength);
|
||||||
|
|
||||||
const aiScene* scene = NULL;
|
const aiScene* scene = NULL;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// create an Importer for this file
|
// create an Importer for this file
|
||||||
Assimp::Importer* imp = new Assimp::Importer();
|
Assimp::Importer* imp = new Assimp::Importer();
|
||||||
|
|
||||||
// copy properties
|
// copy properties
|
||||||
if(props) {
|
if(props) {
|
||||||
const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
|
const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
|
||||||
ImporterPimpl* pimpl = imp->Pimpl();
|
ImporterPimpl* pimpl = imp->Pimpl();
|
||||||
pimpl->mIntProperties = pp->ints;
|
pimpl->mIntProperties = pp->ints;
|
||||||
pimpl->mFloatProperties = pp->floats;
|
pimpl->mFloatProperties = pp->floats;
|
||||||
pimpl->mStringProperties = pp->strings;
|
pimpl->mStringProperties = pp->strings;
|
||||||
pimpl->mMatrixProperties = pp->matrices;
|
pimpl->mMatrixProperties = pp->matrices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and have it read the file from the memory buffer
|
// and have it read the file from the memory buffer
|
||||||
scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
|
scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
|
||||||
|
|
||||||
// if succeeded, store the importer in the scene and keep it alive
|
// if succeeded, store the importer in the scene and keep it alive
|
||||||
if( scene) {
|
if( scene) {
|
||||||
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
|
||||||
priv->mOrigImporter = imp;
|
priv->mOrigImporter = imp;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if failed, extract error code and destroy the import
|
// if failed, extract error code and destroy the import
|
||||||
gLastErrorString = imp->GetErrorString();
|
gLastErrorString = imp->GetErrorString();
|
||||||
delete imp;
|
delete imp;
|
||||||
}
|
}
|
||||||
// return imported data. If the import failed the pointer is NULL anyways
|
// return imported data. If the import failed the pointer is NULL anyways
|
||||||
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Releases all resources associated with the given import process.
|
// Releases all resources associated with the given import process.
|
||||||
void aiReleaseImport( const aiScene* pScene)
|
void aiReleaseImport( const aiScene* pScene)
|
||||||
{
|
{
|
||||||
if (!pScene) {
|
if (!pScene) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// find the importer associated with this data
|
// find the importer associated with this data
|
||||||
const ScenePrivateData* priv = ScenePriv(pScene);
|
const ScenePrivateData* priv = ScenePriv(pScene);
|
||||||
if( !priv || !priv->mOrigImporter) {
|
if( !priv || !priv->mOrigImporter) {
|
||||||
delete pScene;
|
delete pScene;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// deleting the Importer also deletes the scene
|
// deleting the Importer also deletes the scene
|
||||||
// Note: the reason that this is not written as 'delete priv->mOrigImporter'
|
// Note: the reason that this is not written as 'delete priv->mOrigImporter'
|
||||||
// is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
|
// is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
|
||||||
Importer* importer = priv->mOrigImporter;
|
Importer* importer = priv->mOrigImporter;
|
||||||
delete importer;
|
delete importer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
|
ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
|
||||||
unsigned int pFlags)
|
unsigned int pFlags)
|
||||||
{
|
{
|
||||||
const aiScene* sc = NULL;
|
const aiScene* sc = NULL;
|
||||||
|
|
||||||
|
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// find the importer associated with this data
|
// find the importer associated with this data
|
||||||
const ScenePrivateData* priv = ScenePriv(pScene);
|
const ScenePrivateData* priv = ScenePriv(pScene);
|
||||||
if( !priv || !priv->mOrigImporter) {
|
if( !priv || !priv->mOrigImporter) {
|
||||||
ReportSceneNotFoundError();
|
ReportSceneNotFoundError();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
|
sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
|
||||||
|
|
||||||
if (!sc) {
|
if (!sc) {
|
||||||
aiReleaseImport(pScene);
|
aiReleaseImport(pScene);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
ASSIMP_END_EXCEPTION_REGION(const aiScene*);
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CallbackToLogRedirector (const char* msg, char* dt)
|
void CallbackToLogRedirector (const char* msg, char* dt)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != msg && NULL != dt);
|
ai_assert(NULL != msg && NULL != dt);
|
||||||
LogStream* s = (LogStream*)dt;
|
LogStream* s = (LogStream*)dt;
|
||||||
|
|
||||||
s->write(msg);
|
s->write(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
|
ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
|
||||||
{
|
{
|
||||||
aiLogStream sout;
|
aiLogStream sout;
|
||||||
|
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
LogStream* stream = LogStream::createDefaultStream(pStream,file);
|
LogStream* stream = LogStream::createDefaultStream(pStream,file);
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
sout.callback = NULL;
|
sout.callback = NULL;
|
||||||
sout.user = NULL;
|
sout.user = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sout.callback = &CallbackToLogRedirector;
|
sout.callback = &CallbackToLogRedirector;
|
||||||
sout.user = (char*)stream;
|
sout.user = (char*)stream;
|
||||||
}
|
}
|
||||||
gPredefinedStreams.push_back(stream);
|
gPredefinedStreams.push_back(stream);
|
||||||
ASSIMP_END_EXCEPTION_REGION(aiLogStream);
|
ASSIMP_END_EXCEPTION_REGION(aiLogStream);
|
||||||
return sout;
|
return sout;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
|
ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LogStream* lg = new LogToCallbackRedirector(*stream);
|
LogStream* lg = new LogToCallbackRedirector(*stream);
|
||||||
gActiveLogStreams[*stream] = lg;
|
gActiveLogStreams[*stream] = lg;
|
||||||
|
|
||||||
if (DefaultLogger::isNullLogger()) {
|
if (DefaultLogger::isNullLogger()) {
|
||||||
DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
|
DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
|
||||||
}
|
}
|
||||||
DefaultLogger::get()->attachStream(lg);
|
DefaultLogger::get()->attachStream(lg);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
|
ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
// find the logstream associated with this data
|
// find the logstream associated with this data
|
||||||
LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
|
LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
|
||||||
// it should be there... else the user is playing fools with us
|
// it should be there... else the user is playing fools with us
|
||||||
if( it == gActiveLogStreams.end()) {
|
if( it == gActiveLogStreams.end()) {
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
DefaultLogger::get()->detatchStream( it->second );
|
DefaultLogger::get()->detatchStream( it->second );
|
||||||
delete it->second;
|
delete it->second;
|
||||||
|
|
||||||
gActiveLogStreams.erase( it);
|
gActiveLogStreams.erase( it);
|
||||||
|
|
||||||
if (gActiveLogStreams.empty()) {
|
if (gActiveLogStreams.empty()) {
|
||||||
DefaultLogger::kill();
|
DefaultLogger::kill();
|
||||||
}
|
}
|
||||||
ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiDetachAllLogStreams(void)
|
ASSIMP_API void aiDetachAllLogStreams(void)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
|
for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
|
||||||
DefaultLogger::get()->detatchStream( it->second );
|
DefaultLogger::get()->detatchStream( it->second );
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
gActiveLogStreams.clear();
|
gActiveLogStreams.clear();
|
||||||
DefaultLogger::kill();
|
DefaultLogger::kill();
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiEnableVerboseLogging(aiBool d)
|
ASSIMP_API void aiEnableVerboseLogging(aiBool d)
|
||||||
{
|
{
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
|
DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
|
||||||
}
|
}
|
||||||
gVerboseLogging = d;
|
gVerboseLogging = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns the error text of the last failed import process.
|
// Returns the error text of the last failed import process.
|
||||||
const char* aiGetErrorString()
|
const char* aiGetErrorString()
|
||||||
{
|
{
|
||||||
return gLastErrorString.c_str();
|
return gLastErrorString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
// Return the description of a importer given its index
|
// Return the description of a importer given its index
|
||||||
const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
|
const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
|
||||||
{
|
{
|
||||||
return Importer().GetImporterInfo(pIndex);
|
return Importer().GetImporterInfo(pIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------
|
||||||
// Return the number of importers
|
// Return the number of importers
|
||||||
size_t aiGetImportFormatCount(void)
|
size_t aiGetImportFormatCount(void)
|
||||||
{
|
{
|
||||||
return Importer().GetImporterCount();
|
return Importer().GetImporterCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -442,195 +442,195 @@ size_t aiGetImportFormatCount(void)
|
||||||
// Returns the error text of the last failed import process.
|
// Returns the error text of the last failed import process.
|
||||||
aiBool aiIsExtensionSupported(const char* szExtension)
|
aiBool aiIsExtensionSupported(const char* szExtension)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szExtension);
|
ai_assert(NULL != szExtension);
|
||||||
aiBool candoit=AI_FALSE;
|
aiBool candoit=AI_FALSE;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// FIXME: no need to create a temporary Importer instance just for that ..
|
// FIXME: no need to create a temporary Importer instance just for that ..
|
||||||
Assimp::Importer tmp;
|
Assimp::Importer tmp;
|
||||||
candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
|
candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
|
||||||
|
|
||||||
ASSIMP_END_EXCEPTION_REGION(aiBool);
|
ASSIMP_END_EXCEPTION_REGION(aiBool);
|
||||||
return candoit;
|
return candoit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a list of all file extensions supported by ASSIMP
|
// Get a list of all file extensions supported by ASSIMP
|
||||||
void aiGetExtensionList(aiString* szOut)
|
void aiGetExtensionList(aiString* szOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szOut);
|
ai_assert(NULL != szOut);
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// FIXME: no need to create a temporary Importer instance just for that ..
|
// FIXME: no need to create a temporary Importer instance just for that ..
|
||||||
Assimp::Importer tmp;
|
Assimp::Importer tmp;
|
||||||
tmp.GetExtensionList(*szOut);
|
tmp.GetExtensionList(*szOut);
|
||||||
|
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get the memory requirements for a particular import.
|
// Get the memory requirements for a particular import.
|
||||||
void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
|
void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
|
||||||
C_STRUCT aiMemoryInfo* in)
|
C_STRUCT aiMemoryInfo* in)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// find the importer associated with this data
|
// find the importer associated with this data
|
||||||
const ScenePrivateData* priv = ScenePriv(pIn);
|
const ScenePrivateData* priv = ScenePriv(pIn);
|
||||||
if( !priv || !priv->mOrigImporter) {
|
if( !priv || !priv->mOrigImporter) {
|
||||||
ReportSceneNotFoundError();
|
ReportSceneNotFoundError();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return priv->mOrigImporter->GetMemoryRequirements(*in);
|
return priv->mOrigImporter->GetMemoryRequirements(*in);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
|
ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
|
||||||
{
|
{
|
||||||
return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
|
return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
|
ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
|
||||||
{
|
{
|
||||||
delete reinterpret_cast<PropertyMap*>(p);
|
delete reinterpret_cast<PropertyMap*>(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importer::SetPropertyInteger
|
// Importer::SetPropertyInteger
|
||||||
ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
|
ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<int>(pp->ints,szName,value);
|
SetGenericProperty<int>(pp->ints,szName,value);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importer::SetPropertyFloat
|
// Importer::SetPropertyFloat
|
||||||
ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, float value)
|
ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, float value)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<float>(pp->floats,szName,value);
|
SetGenericProperty<float>(pp->floats,szName,value);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importer::SetPropertyString
|
// Importer::SetPropertyString
|
||||||
ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
|
ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
|
||||||
const C_STRUCT aiString* st)
|
const C_STRUCT aiString* st)
|
||||||
{
|
{
|
||||||
if (!st) {
|
if (!st) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
|
SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importer::SetPropertyMatrix
|
// Importer::SetPropertyMatrix
|
||||||
ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName,
|
ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName,
|
||||||
const C_STRUCT aiMatrix4x4* mat)
|
const C_STRUCT aiMatrix4x4* mat)
|
||||||
{
|
{
|
||||||
if (!mat) {
|
if (!mat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat);
|
SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Rotation matrix to quaternion
|
// Rotation matrix to quaternion
|
||||||
ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
|
ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != quat && NULL != mat);
|
ai_assert(NULL != quat && NULL != mat);
|
||||||
*quat = aiQuaternion(*mat);
|
*quat = aiQuaternion(*mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Matrix decomposition
|
// Matrix decomposition
|
||||||
ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
|
ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
|
||||||
aiQuaternion* rotation,
|
aiQuaternion* rotation,
|
||||||
aiVector3D* position)
|
aiVector3D* position)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat);
|
ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat);
|
||||||
mat->Decompose(*scaling,*rotation,*position);
|
mat->Decompose(*scaling,*rotation,*position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Matrix transpose
|
// Matrix transpose
|
||||||
ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
|
ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat);
|
ai_assert(NULL != mat);
|
||||||
mat->Transpose();
|
mat->Transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
|
ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat);
|
ai_assert(NULL != mat);
|
||||||
mat->Transpose();
|
mat->Transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Vector transformation
|
// Vector transformation
|
||||||
ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
|
ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
|
||||||
const aiMatrix3x3* mat)
|
const aiMatrix3x3* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat && NULL != vec);
|
ai_assert(NULL != mat && NULL != vec);
|
||||||
*vec *= (*mat);
|
*vec *= (*mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
|
ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
|
||||||
const aiMatrix4x4* mat)
|
const aiMatrix4x4* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat && NULL != vec);
|
ai_assert(NULL != mat && NULL != vec);
|
||||||
*vec *= (*mat);
|
*vec *= (*mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Matrix multiplication
|
// Matrix multiplication
|
||||||
ASSIMP_API void aiMultiplyMatrix4(
|
ASSIMP_API void aiMultiplyMatrix4(
|
||||||
aiMatrix4x4* dst,
|
aiMatrix4x4* dst,
|
||||||
const aiMatrix4x4* src)
|
const aiMatrix4x4* src)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != dst && NULL != src);
|
ai_assert(NULL != dst && NULL != src);
|
||||||
*dst = (*dst) * (*src);
|
*dst = (*dst) * (*src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiMultiplyMatrix3(
|
ASSIMP_API void aiMultiplyMatrix3(
|
||||||
aiMatrix3x3* dst,
|
aiMatrix3x3* dst,
|
||||||
const aiMatrix3x3* src)
|
const aiMatrix3x3* src)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != dst && NULL != src);
|
ai_assert(NULL != dst && NULL != src);
|
||||||
*dst = (*dst) * (*src);
|
*dst = (*dst) * (*src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Matrix identity
|
// Matrix identity
|
||||||
ASSIMP_API void aiIdentityMatrix3(
|
ASSIMP_API void aiIdentityMatrix3(
|
||||||
aiMatrix3x3* mat)
|
aiMatrix3x3* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat);
|
ai_assert(NULL != mat);
|
||||||
*mat = aiMatrix3x3();
|
*mat = aiMatrix3x3();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiIdentityMatrix4(
|
ASSIMP_API void aiIdentityMatrix4(
|
||||||
aiMatrix4x4* mat)
|
aiMatrix4x4* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat);
|
ai_assert(NULL != mat);
|
||||||
*mat = aiMatrix4x4();
|
*mat = aiMatrix4x4();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -54,76 +54,76 @@ using namespace Assimp;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API size_t aiGetExportFormatCount(void)
|
ASSIMP_API size_t aiGetExportFormatCount(void)
|
||||||
{
|
{
|
||||||
return Exporter().GetExportFormatCount();
|
return Exporter().GetExportFormatCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
|
ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
|
||||||
{
|
{
|
||||||
// Note: this is valid as the index always pertains to a builtin exporter,
|
// Note: this is valid as the index always pertains to a builtin exporter,
|
||||||
// for which the returned structure is guaranteed to be of static storage duration.
|
// for which the returned structure is guaranteed to be of static storage duration.
|
||||||
return Exporter().GetExportFormatDescription(pIndex);
|
return Exporter().GetExportFormatDescription(pIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
||||||
{
|
{
|
||||||
if (!pOut || !pIn) {
|
if (!pOut || !pIn) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneCombiner::CopyScene(pOut,pIn,true);
|
SceneCombiner::CopyScene(pOut,pIn,true);
|
||||||
ScenePriv(*pOut)->mIsCopy = true;
|
ScenePriv(*pOut)->mIsCopy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn)
|
ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn)
|
||||||
{
|
{
|
||||||
// note: aiReleaseImport() is also able to delete scene copies, but in addition
|
// note: aiReleaseImport() is also able to delete scene copies, but in addition
|
||||||
// it also handles scenes with import metadata.
|
// it also handles scenes with import metadata.
|
||||||
delete pIn;
|
delete pIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
|
ASSIMP_API aiReturn aiExportScene( const aiScene* pScene, const char* pFormatId, const char* pFileName, unsigned int pPreprocessing )
|
||||||
{
|
{
|
||||||
return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
|
return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
|
ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
|
||||||
{
|
{
|
||||||
Exporter exp;
|
Exporter exp;
|
||||||
|
|
||||||
if (pIO) {
|
if (pIO) {
|
||||||
exp.SetIOHandler(new CIOSystemWrapper(pIO));
|
exp.SetIOHandler(new CIOSystemWrapper(pIO));
|
||||||
}
|
}
|
||||||
return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
|
return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
|
ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
|
||||||
{
|
{
|
||||||
Exporter exp;
|
Exporter exp;
|
||||||
if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
|
if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
const aiExportDataBlob* blob = exp.GetOrphanedBlob();
|
const aiExportDataBlob* blob = exp.GetOrphanedBlob();
|
||||||
ai_assert(blob);
|
ai_assert(blob);
|
||||||
|
|
||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
|
ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
|
||||||
{
|
{
|
||||||
delete pData;
|
delete pData;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !ASSIMP_BUILD_NO_EXPORT
|
#endif // !ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,8 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -61,69 +60,69 @@ namespace Assimp{
|
||||||
class B3DImporter : public BaseImporter{
|
class B3DImporter : public BaseImporter{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual const aiImporterDesc* GetInfo () const;
|
virtual const aiImporterDesc* GetInfo () const;
|
||||||
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int ReadByte();
|
int ReadByte();
|
||||||
int ReadInt();
|
int ReadInt();
|
||||||
float ReadFloat();
|
float ReadFloat();
|
||||||
aiVector2D ReadVec2();
|
aiVector2D ReadVec2();
|
||||||
aiVector3D ReadVec3();
|
aiVector3D ReadVec3();
|
||||||
aiQuaternion ReadQuat();
|
aiQuaternion ReadQuat();
|
||||||
std::string ReadString();
|
std::string ReadString();
|
||||||
std::string ReadChunk();
|
std::string ReadChunk();
|
||||||
void ExitChunk();
|
void ExitChunk();
|
||||||
unsigned ChunkSize();
|
unsigned ChunkSize();
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T *to_array( const std::vector<T> &v );
|
T *to_array( const std::vector<T> &v );
|
||||||
|
|
||||||
struct Vertex{
|
struct Vertex{
|
||||||
aiVector3D vertex;
|
aiVector3D vertex;
|
||||||
aiVector3D normal;
|
aiVector3D normal;
|
||||||
aiVector3D texcoords;
|
aiVector3D texcoords;
|
||||||
unsigned char bones[4];
|
unsigned char bones[4];
|
||||||
float weights[4];
|
float weights[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
|
||||||
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
void ReadTEXS();
|
void ReadTEXS();
|
||||||
void ReadBRUS();
|
void ReadBRUS();
|
||||||
|
|
||||||
void ReadVRTS();
|
void ReadVRTS();
|
||||||
void ReadTRIS( int v0 );
|
void ReadTRIS( int v0 );
|
||||||
void ReadMESH();
|
void ReadMESH();
|
||||||
void ReadBONE( int id );
|
void ReadBONE( int id );
|
||||||
void ReadKEYS( aiNodeAnim *nodeAnim );
|
void ReadKEYS( aiNodeAnim *nodeAnim );
|
||||||
void ReadANIM();
|
void ReadANIM();
|
||||||
|
|
||||||
aiNode *ReadNODE( aiNode *parent );
|
aiNode *ReadNODE( aiNode *parent );
|
||||||
|
|
||||||
void ReadBB3D( aiScene *scene );
|
void ReadBB3D( aiScene *scene );
|
||||||
|
|
||||||
unsigned _pos;
|
unsigned _pos;
|
||||||
// unsigned _size;
|
// unsigned _size;
|
||||||
std::vector<unsigned char> _buf;
|
std::vector<unsigned char> _buf;
|
||||||
std::vector<unsigned> _stack;
|
std::vector<unsigned> _stack;
|
||||||
|
|
||||||
std::vector<std::string> _textures;
|
std::vector<std::string> _textures;
|
||||||
std::vector<aiMaterial*> _materials;
|
std::vector<aiMaterial*> _materials;
|
||||||
|
|
||||||
int _vflags,_tcsets,_tcsize;
|
int _vflags,_tcsets,_tcsize;
|
||||||
std::vector<Vertex> _vertices;
|
std::vector<Vertex> _vertices;
|
||||||
|
|
||||||
std::vector<aiNode*> _nodes;
|
std::vector<aiNode*> _nodes;
|
||||||
std::vector<aiMesh*> _meshes;
|
std::vector<aiMesh*> _meshes;
|
||||||
std::vector<aiNodeAnim*> _nodeAnims;
|
std::vector<aiNodeAnim*> _nodeAnims;
|
||||||
std::vector<aiAnimation*> _animations;
|
std::vector<aiAnimation*> _animations;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -55,22 +55,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"BVH Importer (MoCap)",
|
"BVH Importer (MoCap)",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
aiImporterFlags_SupportTextFlavour,
|
aiImporterFlags_SupportTextFlavour,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"bvh"
|
"bvh"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BVHLoader::BVHLoader()
|
BVHLoader::BVHLoader()
|
||||||
: noSkeletonMesh()
|
: mLine(),
|
||||||
|
mAnimTickDuration(),
|
||||||
|
mAnimNumFrames(),
|
||||||
|
noSkeletonMesh()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -82,458 +85,458 @@ BVHLoader::~BVHLoader()
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
|
bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
|
||||||
{
|
{
|
||||||
// check file extension
|
// check file extension
|
||||||
const std::string extension = GetExtension(pFile);
|
const std::string extension = GetExtension(pFile);
|
||||||
|
|
||||||
if( extension == "bvh")
|
if( extension == "bvh")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ((!extension.length() || cs) && pIOHandler) {
|
if ((!extension.length() || cs) && pIOHandler) {
|
||||||
const char* tokens[] = {"HIERARCHY"};
|
const char* tokens[] = {"HIERARCHY"};
|
||||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BVHLoader::SetupProperties(const Importer* pImp)
|
void BVHLoader::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Loader meta information
|
// Loader meta information
|
||||||
const aiImporterDesc* BVHLoader::GetInfo () const
|
const aiImporterDesc* BVHLoader::GetInfo () const
|
||||||
{
|
{
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
mFileName = pFile;
|
mFileName = pFile;
|
||||||
|
|
||||||
// read file into memory
|
// read file into memory
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
if( file.get() == NULL)
|
if( file.get() == NULL)
|
||||||
throw DeadlyImportError( "Failed to open file " + pFile + ".");
|
throw DeadlyImportError( "Failed to open file " + pFile + ".");
|
||||||
|
|
||||||
size_t fileSize = file->FileSize();
|
size_t fileSize = file->FileSize();
|
||||||
if( fileSize == 0)
|
if( fileSize == 0)
|
||||||
throw DeadlyImportError( "File is too small.");
|
throw DeadlyImportError( "File is too small.");
|
||||||
|
|
||||||
mBuffer.resize( fileSize);
|
mBuffer.resize( fileSize);
|
||||||
file->Read( &mBuffer.front(), 1, fileSize);
|
file->Read( &mBuffer.front(), 1, fileSize);
|
||||||
|
|
||||||
// start reading
|
// start reading
|
||||||
mReader = mBuffer.begin();
|
mReader = mBuffer.begin();
|
||||||
mLine = 1;
|
mLine = 1;
|
||||||
ReadStructure( pScene);
|
ReadStructure( pScene);
|
||||||
|
|
||||||
if (!noSkeletonMesh) {
|
if (!noSkeletonMesh) {
|
||||||
// build a dummy mesh for the skeleton so that we see something at least
|
// build a dummy mesh for the skeleton so that we see something at least
|
||||||
SkeletonMeshBuilder meshBuilder( pScene);
|
SkeletonMeshBuilder meshBuilder( pScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct an animation from all the motion data we read
|
// construct an animation from all the motion data we read
|
||||||
CreateAnimation( pScene);
|
CreateAnimation( pScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the file
|
// Reads the file
|
||||||
void BVHLoader::ReadStructure( aiScene* pScene)
|
void BVHLoader::ReadStructure( aiScene* pScene)
|
||||||
{
|
{
|
||||||
// first comes hierarchy
|
// first comes hierarchy
|
||||||
std::string header = GetNextToken();
|
std::string header = GetNextToken();
|
||||||
if( header != "HIERARCHY")
|
if( header != "HIERARCHY")
|
||||||
ThrowException( "Expected header string \"HIERARCHY\".");
|
ThrowException( "Expected header string \"HIERARCHY\".");
|
||||||
ReadHierarchy( pScene);
|
ReadHierarchy( pScene);
|
||||||
|
|
||||||
// then comes the motion data
|
// then comes the motion data
|
||||||
std::string motion = GetNextToken();
|
std::string motion = GetNextToken();
|
||||||
if( motion != "MOTION")
|
if( motion != "MOTION")
|
||||||
ThrowException( "Expected beginning of motion data \"MOTION\".");
|
ThrowException( "Expected beginning of motion data \"MOTION\".");
|
||||||
ReadMotion( pScene);
|
ReadMotion( pScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the hierarchy
|
// Reads the hierarchy
|
||||||
void BVHLoader::ReadHierarchy( aiScene* pScene)
|
void BVHLoader::ReadHierarchy( aiScene* pScene)
|
||||||
{
|
{
|
||||||
std::string root = GetNextToken();
|
std::string root = GetNextToken();
|
||||||
if( root != "ROOT")
|
if( root != "ROOT")
|
||||||
ThrowException( "Expected root node \"ROOT\".");
|
ThrowException( "Expected root node \"ROOT\".");
|
||||||
|
|
||||||
// Go read the hierarchy from here
|
// Go read the hierarchy from here
|
||||||
pScene->mRootNode = ReadNode();
|
pScene->mRootNode = ReadNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a node and recursively its childs and returns the created node;
|
// Reads a node and recursively its childs and returns the created node;
|
||||||
aiNode* BVHLoader::ReadNode()
|
aiNode* BVHLoader::ReadNode()
|
||||||
{
|
{
|
||||||
// first token is name
|
// first token is name
|
||||||
std::string nodeName = GetNextToken();
|
std::string nodeName = GetNextToken();
|
||||||
if( nodeName.empty() || nodeName == "{")
|
if( nodeName.empty() || nodeName == "{")
|
||||||
ThrowException( boost::str( boost::format( "Expected node name, but found \"%s\".") % nodeName));
|
ThrowException( boost::str( boost::format( "Expected node name, but found \"%s\".") % nodeName));
|
||||||
|
|
||||||
// then an opening brace should follow
|
// then an opening brace should follow
|
||||||
std::string openBrace = GetNextToken();
|
std::string openBrace = GetNextToken();
|
||||||
if( openBrace != "{")
|
if( openBrace != "{")
|
||||||
ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
|
ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
|
||||||
|
|
||||||
// Create a node
|
// Create a node
|
||||||
aiNode* node = new aiNode( nodeName);
|
aiNode* node = new aiNode( nodeName);
|
||||||
std::vector<aiNode*> childNodes;
|
std::vector<aiNode*> childNodes;
|
||||||
|
|
||||||
// and create an bone entry for it
|
// and create an bone entry for it
|
||||||
mNodes.push_back( Node( node));
|
mNodes.push_back( Node( node));
|
||||||
Node& internNode = mNodes.back();
|
Node& internNode = mNodes.back();
|
||||||
|
|
||||||
// now read the node's contents
|
// now read the node's contents
|
||||||
while( 1)
|
while( 1)
|
||||||
{
|
{
|
||||||
std::string token = GetNextToken();
|
std::string token = GetNextToken();
|
||||||
|
|
||||||
// node offset to parent node
|
// node offset to parent node
|
||||||
if( token == "OFFSET")
|
if( token == "OFFSET")
|
||||||
ReadNodeOffset( node);
|
ReadNodeOffset( node);
|
||||||
else if( token == "CHANNELS")
|
else if( token == "CHANNELS")
|
||||||
ReadNodeChannels( internNode);
|
ReadNodeChannels( internNode);
|
||||||
else if( token == "JOINT")
|
else if( token == "JOINT")
|
||||||
{
|
{
|
||||||
// child node follows
|
// child node follows
|
||||||
aiNode* child = ReadNode();
|
aiNode* child = ReadNode();
|
||||||
child->mParent = node;
|
child->mParent = node;
|
||||||
childNodes.push_back( child);
|
childNodes.push_back( child);
|
||||||
}
|
}
|
||||||
else if( token == "End")
|
else if( token == "End")
|
||||||
{
|
{
|
||||||
// The real symbol is "End Site". Second part comes in a separate token
|
// The real symbol is "End Site". Second part comes in a separate token
|
||||||
std::string siteToken = GetNextToken();
|
std::string siteToken = GetNextToken();
|
||||||
if( siteToken != "Site")
|
if( siteToken != "Site")
|
||||||
ThrowException( boost::str( boost::format( "Expected \"End Site\" keyword, but found \"%s %s\".") % token % siteToken));
|
ThrowException( boost::str( boost::format( "Expected \"End Site\" keyword, but found \"%s %s\".") % token % siteToken));
|
||||||
|
|
||||||
aiNode* child = ReadEndSite( nodeName);
|
aiNode* child = ReadEndSite( nodeName);
|
||||||
child->mParent = node;
|
child->mParent = node;
|
||||||
childNodes.push_back( child);
|
childNodes.push_back( child);
|
||||||
}
|
}
|
||||||
else if( token == "}")
|
else if( token == "}")
|
||||||
{
|
{
|
||||||
// we're done with that part of the hierarchy
|
// we're done with that part of the hierarchy
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// everything else is a parse error
|
// everything else is a parse error
|
||||||
ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
|
ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the child nodes if there are any
|
// add the child nodes if there are any
|
||||||
if( childNodes.size() > 0)
|
if( childNodes.size() > 0)
|
||||||
{
|
{
|
||||||
node->mNumChildren = childNodes.size();
|
node->mNumChildren = childNodes.size();
|
||||||
node->mChildren = new aiNode*[node->mNumChildren];
|
node->mChildren = new aiNode*[node->mNumChildren];
|
||||||
std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
|
std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and return the sub-hierarchy we built here
|
// and return the sub-hierarchy we built here
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an end node and returns the created node.
|
// Reads an end node and returns the created node.
|
||||||
aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
|
aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
|
||||||
{
|
{
|
||||||
// check opening brace
|
// check opening brace
|
||||||
std::string openBrace = GetNextToken();
|
std::string openBrace = GetNextToken();
|
||||||
if( openBrace != "{")
|
if( openBrace != "{")
|
||||||
ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
|
ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
|
||||||
|
|
||||||
// Create a node
|
// Create a node
|
||||||
aiNode* node = new aiNode( "EndSite_" + pParentName);
|
aiNode* node = new aiNode( "EndSite_" + pParentName);
|
||||||
|
|
||||||
// now read the node's contents. Only possible entry is "OFFSET"
|
// now read the node's contents. Only possible entry is "OFFSET"
|
||||||
while( 1)
|
while( 1)
|
||||||
{
|
{
|
||||||
std::string token = GetNextToken();
|
std::string token = GetNextToken();
|
||||||
|
|
||||||
// end node's offset
|
// end node's offset
|
||||||
if( token == "OFFSET")
|
if( token == "OFFSET")
|
||||||
{
|
{
|
||||||
ReadNodeOffset( node);
|
ReadNodeOffset( node);
|
||||||
}
|
}
|
||||||
else if( token == "}")
|
else if( token == "}")
|
||||||
{
|
{
|
||||||
// we're done with the end node
|
// we're done with the end node
|
||||||
break;
|
break;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// everything else is a parse error
|
// everything else is a parse error
|
||||||
ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
|
ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// and return the sub-hierarchy we built here
|
// and return the sub-hierarchy we built here
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a node offset for the given node
|
// Reads a node offset for the given node
|
||||||
void BVHLoader::ReadNodeOffset( aiNode* pNode)
|
void BVHLoader::ReadNodeOffset( aiNode* pNode)
|
||||||
{
|
{
|
||||||
// Offset consists of three floats to read
|
// Offset consists of three floats to read
|
||||||
aiVector3D offset;
|
aiVector3D offset;
|
||||||
offset.x = GetNextTokenAsFloat();
|
offset.x = GetNextTokenAsFloat();
|
||||||
offset.y = GetNextTokenAsFloat();
|
offset.y = GetNextTokenAsFloat();
|
||||||
offset.z = GetNextTokenAsFloat();
|
offset.z = GetNextTokenAsFloat();
|
||||||
|
|
||||||
// build a transformation matrix from it
|
// build a transformation matrix from it
|
||||||
pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y,
|
pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y,
|
||||||
0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f);
|
0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the animation channels for the given node
|
// Reads the animation channels for the given node
|
||||||
void BVHLoader::ReadNodeChannels( BVHLoader::Node& pNode)
|
void BVHLoader::ReadNodeChannels( BVHLoader::Node& pNode)
|
||||||
{
|
{
|
||||||
// number of channels. Use the float reader because we're lazy
|
// number of channels. Use the float reader because we're lazy
|
||||||
float numChannelsFloat = GetNextTokenAsFloat();
|
float numChannelsFloat = GetNextTokenAsFloat();
|
||||||
unsigned int numChannels = (unsigned int) numChannelsFloat;
|
unsigned int numChannels = (unsigned int) numChannelsFloat;
|
||||||
|
|
||||||
for( unsigned int a = 0; a < numChannels; a++)
|
for( unsigned int a = 0; a < numChannels; a++)
|
||||||
{
|
{
|
||||||
std::string channelToken = GetNextToken();
|
std::string channelToken = GetNextToken();
|
||||||
|
|
||||||
if( channelToken == "Xposition")
|
if( channelToken == "Xposition")
|
||||||
pNode.mChannels.push_back( Channel_PositionX);
|
pNode.mChannels.push_back( Channel_PositionX);
|
||||||
else if( channelToken == "Yposition")
|
else if( channelToken == "Yposition")
|
||||||
pNode.mChannels.push_back( Channel_PositionY);
|
pNode.mChannels.push_back( Channel_PositionY);
|
||||||
else if( channelToken == "Zposition")
|
else if( channelToken == "Zposition")
|
||||||
pNode.mChannels.push_back( Channel_PositionZ);
|
pNode.mChannels.push_back( Channel_PositionZ);
|
||||||
else if( channelToken == "Xrotation")
|
else if( channelToken == "Xrotation")
|
||||||
pNode.mChannels.push_back( Channel_RotationX);
|
pNode.mChannels.push_back( Channel_RotationX);
|
||||||
else if( channelToken == "Yrotation")
|
else if( channelToken == "Yrotation")
|
||||||
pNode.mChannels.push_back( Channel_RotationY);
|
pNode.mChannels.push_back( Channel_RotationY);
|
||||||
else if( channelToken == "Zrotation")
|
else if( channelToken == "Zrotation")
|
||||||
pNode.mChannels.push_back( Channel_RotationZ);
|
pNode.mChannels.push_back( Channel_RotationZ);
|
||||||
else
|
else
|
||||||
ThrowException( boost::str( boost::format( "Invalid channel specifier \"%s\".") % channelToken));
|
ThrowException( boost::str( boost::format( "Invalid channel specifier \"%s\".") % channelToken));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the motion data
|
// Reads the motion data
|
||||||
void BVHLoader::ReadMotion( aiScene* /*pScene*/)
|
void BVHLoader::ReadMotion( aiScene* /*pScene*/)
|
||||||
{
|
{
|
||||||
// Read number of frames
|
// Read number of frames
|
||||||
std::string tokenFrames = GetNextToken();
|
std::string tokenFrames = GetNextToken();
|
||||||
if( tokenFrames != "Frames:")
|
if( tokenFrames != "Frames:")
|
||||||
ThrowException( boost::str( boost::format( "Expected frame count \"Frames:\", but found \"%s\".") % tokenFrames));
|
ThrowException( boost::str( boost::format( "Expected frame count \"Frames:\", but found \"%s\".") % tokenFrames));
|
||||||
|
|
||||||
float numFramesFloat = GetNextTokenAsFloat();
|
float numFramesFloat = GetNextTokenAsFloat();
|
||||||
mAnimNumFrames = (unsigned int) numFramesFloat;
|
mAnimNumFrames = (unsigned int) numFramesFloat;
|
||||||
|
|
||||||
// Read frame duration
|
// Read frame duration
|
||||||
std::string tokenDuration1 = GetNextToken();
|
std::string tokenDuration1 = GetNextToken();
|
||||||
std::string tokenDuration2 = GetNextToken();
|
std::string tokenDuration2 = GetNextToken();
|
||||||
if( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
|
if( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
|
||||||
ThrowException( boost::str( boost::format( "Expected frame duration \"Frame Time:\", but found \"%s %s\".") % tokenDuration1 % tokenDuration2));
|
ThrowException( boost::str( boost::format( "Expected frame duration \"Frame Time:\", but found \"%s %s\".") % tokenDuration1 % tokenDuration2));
|
||||||
|
|
||||||
mAnimTickDuration = GetNextTokenAsFloat();
|
mAnimTickDuration = GetNextTokenAsFloat();
|
||||||
|
|
||||||
// resize value vectors for each node
|
// resize value vectors for each node
|
||||||
for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
|
for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
|
||||||
it->mChannelValues.reserve( it->mChannels.size() * mAnimNumFrames);
|
it->mChannelValues.reserve( it->mChannels.size() * mAnimNumFrames);
|
||||||
|
|
||||||
// now read all the data and store it in the corresponding node's value vector
|
// now read all the data and store it in the corresponding node's value vector
|
||||||
for( unsigned int frame = 0; frame < mAnimNumFrames; ++frame)
|
for( unsigned int frame = 0; frame < mAnimNumFrames; ++frame)
|
||||||
{
|
{
|
||||||
// on each line read the values for all nodes
|
// on each line read the values for all nodes
|
||||||
for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
|
for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
|
||||||
{
|
{
|
||||||
// get as many values as the node has channels
|
// get as many values as the node has channels
|
||||||
for( unsigned int c = 0; c < it->mChannels.size(); ++c)
|
for( unsigned int c = 0; c < it->mChannels.size(); ++c)
|
||||||
it->mChannelValues.push_back( GetNextTokenAsFloat());
|
it->mChannelValues.push_back( GetNextTokenAsFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
// after one frame worth of values for all nodes there should be a newline, but we better don't rely on it
|
// after one frame worth of values for all nodes there should be a newline, but we better don't rely on it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Retrieves the next token
|
// Retrieves the next token
|
||||||
std::string BVHLoader::GetNextToken()
|
std::string BVHLoader::GetNextToken()
|
||||||
{
|
{
|
||||||
// skip any preceeding whitespace
|
// skip any preceeding whitespace
|
||||||
while( mReader != mBuffer.end())
|
while( mReader != mBuffer.end())
|
||||||
{
|
{
|
||||||
if( !isspace( *mReader))
|
if( !isspace( *mReader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// count lines
|
// count lines
|
||||||
if( *mReader == '\n')
|
if( *mReader == '\n')
|
||||||
mLine++;
|
mLine++;
|
||||||
|
|
||||||
++mReader;
|
++mReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect all chars till the next whitespace. BVH is easy in respect to that.
|
// collect all chars till the next whitespace. BVH is easy in respect to that.
|
||||||
std::string token;
|
std::string token;
|
||||||
while( mReader != mBuffer.end())
|
while( mReader != mBuffer.end())
|
||||||
{
|
{
|
||||||
if( isspace( *mReader))
|
if( isspace( *mReader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
token.push_back( *mReader);
|
token.push_back( *mReader);
|
||||||
++mReader;
|
++mReader;
|
||||||
|
|
||||||
// little extra logic to make sure braces are counted correctly
|
// little extra logic to make sure braces are counted correctly
|
||||||
if( token == "{" || token == "}")
|
if( token == "{" || token == "}")
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// empty token means end of file, which is just fine
|
// empty token means end of file, which is just fine
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the next token as a float
|
// Reads the next token as a float
|
||||||
float BVHLoader::GetNextTokenAsFloat()
|
float BVHLoader::GetNextTokenAsFloat()
|
||||||
{
|
{
|
||||||
std::string token = GetNextToken();
|
std::string token = GetNextToken();
|
||||||
if( token.empty())
|
if( token.empty())
|
||||||
ThrowException( "Unexpected end of file while trying to read a float");
|
ThrowException( "Unexpected end of file while trying to read a float");
|
||||||
|
|
||||||
// check if the float is valid by testing if the atof() function consumed every char of the token
|
// check if the float is valid by testing if the atof() function consumed every char of the token
|
||||||
const char* ctoken = token.c_str();
|
const char* ctoken = token.c_str();
|
||||||
float result = 0.0f;
|
float result = 0.0f;
|
||||||
ctoken = fast_atoreal_move<float>( ctoken, result);
|
ctoken = fast_atoreal_move<float>( ctoken, result);
|
||||||
|
|
||||||
if( ctoken != token.c_str() + token.length())
|
if( ctoken != token.c_str() + token.length())
|
||||||
ThrowException( boost::str( boost::format( "Expected a floating point number, but found \"%s\".") % token));
|
ThrowException( boost::str( boost::format( "Expected a floating point number, but found \"%s\".") % token));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Aborts the file reading with an exception
|
// Aborts the file reading with an exception
|
||||||
AI_WONT_RETURN void BVHLoader::ThrowException( const std::string& pError)
|
AI_WONT_RETURN void BVHLoader::ThrowException( const std::string& pError)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError( boost::str( boost::format( "%s:%d - %s") % mFileName % mLine % pError));
|
throw DeadlyImportError( boost::str( boost::format( "%s:%d - %s") % mFileName % mLine % pError));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructs an animation for the motion data and stores it in the given scene
|
// Constructs an animation for the motion data and stores it in the given scene
|
||||||
void BVHLoader::CreateAnimation( aiScene* pScene)
|
void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
{
|
{
|
||||||
// create the animation
|
// create the animation
|
||||||
pScene->mNumAnimations = 1;
|
pScene->mNumAnimations = 1;
|
||||||
pScene->mAnimations = new aiAnimation*[1];
|
pScene->mAnimations = new aiAnimation*[1];
|
||||||
aiAnimation* anim = new aiAnimation;
|
aiAnimation* anim = new aiAnimation;
|
||||||
pScene->mAnimations[0] = anim;
|
pScene->mAnimations[0] = anim;
|
||||||
|
|
||||||
// put down the basic parameters
|
// put down the basic parameters
|
||||||
anim->mName.Set( "Motion");
|
anim->mName.Set( "Motion");
|
||||||
anim->mTicksPerSecond = 1.0 / double( mAnimTickDuration);
|
anim->mTicksPerSecond = 1.0 / double( mAnimTickDuration);
|
||||||
anim->mDuration = double( mAnimNumFrames - 1);
|
anim->mDuration = double( mAnimNumFrames - 1);
|
||||||
|
|
||||||
// now generate the tracks for all nodes
|
// now generate the tracks for all nodes
|
||||||
anim->mNumChannels = mNodes.size();
|
anim->mNumChannels = mNodes.size();
|
||||||
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
||||||
|
|
||||||
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
|
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
|
||||||
for (unsigned int i = 0; i < anim->mNumChannels;++i)
|
for (unsigned int i = 0; i < anim->mNumChannels;++i)
|
||||||
anim->mChannels[i] = NULL;
|
anim->mChannels[i] = NULL;
|
||||||
|
|
||||||
for( unsigned int a = 0; a < anim->mNumChannels; a++)
|
for( unsigned int a = 0; a < anim->mNumChannels; a++)
|
||||||
{
|
{
|
||||||
const Node& node = mNodes[a];
|
const Node& node = mNodes[a];
|
||||||
const std::string nodeName = std::string( node.mNode->mName.data );
|
const std::string nodeName = std::string( node.mNode->mName.data );
|
||||||
aiNodeAnim* nodeAnim = new aiNodeAnim;
|
aiNodeAnim* nodeAnim = new aiNodeAnim;
|
||||||
anim->mChannels[a] = nodeAnim;
|
anim->mChannels[a] = nodeAnim;
|
||||||
nodeAnim->mNodeName.Set( nodeName);
|
nodeAnim->mNodeName.Set( nodeName);
|
||||||
|
|
||||||
// translational part, if given
|
// translational part, if given
|
||||||
if( node.mChannels.size() == 6)
|
if( node.mChannels.size() == 6)
|
||||||
{
|
{
|
||||||
nodeAnim->mNumPositionKeys = mAnimNumFrames;
|
nodeAnim->mNumPositionKeys = mAnimNumFrames;
|
||||||
nodeAnim->mPositionKeys = new aiVectorKey[mAnimNumFrames];
|
nodeAnim->mPositionKeys = new aiVectorKey[mAnimNumFrames];
|
||||||
aiVectorKey* poskey = nodeAnim->mPositionKeys;
|
aiVectorKey* poskey = nodeAnim->mPositionKeys;
|
||||||
for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
|
for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
|
||||||
{
|
{
|
||||||
poskey->mTime = double( fr);
|
poskey->mTime = double( fr);
|
||||||
|
|
||||||
// Now compute all translations in the right order
|
// Now compute all translations in the right order
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
for( unsigned int channel = 0; channel < 3; ++channel)
|
||||||
{
|
{
|
||||||
switch( node.mChannels[channel])
|
switch( node.mChannels[channel])
|
||||||
{
|
{
|
||||||
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
||||||
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
||||||
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
|
||||||
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++poskey;
|
++poskey;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// if no translation part is given, put a default sequence
|
// if no translation part is given, put a default sequence
|
||||||
aiVector3D nodePos( node.mNode->mTransformation.a4, node.mNode->mTransformation.b4, node.mNode->mTransformation.c4);
|
aiVector3D nodePos( node.mNode->mTransformation.a4, node.mNode->mTransformation.b4, node.mNode->mTransformation.c4);
|
||||||
nodeAnim->mNumPositionKeys = 1;
|
nodeAnim->mNumPositionKeys = 1;
|
||||||
nodeAnim->mPositionKeys = new aiVectorKey[1];
|
nodeAnim->mPositionKeys = new aiVectorKey[1];
|
||||||
nodeAnim->mPositionKeys[0].mTime = 0.0;
|
nodeAnim->mPositionKeys[0].mTime = 0.0;
|
||||||
nodeAnim->mPositionKeys[0].mValue = nodePos;
|
nodeAnim->mPositionKeys[0].mValue = nodePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rotation part. Always present. First find value offsets
|
// rotation part. Always present. First find value offsets
|
||||||
{
|
{
|
||||||
unsigned int rotOffset = 0;
|
unsigned int rotOffset = 0;
|
||||||
if( node.mChannels.size() == 6)
|
if( node.mChannels.size() == 6)
|
||||||
{
|
{
|
||||||
// Offset all further calculations
|
// Offset all further calculations
|
||||||
rotOffset = 3;
|
rotOffset = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then create the number of rotation keys
|
// Then create the number of rotation keys
|
||||||
nodeAnim->mNumRotationKeys = mAnimNumFrames;
|
nodeAnim->mNumRotationKeys = mAnimNumFrames;
|
||||||
nodeAnim->mRotationKeys = new aiQuatKey[mAnimNumFrames];
|
nodeAnim->mRotationKeys = new aiQuatKey[mAnimNumFrames];
|
||||||
aiQuatKey* rotkey = nodeAnim->mRotationKeys;
|
aiQuatKey* rotkey = nodeAnim->mRotationKeys;
|
||||||
for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
|
for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
|
||||||
{
|
{
|
||||||
aiMatrix4x4 temp;
|
aiMatrix4x4 temp;
|
||||||
aiMatrix3x3 rotMatrix;
|
aiMatrix3x3 rotMatrix;
|
||||||
|
|
||||||
for( unsigned int channel = 0; channel < 3; ++channel)
|
for( unsigned int channel = 0; channel < 3; ++channel)
|
||||||
{
|
{
|
||||||
// translate ZXY euler angels into a quaternion
|
// translate ZXY euler angels into a quaternion
|
||||||
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
|
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
|
||||||
|
|
||||||
// Compute rotation transformations in the right order
|
// Compute rotation transformations in the right order
|
||||||
switch (node.mChannels[rotOffset+channel])
|
switch (node.mChannels[rotOffset+channel])
|
||||||
{
|
{
|
||||||
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
||||||
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
||||||
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
|
||||||
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rotkey->mTime = double( fr);
|
rotkey->mTime = double( fr);
|
||||||
rotkey->mValue = aiQuaternion( rotMatrix);
|
rotkey->mValue = aiQuaternion( rotMatrix);
|
||||||
++rotkey;
|
++rotkey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scaling part. Always just a default track
|
// scaling part. Always just a default track
|
||||||
{
|
{
|
||||||
nodeAnim->mNumScalingKeys = 1;
|
nodeAnim->mNumScalingKeys = 1;
|
||||||
nodeAnim->mScalingKeys = new aiVectorKey[1];
|
nodeAnim->mScalingKeys = new aiVectorKey[1];
|
||||||
nodeAnim->mScalingKeys[0].mTime = 0.0;
|
nodeAnim->mScalingKeys[0].mTime = 0.0;
|
||||||
nodeAnim->mScalingKeys[0].mValue.Set( 1.0f, 1.0f, 1.0f);
|
nodeAnim->mScalingKeys[0].mValue.Set( 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
|
||||||
|
|
138
code/BVHLoader.h
138
code/BVHLoader.h
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -64,106 +64,106 @@ namespace Assimp
|
||||||
class BVHLoader : public BaseImporter
|
class BVHLoader : public BaseImporter
|
||||||
{
|
{
|
||||||
|
|
||||||
/** Possible animation channels for which the motion data holds the values */
|
/** Possible animation channels for which the motion data holds the values */
|
||||||
enum ChannelType
|
enum ChannelType
|
||||||
{
|
{
|
||||||
Channel_PositionX,
|
Channel_PositionX,
|
||||||
Channel_PositionY,
|
Channel_PositionY,
|
||||||
Channel_PositionZ,
|
Channel_PositionZ,
|
||||||
Channel_RotationX,
|
Channel_RotationX,
|
||||||
Channel_RotationY,
|
Channel_RotationY,
|
||||||
Channel_RotationZ
|
Channel_RotationZ
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
|
/** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
const aiNode* mNode;
|
const aiNode* mNode;
|
||||||
std::vector<ChannelType> mChannels;
|
std::vector<ChannelType> mChannels;
|
||||||
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
|
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
|
||||||
|
|
||||||
Node() { }
|
Node() { }
|
||||||
Node( const aiNode* pNode) : mNode( pNode) { }
|
Node( const aiNode* pNode) : mNode( pNode) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BVHLoader();
|
BVHLoader();
|
||||||
~BVHLoader();
|
~BVHLoader();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details. */
|
* See BaseImporter::CanRead() for details. */
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
|
||||||
|
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details
|
* See BaseImporter::InternReadFile() for details
|
||||||
*/
|
*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Reads the file */
|
/** Reads the file */
|
||||||
void ReadStructure( aiScene* pScene);
|
void ReadStructure( aiScene* pScene);
|
||||||
|
|
||||||
/** Reads the hierarchy */
|
/** Reads the hierarchy */
|
||||||
void ReadHierarchy( aiScene* pScene);
|
void ReadHierarchy( aiScene* pScene);
|
||||||
|
|
||||||
/** Reads a node and recursively its childs and returns the created node. */
|
/** Reads a node and recursively its childs and returns the created node. */
|
||||||
aiNode* ReadNode();
|
aiNode* ReadNode();
|
||||||
|
|
||||||
/** Reads an end node and returns the created node. */
|
/** Reads an end node and returns the created node. */
|
||||||
aiNode* ReadEndSite( const std::string& pParentName);
|
aiNode* ReadEndSite( const std::string& pParentName);
|
||||||
|
|
||||||
/** Reads a node offset for the given node */
|
/** Reads a node offset for the given node */
|
||||||
void ReadNodeOffset( aiNode* pNode);
|
void ReadNodeOffset( aiNode* pNode);
|
||||||
|
|
||||||
/** Reads the animation channels into the given node */
|
/** Reads the animation channels into the given node */
|
||||||
void ReadNodeChannels( BVHLoader::Node& pNode);
|
void ReadNodeChannels( BVHLoader::Node& pNode);
|
||||||
|
|
||||||
/** Reads the motion data */
|
/** Reads the motion data */
|
||||||
void ReadMotion( aiScene* pScene);
|
void ReadMotion( aiScene* pScene);
|
||||||
|
|
||||||
/** Retrieves the next token */
|
/** Retrieves the next token */
|
||||||
std::string GetNextToken();
|
std::string GetNextToken();
|
||||||
|
|
||||||
/** Reads the next token as a float */
|
/** Reads the next token as a float */
|
||||||
float GetNextTokenAsFloat();
|
float GetNextTokenAsFloat();
|
||||||
|
|
||||||
/** Aborts the file reading with an exception */
|
/** Aborts the file reading with an exception */
|
||||||
AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
/** Constructs an animation for the motion data and stores it in the given scene */
|
/** Constructs an animation for the motion data and stores it in the given scene */
|
||||||
void CreateAnimation( aiScene* pScene);
|
void CreateAnimation( aiScene* pScene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Filename, for a verbose error message */
|
/** Filename, for a verbose error message */
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** Buffer to hold the loaded file */
|
/** Buffer to hold the loaded file */
|
||||||
std::vector<char> mBuffer;
|
std::vector<char> mBuffer;
|
||||||
|
|
||||||
/** Next char to read from the buffer */
|
/** Next char to read from the buffer */
|
||||||
std::vector<char>::const_iterator mReader;
|
std::vector<char>::const_iterator mReader;
|
||||||
|
|
||||||
/** Current line, for error messages */
|
/** Current line, for error messages */
|
||||||
unsigned int mLine;
|
unsigned int mLine;
|
||||||
|
|
||||||
/** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
|
/** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
|
||||||
* Also contain the motion data for the node's channels
|
* Also contain the motion data for the node's channels
|
||||||
*/
|
*/
|
||||||
std::vector<Node> mNodes;
|
std::vector<Node> mNodes;
|
||||||
|
|
||||||
/** basic Animation parameters */
|
/** basic Animation parameters */
|
||||||
float mAnimTickDuration;
|
float mAnimTickDuration;
|
||||||
unsigned int mAnimNumFrames;
|
unsigned int mAnimNumFrames;
|
||||||
|
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -65,233 +65,241 @@ using namespace Assimp;
|
||||||
BaseImporter::BaseImporter()
|
BaseImporter::BaseImporter()
|
||||||
: progress()
|
: progress()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
BaseImporter::~BaseImporter()
|
BaseImporter::~BaseImporter()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file and returns the imported data.
|
// Imports the given file and returns the imported data.
|
||||||
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
|
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
progress = pImp->GetProgressHandler();
|
progress = pImp->GetProgressHandler();
|
||||||
ai_assert(progress);
|
ai_assert(progress);
|
||||||
|
|
||||||
// Gather configuration properties for this run
|
// Gather configuration properties for this run
|
||||||
SetupProperties( pImp );
|
SetupProperties( pImp );
|
||||||
|
|
||||||
// Construct a file system filter to improve our success ratio at reading external files
|
// Construct a file system filter to improve our success ratio at reading external files
|
||||||
FileSystemFilter filter(pFile,pIOHandler);
|
FileSystemFilter filter(pFile,pIOHandler);
|
||||||
|
|
||||||
// create a scene object to hold the data
|
// create a scene object to hold the data
|
||||||
ScopeGuard<aiScene> sc(new aiScene());
|
ScopeGuard<aiScene> sc(new aiScene());
|
||||||
|
|
||||||
// dispatch importing
|
// dispatch importing
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
InternReadFile( pFile, sc, &filter);
|
InternReadFile( pFile, sc, &filter);
|
||||||
|
|
||||||
} catch( const std::exception& err ) {
|
} catch( const std::exception& err ) {
|
||||||
// extract error description
|
// extract error description
|
||||||
mErrorText = err.what();
|
mErrorText = err.what();
|
||||||
DefaultLogger::get()->error(mErrorText);
|
DefaultLogger::get()->error(mErrorText);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return what we gathered from the import.
|
// return what we gathered from the import.
|
||||||
sc.dismiss();
|
sc.dismiss();
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseImporter::SetupProperties(const Importer* /*pImp*/)
|
void BaseImporter::SetupProperties(const Importer* /*pImp*/)
|
||||||
{
|
{
|
||||||
// the default implementation does nothing
|
// the default implementation does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
{
|
{
|
||||||
const aiImporterDesc* desc = GetInfo();
|
const aiImporterDesc* desc = GetInfo();
|
||||||
ai_assert(desc != NULL);
|
ai_assert(desc != NULL);
|
||||||
|
|
||||||
const char* ext = desc->mFileExtensions;
|
const char* ext = desc->mFileExtensions;
|
||||||
ai_assert(ext != NULL);
|
ai_assert(ext != NULL);
|
||||||
|
|
||||||
const char* last = ext;
|
const char* last = ext;
|
||||||
do {
|
do {
|
||||||
if (!*ext || *ext == ' ') {
|
if (!*ext || *ext == ' ') {
|
||||||
extensions.insert(std::string(last,ext-last));
|
extensions.insert(std::string(last,ext-last));
|
||||||
ai_assert(ext-last > 0);
|
ai_assert(ext-last > 0);
|
||||||
last = ext;
|
last = ext;
|
||||||
while(*last == ' ') {
|
while(*last == ' ') {
|
||||||
++last;
|
++last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(*ext++);
|
while(*ext++);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
|
/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
const char** tokens,
|
const char** tokens,
|
||||||
unsigned int numTokens,
|
unsigned int numTokens,
|
||||||
unsigned int searchBytes /* = 200 */,
|
unsigned int searchBytes /* = 200 */,
|
||||||
bool tokensSol /* false */)
|
bool tokensSol /* false */)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
|
ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
|
||||||
if (!pIOHandler)
|
if (!pIOHandler)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
||||||
if (pStream.get() ) {
|
if (pStream.get() ) {
|
||||||
// read 200 characters from the file
|
// read 200 characters from the file
|
||||||
boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
||||||
char* buffer = _buffer.get();
|
char* buffer = _buffer.get();
|
||||||
|
if( NULL == buffer ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const size_t read = pStream->Read(buffer,1,searchBytes);
|
const size_t read = pStream->Read(buffer,1,searchBytes);
|
||||||
if (!read)
|
if( !read ) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < read; ++i)
|
for( size_t i = 0; i < read; ++i ) {
|
||||||
buffer[i] = ::tolower(buffer[i]);
|
buffer[ i ] = ::tolower( buffer[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
// It is not a proper handling of unicode files here ...
|
// It is not a proper handling of unicode files here ...
|
||||||
// ehm ... but it works in most cases.
|
// ehm ... but it works in most cases.
|
||||||
char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
|
char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
|
||||||
while (cur != end) {
|
while (cur != end) {
|
||||||
if (*cur)
|
if( *cur ) {
|
||||||
*cur2++ = *cur;
|
*cur2++ = *cur;
|
||||||
++cur;
|
}
|
||||||
}
|
++cur;
|
||||||
*cur2 = '\0';
|
}
|
||||||
|
*cur2 = '\0';
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numTokens;++i) {
|
for (unsigned int i = 0; i < numTokens;++i) {
|
||||||
ai_assert(NULL != tokens[i]);
|
ai_assert(NULL != tokens[i]);
|
||||||
|
|
||||||
|
|
||||||
const char* r = strstr(buffer,tokens[i]);
|
const char* r = strstr(buffer,tokens[i]);
|
||||||
if (!r)
|
if( !r ) {
|
||||||
continue;
|
continue;
|
||||||
// We got a match, either we don't care where it is, or it happens to
|
}
|
||||||
// be in the beginning of the file / line
|
// We got a match, either we don't care where it is, or it happens to
|
||||||
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
|
// be in the beginning of the file / line
|
||||||
DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
|
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
|
||||||
return true;
|
DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
|
||||||
}
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Simple check for file extension
|
// Simple check for file extension
|
||||||
/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile,
|
/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile,
|
||||||
const char* ext0,
|
const char* ext0,
|
||||||
const char* ext1,
|
const char* ext1,
|
||||||
const char* ext2)
|
const char* ext2)
|
||||||
{
|
{
|
||||||
std::string::size_type pos = pFile.find_last_of('.');
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
|
|
||||||
// no file extension - can't read
|
// no file extension - can't read
|
||||||
if( pos == std::string::npos)
|
if( pos == std::string::npos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char* ext_real = & pFile[ pos+1 ];
|
const char* ext_real = & pFile[ pos+1 ];
|
||||||
if( !ASSIMP_stricmp(ext_real,ext0) )
|
if( !ASSIMP_stricmp(ext_real,ext0) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// check for other, optional, file extensions
|
// check for other, optional, file extensions
|
||||||
if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
|
if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
|
if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get file extension from path
|
// Get file extension from path
|
||||||
/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
|
/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
|
||||||
{
|
{
|
||||||
std::string::size_type pos = pFile.find_last_of('.');
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
|
|
||||||
// no file extension at all
|
// no file extension at all
|
||||||
if( pos == std::string::npos)
|
if( pos == std::string::npos)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
std::string ret = pFile.substr(pos+1);
|
std::string ret = pFile.substr(pos+1);
|
||||||
std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
|
std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Check for magic bytes at the beginning of the file.
|
// Check for magic bytes at the beginning of the file.
|
||||||
/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
|
/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
|
||||||
const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
|
const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
|
||||||
{
|
{
|
||||||
ai_assert(size <= 16 && _magic);
|
ai_assert(size <= 16 && _magic);
|
||||||
|
|
||||||
if (!pIOHandler) {
|
if (!pIOHandler) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
union {
|
union {
|
||||||
const char* magic;
|
const char* magic;
|
||||||
const uint16_t* magic_u16;
|
const uint16_t* magic_u16;
|
||||||
const uint32_t* magic_u32;
|
const uint32_t* magic_u32;
|
||||||
};
|
};
|
||||||
magic = reinterpret_cast<const char*>(_magic);
|
magic = reinterpret_cast<const char*>(_magic);
|
||||||
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
||||||
if (pStream.get() ) {
|
if (pStream.get() ) {
|
||||||
|
|
||||||
// skip to offset
|
// skip to offset
|
||||||
pStream->Seek(offset,aiOrigin_SET);
|
pStream->Seek(offset,aiOrigin_SET);
|
||||||
|
|
||||||
// read 'size' characters from the file
|
// read 'size' characters from the file
|
||||||
union {
|
union {
|
||||||
char data[16];
|
char data[16];
|
||||||
uint16_t data_u16[8];
|
uint16_t data_u16[8];
|
||||||
uint32_t data_u32[4];
|
uint32_t data_u32[4];
|
||||||
};
|
};
|
||||||
if(size != pStream->Read(data,1,size)) {
|
if(size != pStream->Read(data,1,size)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num; ++i) {
|
for (unsigned int i = 0; i < num; ++i) {
|
||||||
// also check against big endian versions of tokens with size 2,4
|
// also check against big endian versions of tokens with size 2,4
|
||||||
// that's just for convinience, the chance that we cause conflicts
|
// that's just for convinience, the chance that we cause conflicts
|
||||||
// is quite low and it can save some lines and prevent nasty bugs
|
// is quite low and it can save some lines and prevent nasty bugs
|
||||||
if (2 == size) {
|
if (2 == size) {
|
||||||
uint16_t rev = *magic_u16;
|
uint16_t rev = *magic_u16;
|
||||||
ByteSwap::Swap(&rev);
|
ByteSwap::Swap(&rev);
|
||||||
if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
|
if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (4 == size) {
|
else if (4 == size) {
|
||||||
uint32_t rev = *magic_u32;
|
uint32_t rev = *magic_u32;
|
||||||
ByteSwap::Swap(&rev);
|
ByteSwap::Swap(&rev);
|
||||||
if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
|
if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// any length ... just compare
|
// any length ... just compare
|
||||||
if(!memcmp(magic,data,size)) {
|
if(!memcmp(magic,data,size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
magic += size;
|
magic += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
#include "../contrib/ConvertUTF/ConvertUTF.h"
|
||||||
|
@ -299,311 +307,307 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ReportResult(ConversionResult res)
|
void ReportResult(ConversionResult res)
|
||||||
{
|
{
|
||||||
if(res == sourceExhausted) {
|
if(res == sourceExhausted) {
|
||||||
DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
|
DefaultLogger::get()->error("Source ends with incomplete character sequence, transformation to UTF-8 fails");
|
||||||
}
|
}
|
||||||
else if(res == sourceIllegal) {
|
else if(res == sourceIllegal) {
|
||||||
DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
|
DefaultLogger::get()->error("Source contains illegal character sequence, transformation to UTF-8 fails");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert to UTF8 data
|
// Convert to UTF8 data
|
||||||
void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
{
|
{
|
||||||
ConversionResult result;
|
ConversionResult result;
|
||||||
if(data.size() < 8) {
|
if(data.size() < 8) {
|
||||||
throw DeadlyImportError("File is too small");
|
throw DeadlyImportError("File is too small");
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF 8 with BOM
|
// UTF 8 with BOM
|
||||||
if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
|
if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
|
||||||
DefaultLogger::get()->debug("Found UTF-8 BOM ...");
|
DefaultLogger::get()->debug("Found UTF-8 BOM ...");
|
||||||
|
|
||||||
std::copy(data.begin()+3,data.end(),data.begin());
|
std::copy(data.begin()+3,data.end(),data.begin());
|
||||||
data.resize(data.size()-3);
|
data.resize(data.size()-3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF 32 BE with BOM
|
// UTF 32 BE with BOM
|
||||||
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
||||||
|
|
||||||
// swap the endianess ..
|
// swap the endianess ..
|
||||||
for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
|
for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
|
||||||
AI_SWAP4P(p);
|
AI_SWAP4P(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF 32 LE with BOM
|
// UTF 32 LE with BOM
|
||||||
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
|
if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
|
||||||
DefaultLogger::get()->debug("Found UTF-32 BOM ...");
|
DefaultLogger::get()->debug("Found UTF-32 BOM ...");
|
||||||
|
|
||||||
const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
|
const uint32_t* sstart = (uint32_t*)&data.front()+1, *send = (uint32_t*)&data.back()+1;
|
||||||
char* dstart,*dend;
|
char* dstart,*dend;
|
||||||
std::vector<char> output;
|
std::vector<char> output;
|
||||||
do {
|
do {
|
||||||
output.resize(output.size()?output.size()*3/2:data.size()/2);
|
output.resize(output.size()?output.size()*3/2:data.size()/2);
|
||||||
dstart = &output.front(),dend = &output.back()+1;
|
dstart = &output.front(),dend = &output.back()+1;
|
||||||
|
|
||||||
result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
|
result = ConvertUTF32toUTF8((const UTF32**)&sstart,(const UTF32*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
|
||||||
} while(result == targetExhausted);
|
} while(result == targetExhausted);
|
||||||
|
|
||||||
ReportResult(result);
|
ReportResult(result);
|
||||||
|
|
||||||
// copy to output buffer.
|
// copy to output buffer.
|
||||||
const size_t outlen = (size_t)(dstart-&output.front());
|
const size_t outlen = (size_t)(dstart-&output.front());
|
||||||
data.assign(output.begin(),output.begin()+outlen);
|
data.assign(output.begin(),output.begin()+outlen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF 16 BE with BOM
|
// UTF 16 BE with BOM
|
||||||
if(*((uint16_t*)&data.front()) == 0xFFFE) {
|
if(*((uint16_t*)&data.front()) == 0xFFFE) {
|
||||||
|
|
||||||
// swap the endianess ..
|
// swap the endianess ..
|
||||||
for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
|
for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
|
||||||
ByteSwap::Swap2(p);
|
ByteSwap::Swap2(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF 16 LE with BOM
|
// UTF 16 LE with BOM
|
||||||
if(*((uint16_t*)&data.front()) == 0xFEFF) {
|
if(*((uint16_t*)&data.front()) == 0xFEFF) {
|
||||||
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
|
DefaultLogger::get()->debug("Found UTF-16 BOM ...");
|
||||||
|
|
||||||
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
|
const uint16_t* sstart = (uint16_t*)&data.front()+1, *send = (uint16_t*)(&data.back()+1);
|
||||||
char* dstart,*dend;
|
char* dstart,*dend;
|
||||||
std::vector<char> output;
|
std::vector<char> output;
|
||||||
do {
|
do {
|
||||||
output.resize(output.size()?output.size()*3/2:data.size()*3/4);
|
output.resize(output.size()?output.size()*3/2:data.size()*3/4);
|
||||||
dstart = &output.front(),dend = &output.back()+1;
|
dstart = &output.front(),dend = &output.back()+1;
|
||||||
|
|
||||||
result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
|
result = ConvertUTF16toUTF8((const UTF16**)&sstart,(const UTF16*)send,(UTF8**)&dstart,(UTF8*)dend,lenientConversion);
|
||||||
} while(result == targetExhausted);
|
} while(result == targetExhausted);
|
||||||
|
|
||||||
ReportResult(result);
|
ReportResult(result);
|
||||||
|
|
||||||
// copy to output buffer.
|
// copy to output buffer.
|
||||||
const size_t outlen = (size_t)(dstart-&output.front());
|
const size_t outlen = (size_t)(dstart-&output.front());
|
||||||
data.assign(output.begin(),output.begin()+outlen);
|
data.assign(output.begin(),output.begin()+outlen);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert to UTF8 data to ISO-8859-1
|
// Convert to UTF8 data to ISO-8859-1
|
||||||
void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
|
void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
|
||||||
{
|
{
|
||||||
size_t size = data.size();
|
size_t size = data.size();
|
||||||
size_t i = 0, j = 0;
|
size_t i = 0, j = 0;
|
||||||
|
|
||||||
while(i < size) {
|
while(i < size) {
|
||||||
if ((unsigned char) data[i] < (size_t) 0x80) {
|
if ((unsigned char) data[i] < (size_t) 0x80) {
|
||||||
data[j] = data[i];
|
data[j] = data[i];
|
||||||
} else if(i < size - 1) {
|
} else if(i < size - 1) {
|
||||||
if((unsigned char) data[i] == 0xC2) {
|
if((unsigned char) data[i] == 0xC2) {
|
||||||
data[j] = data[++i];
|
data[j] = data[++i];
|
||||||
} else if((unsigned char) data[i] == 0xC3) {
|
} else if((unsigned char) data[i] == 0xC3) {
|
||||||
data[j] = ((unsigned char) data[++i] + 0x40);
|
data[j] = ((unsigned char) data[++i] + 0x40);
|
||||||
} else {
|
} else {
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
|
|
||||||
stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1.";
|
stream << "UTF8 code " << std::hex << data[i] << data[i + 1] << " can not be converted into ISA-8859-1.";
|
||||||
|
|
||||||
DefaultLogger::get()->error(stream.str());
|
DefaultLogger::get()->error(stream.str());
|
||||||
|
|
||||||
data[j++] = data[i++];
|
data[j++] = data[i++];
|
||||||
data[j] = data[i];
|
data[j] = data[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DefaultLogger::get()->error("UTF8 code but only one character remaining");
|
DefaultLogger::get()->error("UTF8 code but only one character remaining");
|
||||||
|
|
||||||
data[j] = data[i];
|
data[j] = data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
i++; j++;
|
i++; j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.resize(j);
|
data.resize(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseImporter::TextFileToBuffer(IOStream* stream,
|
void BaseImporter::TextFileToBuffer(IOStream* stream,
|
||||||
std::vector<char>& data)
|
std::vector<char>& data)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != stream);
|
ai_assert(NULL != stream);
|
||||||
|
|
||||||
const size_t fileSize = stream->FileSize();
|
const size_t fileSize = stream->FileSize();
|
||||||
if(!fileSize) {
|
if(!fileSize) {
|
||||||
throw DeadlyImportError("File is empty");
|
throw DeadlyImportError("File is empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
data.reserve(fileSize+1);
|
data.reserve(fileSize+1);
|
||||||
data.resize(fileSize);
|
data.resize(fileSize);
|
||||||
if(fileSize != stream->Read( &data[0], 1, fileSize)) {
|
if(fileSize != stream->Read( &data[0], 1, fileSize)) {
|
||||||
throw DeadlyImportError("File read error");
|
throw DeadlyImportError("File read error");
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertToUTF8(data);
|
ConvertToUTF8(data);
|
||||||
|
|
||||||
// append a binary zero to simplify string parsing
|
// append a binary zero to simplify string parsing
|
||||||
data.push_back(0);
|
data.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
// Represents an import request
|
// Represents an import request
|
||||||
struct LoadRequest
|
struct LoadRequest
|
||||||
{
|
{
|
||||||
LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
|
LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
|
||||||
: file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
|
: file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
|
||||||
{
|
{
|
||||||
if (_map)
|
if (_map)
|
||||||
map = *_map;
|
map = *_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string file;
|
const std::string file;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned int refCnt;
|
unsigned int refCnt;
|
||||||
aiScene* scene;
|
aiScene* scene;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
BatchLoader::PropertyMap map;
|
BatchLoader::PropertyMap map;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
bool operator== (const std::string& f) {
|
bool operator== (const std::string& f) {
|
||||||
return file == f;
|
return file == f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// BatchLoader::pimpl data structure
|
// BatchLoader::pimpl data structure
|
||||||
struct Assimp::BatchData
|
struct Assimp::BatchData
|
||||||
{
|
{
|
||||||
BatchData()
|
BatchData()
|
||||||
: pIOSystem()
|
: pIOSystem()
|
||||||
, pImporter()
|
, pImporter()
|
||||||
, next_id(0xffff)
|
, next_id(0xffff)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// IO system to be used for all imports
|
// IO system to be used for all imports
|
||||||
IOSystem* pIOSystem;
|
IOSystem* pIOSystem;
|
||||||
|
|
||||||
// Importer used to load all meshes
|
// Importer used to load all meshes
|
||||||
Importer* pImporter;
|
Importer* pImporter;
|
||||||
|
|
||||||
// List of all imports
|
// List of all imports
|
||||||
std::list<LoadRequest> requests;
|
std::list<LoadRequest> requests;
|
||||||
|
|
||||||
// Base path
|
// Base path
|
||||||
std::string pathBase;
|
std::string pathBase;
|
||||||
|
|
||||||
// Id for next item
|
// Id for next item
|
||||||
unsigned int next_id;
|
unsigned int next_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BatchLoader::BatchLoader(IOSystem* pIO)
|
BatchLoader::BatchLoader(IOSystem* pIO)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pIO);
|
ai_assert(NULL != pIO);
|
||||||
|
|
||||||
data = new BatchData();
|
data = new BatchData();
|
||||||
data->pIOSystem = pIO;
|
data->pIOSystem = pIO;
|
||||||
|
|
||||||
data->pImporter = new Importer();
|
data->pImporter = new Importer();
|
||||||
data->pImporter->SetIOHandler(data->pIOSystem);
|
data->pImporter->SetIOHandler(data->pIOSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BatchLoader::~BatchLoader()
|
BatchLoader::~BatchLoader()
|
||||||
{
|
{
|
||||||
// delete all scenes wthat have not been polled by the user
|
// delete all scenes wthat have not been polled by the user
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
||||||
|
|
||||||
delete (*it).scene;
|
delete (*it).scene;
|
||||||
}
|
}
|
||||||
data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
|
data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
|
||||||
delete data->pImporter;
|
delete data->pImporter;
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int BatchLoader::AddLoadRequest (const std::string& file,
|
unsigned int BatchLoader::AddLoadRequest (const std::string& file,
|
||||||
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
|
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
|
||||||
{
|
{
|
||||||
ai_assert(!file.empty());
|
ai_assert(!file.empty());
|
||||||
|
|
||||||
// check whether we have this loading request already
|
// check whether we have this loading request already
|
||||||
std::list<LoadRequest>::iterator it;
|
std::list<LoadRequest>::iterator it;
|
||||||
for (it = data->requests.begin();it != data->requests.end(); ++it) {
|
for (it = data->requests.begin();it != data->requests.end(); ++it) {
|
||||||
|
|
||||||
// Call IOSystem's path comparison function here
|
// Call IOSystem's path comparison function here
|
||||||
if (data->pIOSystem->ComparePaths((*it).file,file)) {
|
if (data->pIOSystem->ComparePaths((*it).file,file)) {
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
if (!((*it).map == *map))
|
if (!((*it).map == *map))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!(*it).map.empty())
|
else if (!(*it).map.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
(*it).refCnt++;
|
(*it).refCnt++;
|
||||||
return (*it).id;
|
return (*it).id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no, we don't have it. So add it to the queue ...
|
// no, we don't have it. So add it to the queue ...
|
||||||
data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
|
data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
|
||||||
return data->next_id++;
|
return data->next_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiScene* BatchLoader::GetImport (unsigned int which)
|
aiScene* BatchLoader::GetImport (unsigned int which)
|
||||||
{
|
{
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
||||||
|
|
||||||
if ((*it).id == which && (*it).loaded) {
|
if ((*it).id == which && (*it).loaded) {
|
||||||
|
|
||||||
aiScene* sc = (*it).scene;
|
aiScene* sc = (*it).scene;
|
||||||
if (!(--(*it).refCnt)) {
|
if (!(--(*it).refCnt)) {
|
||||||
data->requests.erase(it);
|
data->requests.erase(it);
|
||||||
}
|
}
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BatchLoader::LoadAll()
|
void BatchLoader::LoadAll()
|
||||||
{
|
{
|
||||||
// no threaded implementation for the moment
|
// no threaded implementation for the moment
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
||||||
// force validation in debug builds
|
// force validation in debug builds
|
||||||
unsigned int pp = (*it).flags;
|
unsigned int pp = (*it).flags;
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
pp |= aiProcess_ValidateDataStructure;
|
pp |= aiProcess_ValidateDataStructure;
|
||||||
#endif
|
#endif
|
||||||
// setup config properties if necessary
|
// setup config properties if necessary
|
||||||
ImporterPimpl* pimpl = data->pImporter->Pimpl();
|
ImporterPimpl* pimpl = data->pImporter->Pimpl();
|
||||||
pimpl->mFloatProperties = (*it).map.floats;
|
pimpl->mFloatProperties = (*it).map.floats;
|
||||||
pimpl->mIntProperties = (*it).map.ints;
|
pimpl->mIntProperties = (*it).map.ints;
|
||||||
pimpl->mStringProperties = (*it).map.strings;
|
pimpl->mStringProperties = (*it).map.strings;
|
||||||
pimpl->mMatrixProperties = (*it).map.matrices;
|
pimpl->mMatrixProperties = (*it).map.matrices;
|
||||||
|
|
||||||
if (!DefaultLogger::isNullLogger())
|
if (!DefaultLogger::isNullLogger())
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
|
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
|
||||||
DefaultLogger::get()->info("File: " + (*it).file);
|
DefaultLogger::get()->info("File: " + (*it).file);
|
||||||
}
|
}
|
||||||
data->pImporter->ReadFile((*it).file,pp);
|
data->pImporter->ReadFile((*it).file,pp);
|
||||||
(*it).scene = data->pImporter->GetOrphanedScene();
|
(*it).scene = data->pImporter->GetOrphanedScene();
|
||||||
(*it).loaded = true;
|
(*it).loaded = true;
|
||||||
|
|
||||||
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
|
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
class Importer;
|
class Importer;
|
||||||
class IOSystem;
|
class IOSystem;
|
||||||
|
@ -64,32 +64,32 @@ class IOStream;
|
||||||
|
|
||||||
// utility to do char4 to uint32 in a portable manner
|
// utility to do char4 to uint32 in a portable manner
|
||||||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
||||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
(string[1] << 16) + (string[2] << 8) + string[3]))
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ScopeGuard
|
struct ScopeGuard
|
||||||
{
|
{
|
||||||
ScopeGuard(T* obj) : obj(obj), mdismiss() {}
|
ScopeGuard(T* obj) : obj(obj), mdismiss() {}
|
||||||
~ScopeGuard () throw() {
|
~ScopeGuard () throw() {
|
||||||
if (!mdismiss) {
|
if (!mdismiss) {
|
||||||
delete obj;
|
delete obj;
|
||||||
}
|
}
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* dismiss() {
|
T* dismiss() {
|
||||||
mdismiss=true;
|
mdismiss=true;
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator T*() {
|
operator T*() {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* operator -> () {
|
T* operator -> () {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// no copying allowed.
|
// no copying allowed.
|
||||||
|
@ -97,8 +97,8 @@ private:
|
||||||
ScopeGuard( const ScopeGuard & );
|
ScopeGuard( const ScopeGuard & );
|
||||||
ScopeGuard &operator = ( const ScopeGuard & );
|
ScopeGuard &operator = ( const ScopeGuard & );
|
||||||
|
|
||||||
T* obj;
|
T* obj;
|
||||||
bool mdismiss;
|
bool mdismiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,257 +115,257 @@ private:
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API BaseImporter
|
class ASSIMP_API BaseImporter
|
||||||
{
|
{
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Constructor to be privately used by #Importer */
|
/** Constructor to be privately used by #Importer */
|
||||||
BaseImporter();
|
BaseImporter();
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
virtual ~BaseImporter();
|
virtual ~BaseImporter();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
*
|
*
|
||||||
* The implementation should be as quick as possible. A check for
|
* The implementation should be as quick as possible. A check for
|
||||||
* the file extension is enough. If no suitable loader is found with
|
* the file extension is enough. If no suitable loader is found with
|
||||||
* this strategy, CanRead() is called again, the 'checkSig' parameter
|
* this strategy, CanRead() is called again, the 'checkSig' parameter
|
||||||
* set to true this time. Now the implementation is expected to
|
* set to true this time. Now the implementation is expected to
|
||||||
* perform a full check of the file structure, possibly searching the
|
* perform a full check of the file structure, possibly searching the
|
||||||
* first bytes of the file for magic identifiers or keywords.
|
* first bytes of the file for magic identifiers or keywords.
|
||||||
*
|
*
|
||||||
* @param pFile Path and file name of the file to be examined.
|
* @param pFile Path and file name of the file to be examined.
|
||||||
* @param pIOHandler The IO handler to use for accessing any file.
|
* @param pIOHandler The IO handler to use for accessing any file.
|
||||||
* @param checkSig Set to true if this method is called a second time.
|
* @param checkSig Set to true if this method is called a second time.
|
||||||
* This time, the implementation may take more time to examine the
|
* This time, the implementation may take more time to examine the
|
||||||
* contents of the file to be loaded for magic bytes, keywords, etc
|
* contents of the file to be loaded for magic bytes, keywords, etc
|
||||||
* to be able to load files with unknown/not existent file extensions.
|
* to be able to load files with unknown/not existent file extensions.
|
||||||
* @return true if the class can read this file, false if not.
|
* @return true if the class can read this file, false if not.
|
||||||
*/
|
*/
|
||||||
virtual bool CanRead(
|
virtual bool CanRead(
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
IOSystem* pIOHandler,
|
IOSystem* pIOHandler,
|
||||||
bool checkSig
|
bool checkSig
|
||||||
) const = 0;
|
) const = 0;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file and returns the imported data.
|
/** Imports the given file and returns the imported data.
|
||||||
* If the import succeeds, ownership of the data is transferred to
|
* If the import succeeds, ownership of the data is transferred to
|
||||||
* the caller. If the import fails, NULL is returned. The function
|
* the caller. If the import fails, NULL is returned. The function
|
||||||
* takes care that any partially constructed data is destroyed
|
* takes care that any partially constructed data is destroyed
|
||||||
* beforehand.
|
* beforehand.
|
||||||
*
|
*
|
||||||
* @param pImp #Importer object hosting this loader.
|
* @param pImp #Importer object hosting this loader.
|
||||||
* @param pFile Path of the file to be imported.
|
* @param pFile Path of the file to be imported.
|
||||||
* @param pIOHandler IO-Handler used to open this and possible other files.
|
* @param pIOHandler IO-Handler used to open this and possible other files.
|
||||||
* @return The imported data or NULL if failed. If it failed a
|
* @return The imported data or NULL if failed. If it failed a
|
||||||
* human-readable error description can be retrieved by calling
|
* human-readable error description can be retrieved by calling
|
||||||
* GetErrorText()
|
* GetErrorText()
|
||||||
*
|
*
|
||||||
* @note This function is not intended to be overridden. Implement
|
* @note This function is not intended to be overridden. Implement
|
||||||
* InternReadFile() to do the import. If an exception is thrown somewhere
|
* InternReadFile() to do the import. If an exception is thrown somewhere
|
||||||
* in InternReadFile(), this function will catch it and transform it into
|
* in InternReadFile(), this function will catch it and transform it into
|
||||||
* a suitable response to the caller.
|
* a suitable response to the caller.
|
||||||
*/
|
*/
|
||||||
aiScene* ReadFile(
|
aiScene* ReadFile(
|
||||||
const Importer* pImp,
|
const Importer* pImp,
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
IOSystem* pIOHandler
|
IOSystem* pIOHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the error description of the last error that occured.
|
/** Returns the error description of the last error that occured.
|
||||||
* @return A description of the last error that occured. An empty
|
* @return A description of the last error that occured. An empty
|
||||||
* string if there was no error.
|
* string if there was no error.
|
||||||
*/
|
*/
|
||||||
const std::string& GetErrorText() const {
|
const std::string& GetErrorText() const {
|
||||||
return mErrorText;
|
return mErrorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ReadFile().
|
/** Called prior to ReadFile().
|
||||||
* The function is a request to the importer to update its configuration
|
* The function is a request to the importer to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
* @param pImp Importer instance
|
* @param pImp Importer instance
|
||||||
*/
|
*/
|
||||||
virtual void SetupProperties(
|
virtual void SetupProperties(
|
||||||
const Importer* pImp
|
const Importer* pImp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called by #Importer::GetImporterInfo to get a description of
|
/** Called by #Importer::GetImporterInfo to get a description of
|
||||||
* some loader features. Importers must provide this information. */
|
* some loader features. Importers must provide this information. */
|
||||||
virtual const aiImporterDesc* GetInfo() const = 0;
|
virtual const aiImporterDesc* GetInfo() const = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
/** Called by #Importer::GetExtensionList for each loaded importer.
|
||||||
* Take the extension list contained in the structure returned by
|
* Take the extension list contained in the structure returned by
|
||||||
* #GetInfo and insert all file extensions into the given set.
|
* #GetInfo and insert all file extensions into the given set.
|
||||||
* @param extension set to collect file extensions in*/
|
* @param extension set to collect file extensions in*/
|
||||||
void GetExtensionList(std::set<std::string>& extensions);
|
void GetExtensionList(std::set<std::string>& extensions);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure. The
|
/** Imports the given file into the given scene structure. The
|
||||||
* function is expected to throw an ImportErrorException if there is
|
* function is expected to throw an ImportErrorException if there is
|
||||||
* an error. If it terminates normally, the data in aiScene is
|
* an error. If it terminates normally, the data in aiScene is
|
||||||
* expected to be correct. Override this function to implement the
|
* expected to be correct. Override this function to implement the
|
||||||
* actual importing.
|
* actual importing.
|
||||||
* <br>
|
* <br>
|
||||||
* The output scene must meet the following requirements:<br>
|
* The output scene must meet the following requirements:<br>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>At least a root node must be there, even if its only purpose
|
* <li>At least a root node must be there, even if its only purpose
|
||||||
* is to reference one mesh.</li>
|
* is to reference one mesh.</li>
|
||||||
* <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
|
* <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
|
||||||
* in the mesh are determined automatically in this case.</li>
|
* in the mesh are determined automatically in this case.</li>
|
||||||
* <li>the vertex data is stored in a pseudo-indexed "verbose" format.
|
* <li>the vertex data is stored in a pseudo-indexed "verbose" format.
|
||||||
* In fact this means that every vertex that is referenced by
|
* In fact this means that every vertex that is referenced by
|
||||||
* a face is unique. Or the other way round: a vertex index may
|
* a face is unique. Or the other way round: a vertex index may
|
||||||
* not occur twice in a single aiMesh.</li>
|
* not occur twice in a single aiMesh.</li>
|
||||||
* <li>aiAnimation::mDuration may be -1. Assimp determines the length
|
* <li>aiAnimation::mDuration may be -1. Assimp determines the length
|
||||||
* of the animation automatically in this case as the length of
|
* of the animation automatically in this case as the length of
|
||||||
* the longest animation channel.</li>
|
* the longest animation channel.</li>
|
||||||
* <li>aiMesh::mBitangents may be NULL if tangents and normals are
|
* <li>aiMesh::mBitangents may be NULL if tangents and normals are
|
||||||
* given. In this case bitangents are computed as the cross product
|
* given. In this case bitangents are computed as the cross product
|
||||||
* between normal and tangent.</li>
|
* between normal and tangent.</li>
|
||||||
* <li>There needn't be a material. If none is there a default material
|
* <li>There needn't be a material. If none is there a default material
|
||||||
* is generated. However, it is recommended practice for loaders
|
* is generated. However, it is recommended practice for loaders
|
||||||
* to generate a default material for yourself that matches the
|
* to generate a default material for yourself that matches the
|
||||||
* default material setting for the file format better than Assimp's
|
* default material setting for the file format better than Assimp's
|
||||||
* generic default material. Note that default materials *should*
|
* generic default material. Note that default materials *should*
|
||||||
* be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
|
* be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
|
||||||
* or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
|
* or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
|
||||||
* texture. </li>
|
* texture. </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
|
* If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
|
||||||
* <li> at least one mesh must be there</li>
|
* <li> at least one mesh must be there</li>
|
||||||
* <li> there may be no meshes with 0 vertices or faces</li>
|
* <li> there may be no meshes with 0 vertices or faces</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* This won't be checked (except by the validation step): Assimp will
|
* This won't be checked (except by the validation step): Assimp will
|
||||||
* crash if one of the conditions is not met!
|
* crash if one of the conditions is not met!
|
||||||
*
|
*
|
||||||
* @param pFile Path of the file to be imported.
|
* @param pFile Path of the file to be imported.
|
||||||
* @param pScene The scene object to hold the imported data.
|
* @param pScene The scene object to hold the imported data.
|
||||||
* NULL is not a valid parameter.
|
* NULL is not a valid parameter.
|
||||||
* @param pIOHandler The IO handler to use for any file access.
|
* @param pIOHandler The IO handler to use for any file access.
|
||||||
* NULL is not a valid parameter. */
|
* NULL is not a valid parameter. */
|
||||||
virtual void InternReadFile(
|
virtual void InternReadFile(
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
aiScene* pScene,
|
aiScene* pScene,
|
||||||
IOSystem* pIOHandler
|
IOSystem* pIOHandler
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
public: // static utilities
|
public: // static utilities
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** A utility for CanRead().
|
/** A utility for CanRead().
|
||||||
*
|
*
|
||||||
* The function searches the header of a file for a specific token
|
* The function searches the header of a file for a specific token
|
||||||
* and returns true if this token is found. This works for text
|
* and returns true if this token is found. This works for text
|
||||||
* files only. There is a rudimentary handling of UNICODE files.
|
* files only. There is a rudimentary handling of UNICODE files.
|
||||||
* The comparison is case independent.
|
* The comparison is case independent.
|
||||||
*
|
*
|
||||||
* @param pIOSystem IO System to work with
|
* @param pIOSystem IO System to work with
|
||||||
* @param file File name of the file
|
* @param file File name of the file
|
||||||
* @param tokens List of tokens to search for
|
* @param tokens List of tokens to search for
|
||||||
* @param numTokens Size of the token array
|
* @param numTokens Size of the token array
|
||||||
* @param searchBytes Number of bytes to be searched for the tokens.
|
* @param searchBytes Number of bytes to be searched for the tokens.
|
||||||
*/
|
*/
|
||||||
static bool SearchFileHeaderForToken(
|
static bool SearchFileHeaderForToken(
|
||||||
IOSystem* pIOSystem,
|
IOSystem* pIOSystem,
|
||||||
const std::string& file,
|
const std::string& file,
|
||||||
const char** tokens,
|
const char** tokens,
|
||||||
unsigned int numTokens,
|
unsigned int numTokens,
|
||||||
unsigned int searchBytes = 200,
|
unsigned int searchBytes = 200,
|
||||||
bool tokensSol = false);
|
bool tokensSol = false);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Check whether a file has a specific file extension
|
/** @brief Check whether a file has a specific file extension
|
||||||
* @param pFile Input file
|
* @param pFile Input file
|
||||||
* @param ext0 Extension to check for. Lowercase characters only, no dot!
|
* @param ext0 Extension to check for. Lowercase characters only, no dot!
|
||||||
* @param ext1 Optional second extension
|
* @param ext1 Optional second extension
|
||||||
* @param ext2 Optional third extension
|
* @param ext2 Optional third extension
|
||||||
* @note Case-insensitive
|
* @note Case-insensitive
|
||||||
*/
|
*/
|
||||||
static bool SimpleExtensionCheck (
|
static bool SimpleExtensionCheck (
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
const char* ext0,
|
const char* ext0,
|
||||||
const char* ext1 = NULL,
|
const char* ext1 = NULL,
|
||||||
const char* ext2 = NULL);
|
const char* ext2 = NULL);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Extract file extension from a string
|
/** @brief Extract file extension from a string
|
||||||
* @param pFile Input file
|
* @param pFile Input file
|
||||||
* @return Extension without trailing dot, all lowercase
|
* @return Extension without trailing dot, all lowercase
|
||||||
*/
|
*/
|
||||||
static std::string GetExtension (
|
static std::string GetExtension (
|
||||||
const std::string& pFile);
|
const std::string& pFile);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Check whether a file starts with one or more magic tokens
|
/** @brief Check whether a file starts with one or more magic tokens
|
||||||
* @param pFile Input file
|
* @param pFile Input file
|
||||||
* @param pIOHandler IO system to be used
|
* @param pIOHandler IO system to be used
|
||||||
* @param magic n magic tokens
|
* @param magic n magic tokens
|
||||||
* @params num Size of magic
|
* @params num Size of magic
|
||||||
* @param offset Offset from file start where tokens are located
|
* @param offset Offset from file start where tokens are located
|
||||||
* @param Size of one token, in bytes. Maximally 16 bytes.
|
* @param Size of one token, in bytes. Maximally 16 bytes.
|
||||||
* @return true if one of the given tokens was found
|
* @return true if one of the given tokens was found
|
||||||
*
|
*
|
||||||
* @note For convinence, the check is also performed for the
|
* @note For convinence, the check is also performed for the
|
||||||
* byte-swapped variant of all tokens (big endian). Only for
|
* byte-swapped variant of all tokens (big endian). Only for
|
||||||
* tokens of size 2,4.
|
* tokens of size 2,4.
|
||||||
*/
|
*/
|
||||||
static bool CheckMagicToken(
|
static bool CheckMagicToken(
|
||||||
IOSystem* pIOHandler,
|
IOSystem* pIOHandler,
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
const void* magic,
|
const void* magic,
|
||||||
unsigned int num,
|
unsigned int num,
|
||||||
unsigned int offset = 0,
|
unsigned int offset = 0,
|
||||||
unsigned int size = 4);
|
unsigned int size = 4);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** An utility for all text file loaders. It converts a file to our
|
/** An utility for all text file loaders. It converts a file to our
|
||||||
* UTF8 character set. Errors are reported, but ignored.
|
* UTF8 character set. Errors are reported, but ignored.
|
||||||
*
|
*
|
||||||
* @param data File buffer to be converted to UTF8 data. The buffer
|
* @param data File buffer to be converted to UTF8 data. The buffer
|
||||||
* is resized as appropriate. */
|
* is resized as appropriate. */
|
||||||
static void ConvertToUTF8(
|
static void ConvertToUTF8(
|
||||||
std::vector<char>& data);
|
std::vector<char>& data);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** An utility for all text file loaders. It converts a file from our
|
/** An utility for all text file loaders. It converts a file from our
|
||||||
* UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
|
* UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
|
||||||
*
|
*
|
||||||
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
|
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
|
||||||
* is resized as appropriate. */
|
* is resized as appropriate. */
|
||||||
static void ConvertUTF8toISO8859_1(
|
static void ConvertUTF8toISO8859_1(
|
||||||
std::string& data);
|
std::string& data);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Utility for text file loaders which copies the contents of the
|
/** Utility for text file loaders which copies the contents of the
|
||||||
* file into a memory buffer and converts it to our UTF8
|
* file into a memory buffer and converts it to our UTF8
|
||||||
* representation.
|
* representation.
|
||||||
* @param stream Stream to read from.
|
* @param stream Stream to read from.
|
||||||
* @param data Output buffer to be resized and filled with the
|
* @param data Output buffer to be resized and filled with the
|
||||||
* converted text file data. The buffer is terminated with
|
* converted text file data. The buffer is terminated with
|
||||||
* a binary 0. */
|
* a binary 0. */
|
||||||
static void TextFileToBuffer(
|
static void TextFileToBuffer(
|
||||||
IOStream* stream,
|
IOStream* stream,
|
||||||
std::vector<char>& data);
|
std::vector<char>& data);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Error description in case there was one. */
|
/** Error description in case there was one. */
|
||||||
std::string mErrorText;
|
std::string mErrorText;
|
||||||
|
|
||||||
/** Currently set progress handler */
|
/** Currently set progress handler */
|
||||||
ProgressHandler* progress;
|
ProgressHandler* progress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -61,45 +61,45 @@ BaseProcess::BaseProcess()
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
BaseProcess::~BaseProcess()
|
BaseProcess::~BaseProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseProcess::ExecuteOnScene( Importer* pImp)
|
void BaseProcess::ExecuteOnScene( Importer* pImp)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene);
|
ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene);
|
||||||
|
|
||||||
progress = pImp->GetProgressHandler();
|
progress = pImp->GetProgressHandler();
|
||||||
ai_assert(progress);
|
ai_assert(progress);
|
||||||
|
|
||||||
SetupProperties( pImp );
|
SetupProperties( pImp );
|
||||||
|
|
||||||
// catch exceptions thrown inside the PostProcess-Step
|
// catch exceptions thrown inside the PostProcess-Step
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Execute(pImp->Pimpl()->mScene);
|
Execute(pImp->Pimpl()->mScene);
|
||||||
|
|
||||||
} catch( const std::exception& err ) {
|
} catch( const std::exception& err ) {
|
||||||
|
|
||||||
// extract error description
|
// extract error description
|
||||||
pImp->Pimpl()->mErrorString = err.what();
|
pImp->Pimpl()->mErrorString = err.what();
|
||||||
DefaultLogger::get()->error(pImp->Pimpl()->mErrorString);
|
DefaultLogger::get()->error(pImp->Pimpl()->mErrorString);
|
||||||
|
|
||||||
// and kill the partially imported data
|
// and kill the partially imported data
|
||||||
delete pImp->Pimpl()->mScene;
|
delete pImp->Pimpl()->mScene;
|
||||||
pImp->Pimpl()->mScene = NULL;
|
pImp->Pimpl()->mScene = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseProcess::SetupProperties(const Importer* /*pImp*/)
|
void BaseProcess::SetupProperties(const Importer* /*pImp*/)
|
||||||
{
|
{
|
||||||
// the default implementation does nothing
|
// the default implementation does nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BaseProcess::RequireVerboseFormat() const
|
bool BaseProcess::RequireVerboseFormat() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
class Importer;
|
class Importer;
|
||||||
|
|
||||||
|
@ -64,121 +64,121 @@ class SharedPostProcessInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct Base
|
struct Base
|
||||||
{
|
{
|
||||||
virtual ~Base()
|
virtual ~Base()
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Represents data that is allocated on the heap, thus needs to be deleted
|
//! Represents data that is allocated on the heap, thus needs to be deleted
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct THeapData : public Base
|
struct THeapData : public Base
|
||||||
{
|
{
|
||||||
THeapData(T* in)
|
THeapData(T* in)
|
||||||
: data (in)
|
: data (in)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~THeapData()
|
~THeapData()
|
||||||
{
|
{
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
T* data;
|
T* data;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! Represents static, by-value data not allocated on the heap
|
//! Represents static, by-value data not allocated on the heap
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TStaticData : public Base
|
struct TStaticData : public Base
|
||||||
{
|
{
|
||||||
TStaticData(T in)
|
TStaticData(T in)
|
||||||
: data (in)
|
: data (in)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~TStaticData()
|
~TStaticData()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
T data;
|
T data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// some typedefs for cleaner code
|
// some typedefs for cleaner code
|
||||||
typedef unsigned int KeyType;
|
typedef unsigned int KeyType;
|
||||||
typedef std::map<KeyType, Base*> PropertyMap;
|
typedef std::map<KeyType, Base*> PropertyMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Destructor
|
//! Destructor
|
||||||
~SharedPostProcessInfo()
|
~SharedPostProcessInfo()
|
||||||
{
|
{
|
||||||
Clean();
|
Clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Remove all stored properties from the table
|
//! Remove all stored properties from the table
|
||||||
void Clean()
|
void Clean()
|
||||||
{
|
{
|
||||||
// invoke the virtual destructor for all stored properties
|
// invoke the virtual destructor for all stored properties
|
||||||
for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
|
for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
|
||||||
it != end; ++it)
|
it != end; ++it)
|
||||||
{
|
{
|
||||||
delete (*it).second;
|
delete (*it).second;
|
||||||
}
|
}
|
||||||
pmap.clear();
|
pmap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Add a heap property to the list
|
//! Add a heap property to the list
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AddProperty( const char* name, T* in ){
|
void AddProperty( const char* name, T* in ){
|
||||||
AddProperty(name,(Base*)new THeapData<T>(in));
|
AddProperty(name,(Base*)new THeapData<T>(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Add a static by-value property to the list
|
//! Add a static by-value property to the list
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AddProperty( const char* name, T in ){
|
void AddProperty( const char* name, T in ){
|
||||||
AddProperty(name,(Base*)new TStaticData<T>(in));
|
AddProperty(name,(Base*)new TStaticData<T>(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Get a heap property
|
//! Get a heap property
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool GetProperty( const char* name, T*& out ) const
|
bool GetProperty( const char* name, T*& out ) const
|
||||||
{
|
{
|
||||||
THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
|
THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
|
||||||
if(!t)
|
if(!t)
|
||||||
{
|
{
|
||||||
out = NULL;
|
out = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
out = t->data;
|
out = t->data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Get a static, by-value property
|
//! Get a static, by-value property
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool GetProperty( const char* name, T& out ) const
|
bool GetProperty( const char* name, T& out ) const
|
||||||
{
|
{
|
||||||
TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
|
TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
|
||||||
if(!t)return false;
|
if(!t)return false;
|
||||||
out = t->data;
|
out = t->data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Remove a property of a specific type
|
//! Remove a property of a specific type
|
||||||
void RemoveProperty( const char* name) {
|
void RemoveProperty( const char* name) {
|
||||||
SetGenericPropertyPtr<Base>(pmap,name,NULL);
|
SetGenericPropertyPtr<Base>(pmap,name,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void AddProperty( const char* name, Base* data) {
|
void AddProperty( const char* name, Base* data) {
|
||||||
SetGenericPropertyPtr<Base>(pmap,name,data);
|
SetGenericPropertyPtr<Base>(pmap,name,data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Base* GetPropertyInternal( const char* name) const {
|
Base* GetPropertyInternal( const char* name) const {
|
||||||
return GetGenericProperty<Base*>(pmap,name,NULL);
|
return GetGenericProperty<Base*>(pmap,name,NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Map of all stored properties
|
//! Map of all stored properties
|
||||||
PropertyMap pmap;
|
PropertyMap pmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -190,10 +190,10 @@ private:
|
||||||
*/
|
*/
|
||||||
struct PPDependencyTable
|
struct PPDependencyTable
|
||||||
{
|
{
|
||||||
unsigned int execute_me_before_these;
|
unsigned int execute_me_before_these;
|
||||||
unsigned int execute_me_after_these;
|
unsigned int execute_me_after_these;
|
||||||
unsigned int only_if_these_are_not_specified;
|
unsigned int only_if_these_are_not_specified;
|
||||||
unsigned int mutually_exclusive_with;
|
unsigned int mutually_exclusive_with;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -213,79 +213,79 @@ private:
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API_WINONLY BaseProcess
|
class ASSIMP_API_WINONLY BaseProcess
|
||||||
{
|
{
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Constructor to be privately used by Importer */
|
/** Constructor to be privately used by Importer */
|
||||||
BaseProcess();
|
BaseProcess();
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
virtual ~BaseProcess();
|
virtual ~BaseProcess();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
* @param pFlags The processing flags the importer was called with. A
|
* @param pFlags The processing flags the importer was called with. A
|
||||||
* bitwise combination of #aiPostProcessSteps.
|
* bitwise combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
virtual bool IsActive( unsigned int pFlags) const = 0;
|
virtual bool IsActive( unsigned int pFlags) const = 0;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Check whether this step expects its input vertex data to be
|
/** Check whether this step expects its input vertex data to be
|
||||||
* in verbose format. */
|
* in verbose format. */
|
||||||
virtual bool RequireVerboseFormat() const;
|
virtual bool RequireVerboseFormat() const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* The function deletes the scene if the postprocess step fails (
|
* The function deletes the scene if the postprocess step fails (
|
||||||
* the object pointer will be set to NULL).
|
* the object pointer will be set to NULL).
|
||||||
* @param pImp Importer instance (pImp->mScene must be valid)
|
* @param pImp Importer instance (pImp->mScene must be valid)
|
||||||
*/
|
*/
|
||||||
void ExecuteOnScene( Importer* pImp);
|
void ExecuteOnScene( Importer* pImp);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
virtual void SetupProperties(const Importer* pImp);
|
virtual void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* A process should throw an ImportErrorException* if it fails.
|
* A process should throw an ImportErrorException* if it fails.
|
||||||
* This method must be implemented by deriving classes.
|
* This method must be implemented by deriving classes.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
virtual void Execute( aiScene* pScene) = 0;
|
virtual void Execute( aiScene* pScene) = 0;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Assign a new SharedPostProcessInfo to the step. This object
|
/** Assign a new SharedPostProcessInfo to the step. This object
|
||||||
* allows multiple postprocess steps to share data.
|
* allows multiple postprocess steps to share data.
|
||||||
* @param sh May be NULL
|
* @param sh May be NULL
|
||||||
*/
|
*/
|
||||||
inline void SetSharedData(SharedPostProcessInfo* sh) {
|
inline void SetSharedData(SharedPostProcessInfo* sh) {
|
||||||
shared = sh;
|
shared = sh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Get the shared data that is assigned to the step.
|
/** Get the shared data that is assigned to the step.
|
||||||
*/
|
*/
|
||||||
inline SharedPostProcessInfo* GetSharedData() {
|
inline SharedPostProcessInfo* GetSharedData() {
|
||||||
return shared;
|
return shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** See the doc of #SharedPostProcessInfo for more details */
|
/** See the doc of #SharedPostProcessInfo for more details */
|
||||||
SharedPostProcessInfo* shared;
|
SharedPostProcessInfo* shared;
|
||||||
|
|
||||||
/** Currently active progress handler */
|
/** Currently active progress handler */
|
||||||
ProgressHandler* progress;
|
ProgressHandler* progress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
146
code/Bitmap.cpp
146
code/Bitmap.cpp
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -53,95 +53,95 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
void Bitmap::Save(aiTexture* texture, IOStream* file) {
|
void Bitmap::Save(aiTexture* texture, IOStream* file) {
|
||||||
if(file != NULL) {
|
if(file != NULL) {
|
||||||
Header header;
|
Header header;
|
||||||
DIB dib;
|
DIB dib;
|
||||||
|
|
||||||
dib.size = DIB::dib_size;
|
dib.size = DIB::dib_size;
|
||||||
dib.width = texture->mWidth;
|
dib.width = texture->mWidth;
|
||||||
dib.height = texture->mHeight;
|
dib.height = texture->mHeight;
|
||||||
dib.planes = 1;
|
dib.planes = 1;
|
||||||
dib.bits_per_pixel = 8 * mBytesPerPixel;
|
dib.bits_per_pixel = 8 * mBytesPerPixel;
|
||||||
dib.compression = 0;
|
dib.compression = 0;
|
||||||
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
|
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
|
||||||
dib.x_resolution = 0;
|
dib.x_resolution = 0;
|
||||||
dib.y_resolution = 0;
|
dib.y_resolution = 0;
|
||||||
dib.nb_colors = 0;
|
dib.nb_colors = 0;
|
||||||
dib.nb_important_colors = 0;
|
dib.nb_important_colors = 0;
|
||||||
|
|
||||||
header.type = 0x4D42; // 'BM'
|
header.type = 0x4D42; // 'BM'
|
||||||
header.offset = Header::header_size + DIB::dib_size;
|
header.offset = Header::header_size + DIB::dib_size;
|
||||||
header.size = header.offset + dib.image_size;
|
header.size = header.offset + dib.image_size;
|
||||||
header.reserved1 = 0;
|
header.reserved1 = 0;
|
||||||
header.reserved2 = 0;
|
header.reserved2 = 0;
|
||||||
|
|
||||||
WriteHeader(header, file);
|
WriteHeader(header, file);
|
||||||
WriteDIB(dib, file);
|
WriteDIB(dib, file);
|
||||||
WriteData(texture, file);
|
WriteData(texture, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::size_t Copy(uint8_t* data, T& field) {
|
inline std::size_t Copy(uint8_t* data, T& field) {
|
||||||
std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
|
std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::WriteHeader(Header& header, IOStream* file) {
|
void Bitmap::WriteHeader(Header& header, IOStream* file) {
|
||||||
uint8_t data[Header::header_size];
|
uint8_t data[Header::header_size];
|
||||||
|
|
||||||
std::size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
|
|
||||||
offset += Copy(&data[offset], header.type);
|
offset += Copy(&data[offset], header.type);
|
||||||
offset += Copy(&data[offset], header.size);
|
offset += Copy(&data[offset], header.size);
|
||||||
offset += Copy(&data[offset], header.reserved1);
|
offset += Copy(&data[offset], header.reserved1);
|
||||||
offset += Copy(&data[offset], header.reserved2);
|
offset += Copy(&data[offset], header.reserved2);
|
||||||
offset += Copy(&data[offset], header.offset);
|
offset += Copy(&data[offset], header.offset);
|
||||||
|
|
||||||
file->Write(data, Header::header_size, 1);
|
file->Write(data, Header::header_size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::WriteDIB(DIB& dib, IOStream* file) {
|
void Bitmap::WriteDIB(DIB& dib, IOStream* file) {
|
||||||
uint8_t data[DIB::dib_size];
|
uint8_t data[DIB::dib_size];
|
||||||
|
|
||||||
std::size_t offset = 0;
|
std::size_t offset = 0;
|
||||||
|
|
||||||
offset += Copy(&data[offset], dib.size);
|
offset += Copy(&data[offset], dib.size);
|
||||||
offset += Copy(&data[offset], dib.width);
|
offset += Copy(&data[offset], dib.width);
|
||||||
offset += Copy(&data[offset], dib.height);
|
offset += Copy(&data[offset], dib.height);
|
||||||
offset += Copy(&data[offset], dib.planes);
|
offset += Copy(&data[offset], dib.planes);
|
||||||
offset += Copy(&data[offset], dib.bits_per_pixel);
|
offset += Copy(&data[offset], dib.bits_per_pixel);
|
||||||
offset += Copy(&data[offset], dib.compression);
|
offset += Copy(&data[offset], dib.compression);
|
||||||
offset += Copy(&data[offset], dib.image_size);
|
offset += Copy(&data[offset], dib.image_size);
|
||||||
offset += Copy(&data[offset], dib.x_resolution);
|
offset += Copy(&data[offset], dib.x_resolution);
|
||||||
offset += Copy(&data[offset], dib.y_resolution);
|
offset += Copy(&data[offset], dib.y_resolution);
|
||||||
offset += Copy(&data[offset], dib.nb_colors);
|
offset += Copy(&data[offset], dib.nb_colors);
|
||||||
offset += Copy(&data[offset], dib.nb_important_colors);
|
offset += Copy(&data[offset], dib.nb_important_colors);
|
||||||
|
|
||||||
file->Write(data, DIB::dib_size, 1);
|
file->Write(data, DIB::dib_size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::WriteData(aiTexture* texture, IOStream* file) {
|
void Bitmap::WriteData(aiTexture* texture, IOStream* file) {
|
||||||
static const std::size_t padding_offset = 4;
|
static const std::size_t padding_offset = 4;
|
||||||
static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0};
|
static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0};
|
||||||
|
|
||||||
unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset;
|
unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset;
|
||||||
uint8_t pixel[mBytesPerPixel];
|
uint8_t pixel[mBytesPerPixel];
|
||||||
|
|
||||||
for(std::size_t i = 0; i < texture->mHeight; ++i) {
|
for(std::size_t i = 0; i < texture->mHeight; ++i) {
|
||||||
for(std::size_t j = 0; j < texture->mWidth; ++j) {
|
for(std::size_t j = 0; j < texture->mWidth; ++j) {
|
||||||
const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format
|
const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format
|
||||||
|
|
||||||
pixel[0] = texel.r;
|
pixel[0] = texel.r;
|
||||||
pixel[1] = texel.g;
|
pixel[1] = texel.g;
|
||||||
pixel[2] = texel.b;
|
pixel[2] = texel.b;
|
||||||
pixel[3] = texel.a;
|
pixel[3] = texel.a;
|
||||||
|
|
||||||
file->Write(pixel, mBytesPerPixel, 1);
|
file->Write(pixel, mBytesPerPixel, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
file->Write(padding_data, padding, 1);
|
file->Write(padding_data, padding, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
102
code/Bitmap.h
102
code/Bitmap.h
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -57,85 +57,85 @@ namespace Assimp {
|
||||||
class IOStream;
|
class IOStream;
|
||||||
class Bitmap {
|
class Bitmap {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct Header {
|
struct Header {
|
||||||
|
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
|
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
uint16_t reserved1;
|
uint16_t reserved1;
|
||||||
|
|
||||||
uint16_t reserved2;
|
uint16_t reserved2;
|
||||||
|
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
|
|
||||||
// We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
|
// We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
|
||||||
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
||||||
static const std::size_t header_size =
|
static const std::size_t header_size =
|
||||||
sizeof(uint16_t) + // type
|
sizeof(uint16_t) + // type
|
||||||
sizeof(uint32_t) + // size
|
sizeof(uint32_t) + // size
|
||||||
sizeof(uint16_t) + // reserved1
|
sizeof(uint16_t) + // reserved1
|
||||||
sizeof(uint16_t) + // reserved2
|
sizeof(uint16_t) + // reserved2
|
||||||
sizeof(uint32_t); // offset
|
sizeof(uint32_t); // offset
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DIB {
|
struct DIB {
|
||||||
|
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
int32_t width;
|
int32_t width;
|
||||||
|
|
||||||
int32_t height;
|
int32_t height;
|
||||||
|
|
||||||
uint16_t planes;
|
uint16_t planes;
|
||||||
|
|
||||||
uint16_t bits_per_pixel;
|
uint16_t bits_per_pixel;
|
||||||
|
|
||||||
uint32_t compression;
|
uint32_t compression;
|
||||||
|
|
||||||
uint32_t image_size;
|
uint32_t image_size;
|
||||||
|
|
||||||
int32_t x_resolution;
|
int32_t x_resolution;
|
||||||
|
|
||||||
int32_t y_resolution;
|
int32_t y_resolution;
|
||||||
|
|
||||||
uint32_t nb_colors;
|
uint32_t nb_colors;
|
||||||
|
|
||||||
uint32_t nb_important_colors;
|
uint32_t nb_important_colors;
|
||||||
|
|
||||||
// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
|
// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
|
||||||
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
|
||||||
static const std::size_t dib_size =
|
static const std::size_t dib_size =
|
||||||
sizeof(uint32_t) + // size
|
sizeof(uint32_t) + // size
|
||||||
sizeof(int32_t) + // width
|
sizeof(int32_t) + // width
|
||||||
sizeof(int32_t) + // height
|
sizeof(int32_t) + // height
|
||||||
sizeof(uint16_t) + // planes
|
sizeof(uint16_t) + // planes
|
||||||
sizeof(uint16_t) + // bits_per_pixel
|
sizeof(uint16_t) + // bits_per_pixel
|
||||||
sizeof(uint32_t) + // compression
|
sizeof(uint32_t) + // compression
|
||||||
sizeof(uint32_t) + // image_size
|
sizeof(uint32_t) + // image_size
|
||||||
sizeof(int32_t) + // x_resolution
|
sizeof(int32_t) + // x_resolution
|
||||||
sizeof(int32_t) + // y_resolution
|
sizeof(int32_t) + // y_resolution
|
||||||
sizeof(uint32_t) + // nb_colors
|
sizeof(uint32_t) + // nb_colors
|
||||||
sizeof(uint32_t); // nb_important_colors
|
sizeof(uint32_t); // nb_important_colors
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::size_t mBytesPerPixel = 4;
|
static const std::size_t mBytesPerPixel = 4;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void Save(aiTexture* texture, IOStream* file);
|
static void Save(aiTexture* texture, IOStream* file);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void WriteHeader(Header& header, IOStream* file);
|
static void WriteHeader(Header& header, IOStream* file);
|
||||||
|
|
||||||
static void WriteDIB(DIB& dib, IOStream* file);
|
static void WriteDIB(DIB& dib, IOStream* file);
|
||||||
|
|
||||||
static void WriteData(aiTexture* texture, IOStream* file);
|
static void WriteData(aiTexture* texture, IOStream* file);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: ";
|
template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: ";
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -61,142 +61,142 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
|
BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
|
||||||
BMesh( mesh ),
|
BMesh( mesh ),
|
||||||
triMesh( NULL )
|
triMesh( NULL )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BlenderBMeshConverter::~BlenderBMeshConverter( )
|
BlenderBMeshConverter::~BlenderBMeshConverter( )
|
||||||
{
|
{
|
||||||
DestroyTriMesh( );
|
DestroyTriMesh( );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BlenderBMeshConverter::ContainsBMesh( ) const
|
bool BlenderBMeshConverter::ContainsBMesh( ) const
|
||||||
{
|
{
|
||||||
// TODO - Should probably do some additional verification here
|
// TODO - Should probably do some additional verification here
|
||||||
return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
|
return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const Mesh* BlenderBMeshConverter::TriangulateBMesh( )
|
const Mesh* BlenderBMeshConverter::TriangulateBMesh( )
|
||||||
{
|
{
|
||||||
AssertValidMesh( );
|
AssertValidMesh( );
|
||||||
AssertValidSizes( );
|
AssertValidSizes( );
|
||||||
PrepareTriMesh( );
|
PrepareTriMesh( );
|
||||||
|
|
||||||
for ( int i = 0; i < BMesh->totpoly; ++i )
|
for ( int i = 0; i < BMesh->totpoly; ++i )
|
||||||
{
|
{
|
||||||
const MPoly& poly = BMesh->mpoly[ i ];
|
const MPoly& poly = BMesh->mpoly[ i ];
|
||||||
ConvertPolyToFaces( poly );
|
ConvertPolyToFaces( poly );
|
||||||
}
|
}
|
||||||
|
|
||||||
return triMesh;
|
return triMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::AssertValidMesh( )
|
void BlenderBMeshConverter::AssertValidMesh( )
|
||||||
{
|
{
|
||||||
if ( !ContainsBMesh( ) )
|
if ( !ContainsBMesh( ) )
|
||||||
{
|
{
|
||||||
ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" );
|
ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::AssertValidSizes( )
|
void BlenderBMeshConverter::AssertValidSizes( )
|
||||||
{
|
{
|
||||||
if ( BMesh->totpoly != static_cast<int>( BMesh->mpoly.size( ) ) )
|
if ( BMesh->totpoly != static_cast<int>( BMesh->mpoly.size( ) ) )
|
||||||
{
|
{
|
||||||
ThrowException( "BMesh poly array has incorrect size" );
|
ThrowException( "BMesh poly array has incorrect size" );
|
||||||
}
|
}
|
||||||
if ( BMesh->totloop != static_cast<int>( BMesh->mloop.size( ) ) )
|
if ( BMesh->totloop != static_cast<int>( BMesh->mloop.size( ) ) )
|
||||||
{
|
{
|
||||||
ThrowException( "BMesh loop array has incorrect size" );
|
ThrowException( "BMesh loop array has incorrect size" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::PrepareTriMesh( )
|
void BlenderBMeshConverter::PrepareTriMesh( )
|
||||||
{
|
{
|
||||||
if ( triMesh )
|
if ( triMesh )
|
||||||
{
|
{
|
||||||
DestroyTriMesh( );
|
DestroyTriMesh( );
|
||||||
}
|
}
|
||||||
|
|
||||||
triMesh = new Mesh( *BMesh );
|
triMesh = new Mesh( *BMesh );
|
||||||
triMesh->totface = 0;
|
triMesh->totface = 0;
|
||||||
triMesh->mface.clear( );
|
triMesh->mface.clear( );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::DestroyTriMesh( )
|
void BlenderBMeshConverter::DestroyTriMesh( )
|
||||||
{
|
{
|
||||||
delete triMesh;
|
delete triMesh;
|
||||||
triMesh = NULL;
|
triMesh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
|
void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
|
||||||
{
|
{
|
||||||
const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ];
|
const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ];
|
||||||
|
|
||||||
if ( poly.totloop == 3 || poly.totloop == 4 )
|
if ( poly.totloop == 3 || poly.totloop == 4 )
|
||||||
{
|
{
|
||||||
AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 );
|
AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 );
|
||||||
|
|
||||||
// UVs are optional, so only convert when present.
|
// UVs are optional, so only convert when present.
|
||||||
if ( BMesh->mloopuv.size() )
|
if ( BMesh->mloopuv.size() )
|
||||||
{
|
{
|
||||||
if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
|
if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
|
||||||
{
|
{
|
||||||
ThrowException( "BMesh uv loop array has incorrect size" );
|
ThrowException( "BMesh uv loop array has incorrect size" );
|
||||||
}
|
}
|
||||||
const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ];
|
const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ];
|
||||||
AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 );
|
AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( poly.totloop > 4 )
|
else if ( poly.totloop > 4 )
|
||||||
{
|
{
|
||||||
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
BlenderTessellatorGL tessGL( *this );
|
BlenderTessellatorGL tessGL( *this );
|
||||||
tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
|
tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
|
||||||
#elif ASSIMP_BLEND_WITH_POLY_2_TRI
|
#elif ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
BlenderTessellatorP2T tessP2T( *this );
|
BlenderTessellatorP2T tessP2T( *this );
|
||||||
tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
|
tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
|
void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
|
||||||
{
|
{
|
||||||
MFace face;
|
MFace face;
|
||||||
face.v1 = v1;
|
face.v1 = v1;
|
||||||
face.v2 = v2;
|
face.v2 = v2;
|
||||||
face.v3 = v3;
|
face.v3 = v3;
|
||||||
face.v4 = v4;
|
face.v4 = v4;
|
||||||
// TODO - Work out how materials work
|
// TODO - Work out how materials work
|
||||||
face.mat_nr = 0;
|
face.mat_nr = 0;
|
||||||
triMesh->mface.push_back( face );
|
triMesh->mface.push_back( face );
|
||||||
triMesh->totface = triMesh->mface.size( );
|
triMesh->totface = triMesh->mface.size( );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 )
|
void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 )
|
||||||
{
|
{
|
||||||
MTFace mtface;
|
MTFace mtface;
|
||||||
memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 );
|
memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 );
|
||||||
memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 );
|
memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 );
|
||||||
memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 );
|
memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 );
|
||||||
|
|
||||||
if ( uv4 )
|
if ( uv4 )
|
||||||
{
|
{
|
||||||
memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 );
|
memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
triMesh->mtface.push_back( mtface );
|
triMesh->mtface.push_back( mtface );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
|
@ -48,46 +48,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter
|
namespace Formatter
|
||||||
{
|
{
|
||||||
template < typename T,typename TR, typename A > class basic_formatter;
|
template < typename T,typename TR, typename A > class basic_formatter;
|
||||||
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderScene.h
|
// BlenderScene.h
|
||||||
namespace Blender
|
namespace Blender
|
||||||
{
|
{
|
||||||
struct Mesh;
|
struct Mesh;
|
||||||
struct MPoly;
|
struct MPoly;
|
||||||
struct MLoop;
|
struct MLoop;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter >
|
class BlenderBMeshConverter: public LogFunctions< BlenderBMeshConverter >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlenderBMeshConverter( const Blender::Mesh* mesh );
|
BlenderBMeshConverter( const Blender::Mesh* mesh );
|
||||||
~BlenderBMeshConverter( );
|
~BlenderBMeshConverter( );
|
||||||
|
|
||||||
bool ContainsBMesh( ) const;
|
bool ContainsBMesh( ) const;
|
||||||
|
|
||||||
const Blender::Mesh* TriangulateBMesh( );
|
const Blender::Mesh* TriangulateBMesh( );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AssertValidMesh( );
|
void AssertValidMesh( );
|
||||||
void AssertValidSizes( );
|
void AssertValidSizes( );
|
||||||
void PrepareTriMesh( );
|
void PrepareTriMesh( );
|
||||||
void DestroyTriMesh( );
|
void DestroyTriMesh( );
|
||||||
void ConvertPolyToFaces( const Blender::MPoly& poly );
|
void ConvertPolyToFaces( const Blender::MPoly& poly );
|
||||||
void AddFace( int v1, int v2, int v3, int v4 = 0 );
|
void AddFace( int v1, int v2, int v3, int v4 = 0 );
|
||||||
void AddTFace( const float* uv1, const float* uv2, const float *uv3, const float* uv4 = 0 );
|
void AddTFace( const float* uv1, const float* uv2, const float *uv3, const float* uv4 = 0 );
|
||||||
|
|
||||||
const Blender::Mesh* BMesh;
|
const Blender::Mesh* BMesh;
|
||||||
Blender::Mesh* triMesh;
|
Blender::Mesh* triMesh;
|
||||||
|
|
||||||
friend class BlenderTessellatorGL;
|
friend class BlenderTessellatorGL;
|
||||||
friend class BlenderTessellatorP2T;
|
friend class BlenderTessellatorP2T;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -56,168 +56,168 @@ using namespace Assimp::Formatter;
|
||||||
|
|
||||||
#define for_each BOOST_FOREACH
|
#define for_each BOOST_FOREACH
|
||||||
bool match4(StreamReaderAny& stream, const char* string) {
|
bool match4(StreamReaderAny& stream, const char* string) {
|
||||||
char tmp[] = {
|
char tmp[] = {
|
||||||
(stream).GetI1(),
|
(stream).GetI1(),
|
||||||
(stream).GetI1(),
|
(stream).GetI1(),
|
||||||
(stream).GetI1(),
|
(stream).GetI1(),
|
||||||
(stream).GetI1()
|
(stream).GetI1()
|
||||||
};
|
};
|
||||||
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
|
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Type {
|
struct Type {
|
||||||
size_t size;
|
size_t size;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void DNAParser :: Parse ()
|
void DNAParser :: Parse ()
|
||||||
{
|
{
|
||||||
StreamReaderAny& stream = *db.reader.get();
|
StreamReaderAny& stream = *db.reader.get();
|
||||||
DNA& dna = db.dna;
|
DNA& dna = db.dna;
|
||||||
|
|
||||||
if(!match4(stream,"SDNA")) {
|
if(!match4(stream,"SDNA")) {
|
||||||
throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
|
throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
|
||||||
}
|
}
|
||||||
|
|
||||||
// name dictionary
|
// name dictionary
|
||||||
if(!match4(stream,"NAME")) {
|
if(!match4(stream,"NAME")) {
|
||||||
throw DeadlyImportError("BlenderDNA: Expected NAME field");
|
throw DeadlyImportError("BlenderDNA: Expected NAME field");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> names (stream.GetI4());
|
std::vector<std::string> names (stream.GetI4());
|
||||||
for_each(std::string& s, names) {
|
for_each(std::string& s, names) {
|
||||||
while (char c = stream.GetI1()) {
|
while (char c = stream.GetI1()) {
|
||||||
s += c;
|
s += c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// type dictionary
|
// type dictionary
|
||||||
for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
|
for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
|
||||||
if(!match4(stream,"TYPE")) {
|
if(!match4(stream,"TYPE")) {
|
||||||
throw DeadlyImportError("BlenderDNA: Expected TYPE field");
|
throw DeadlyImportError("BlenderDNA: Expected TYPE field");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Type> types (stream.GetI4());
|
std::vector<Type> types (stream.GetI4());
|
||||||
for_each(Type& s, types) {
|
for_each(Type& s, types) {
|
||||||
while (char c = stream.GetI1()) {
|
while (char c = stream.GetI1()) {
|
||||||
s.name += c;
|
s.name += c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// type length dictionary
|
// type length dictionary
|
||||||
for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
|
for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
|
||||||
if(!match4(stream,"TLEN")) {
|
if(!match4(stream,"TLEN")) {
|
||||||
throw DeadlyImportError("BlenderDNA: Expected TLEN field");
|
throw DeadlyImportError("BlenderDNA: Expected TLEN field");
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each(Type& s, types) {
|
for_each(Type& s, types) {
|
||||||
s.size = stream.GetI2();
|
s.size = stream.GetI2();
|
||||||
}
|
}
|
||||||
|
|
||||||
// structures dictionary
|
// structures dictionary
|
||||||
for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
|
for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
|
||||||
if(!match4(stream,"STRC")) {
|
if(!match4(stream,"STRC")) {
|
||||||
throw DeadlyImportError("BlenderDNA: Expected STRC field");
|
throw DeadlyImportError("BlenderDNA: Expected STRC field");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t end = stream.GetI4(), fields = 0;
|
size_t end = stream.GetI4(), fields = 0;
|
||||||
|
|
||||||
dna.structures.reserve(end);
|
dna.structures.reserve(end);
|
||||||
for(size_t i = 0; i != end; ++i) {
|
for(size_t i = 0; i != end; ++i) {
|
||||||
|
|
||||||
uint16_t n = stream.GetI2();
|
uint16_t n = stream.GetI2();
|
||||||
if (n >= types.size()) {
|
if (n >= types.size()) {
|
||||||
throw DeadlyImportError((format(),
|
throw DeadlyImportError((format(),
|
||||||
"BlenderDNA: Invalid type index in structure name" ,n,
|
"BlenderDNA: Invalid type index in structure name" ,n,
|
||||||
" (there are only ", types.size(), " entries)"
|
" (there are only ", types.size(), " entries)"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// maintain separate indexes
|
// maintain separate indexes
|
||||||
dna.indices[types[n].name] = dna.structures.size();
|
dna.indices[types[n].name] = dna.structures.size();
|
||||||
|
|
||||||
dna.structures.push_back(Structure());
|
dna.structures.push_back(Structure());
|
||||||
Structure& s = dna.structures.back();
|
Structure& s = dna.structures.back();
|
||||||
s.name = types[n].name;
|
s.name = types[n].name;
|
||||||
//s.index = dna.structures.size()-1;
|
//s.index = dna.structures.size()-1;
|
||||||
|
|
||||||
n = stream.GetI2();
|
n = stream.GetI2();
|
||||||
s.fields.reserve(n);
|
s.fields.reserve(n);
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (size_t m = 0; m < n; ++m, ++fields) {
|
for (size_t m = 0; m < n; ++m, ++fields) {
|
||||||
|
|
||||||
uint16_t j = stream.GetI2();
|
uint16_t j = stream.GetI2();
|
||||||
if (j >= types.size()) {
|
if (j >= types.size()) {
|
||||||
throw DeadlyImportError((format(),
|
throw DeadlyImportError((format(),
|
||||||
"BlenderDNA: Invalid type index in structure field ", j,
|
"BlenderDNA: Invalid type index in structure field ", j,
|
||||||
" (there are only ", types.size(), " entries)"
|
" (there are only ", types.size(), " entries)"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
s.fields.push_back(Field());
|
s.fields.push_back(Field());
|
||||||
Field& f = s.fields.back();
|
Field& f = s.fields.back();
|
||||||
f.offset = offset;
|
f.offset = offset;
|
||||||
|
|
||||||
f.type = types[j].name;
|
f.type = types[j].name;
|
||||||
f.size = types[j].size;
|
f.size = types[j].size;
|
||||||
|
|
||||||
j = stream.GetI2();
|
j = stream.GetI2();
|
||||||
if (j >= names.size()) {
|
if (j >= names.size()) {
|
||||||
throw DeadlyImportError((format(),
|
throw DeadlyImportError((format(),
|
||||||
"BlenderDNA: Invalid name index in structure field ", j,
|
"BlenderDNA: Invalid name index in structure field ", j,
|
||||||
" (there are only ", names.size(), " entries)"
|
" (there are only ", names.size(), " entries)"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
f.name = names[j];
|
f.name = names[j];
|
||||||
f.flags = 0u;
|
f.flags = 0u;
|
||||||
|
|
||||||
// pointers always specify the size of the pointee instead of their own.
|
// pointers always specify the size of the pointee instead of their own.
|
||||||
// The pointer asterisk remains a property of the lookup name.
|
// The pointer asterisk remains a property of the lookup name.
|
||||||
if (f.name[0] == '*') {
|
if (f.name[0] == '*') {
|
||||||
f.size = db.i64bit ? 8 : 4;
|
f.size = db.i64bit ? 8 : 4;
|
||||||
f.flags |= FieldFlag_Pointer;
|
f.flags |= FieldFlag_Pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrays, however, specify the size of a single element so we
|
// arrays, however, specify the size of a single element so we
|
||||||
// need to parse the (possibly multi-dimensional) array declaration
|
// need to parse the (possibly multi-dimensional) array declaration
|
||||||
// in order to obtain the actual size of the array in the file.
|
// in order to obtain the actual size of the array in the file.
|
||||||
// Also we need to alter the lookup name to include no array
|
// Also we need to alter the lookup name to include no array
|
||||||
// brackets anymore or size fixup won't work (if our size does
|
// brackets anymore or size fixup won't work (if our size does
|
||||||
// not match the size read from the DNA).
|
// not match the size read from the DNA).
|
||||||
if (*f.name.rbegin() == ']') {
|
if (*f.name.rbegin() == ']') {
|
||||||
const std::string::size_type rb = f.name.find('[');
|
const std::string::size_type rb = f.name.find('[');
|
||||||
if (rb == std::string::npos) {
|
if (rb == std::string::npos) {
|
||||||
throw DeadlyImportError((format(),
|
throw DeadlyImportError((format(),
|
||||||
"BlenderDNA: Encountered invalid array declaration ",
|
"BlenderDNA: Encountered invalid array declaration ",
|
||||||
f.name
|
f.name
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
f.flags |= FieldFlag_Array;
|
f.flags |= FieldFlag_Array;
|
||||||
DNA::ExtractArraySize(f.name,f.array_sizes);
|
DNA::ExtractArraySize(f.name,f.array_sizes);
|
||||||
f.name = f.name.substr(0,rb);
|
f.name = f.name.substr(0,rb);
|
||||||
|
|
||||||
f.size *= f.array_sizes[0] * f.array_sizes[1];
|
f.size *= f.array_sizes[0] * f.array_sizes[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// maintain separate indexes
|
// maintain separate indexes
|
||||||
s.indices[f.name] = s.fields.size()-1;
|
s.indices[f.name] = s.fields.size()-1;
|
||||||
offset += f.size;
|
offset += f.size;
|
||||||
}
|
}
|
||||||
s.size = offset;
|
s.size = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
|
DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
|
||||||
" structures with totally ",fields," fields"));
|
" structures with totally ",fields," fields"));
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
||||||
dna.DumpToFile();
|
dna.DumpToFile();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dna.AddPrimitiveStructures();
|
dna.AddPrimitiveStructures();
|
||||||
dna.RegisterConverters();
|
dna.RegisterConverters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,144 +227,144 @@ void DNAParser :: Parse ()
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void DNA :: DumpToFile()
|
void DNA :: DumpToFile()
|
||||||
{
|
{
|
||||||
// we dont't bother using the VFS here for this is only for debugging.
|
// we dont't bother using the VFS here for this is only for debugging.
|
||||||
// (and all your bases are belong to us).
|
// (and all your bases are belong to us).
|
||||||
|
|
||||||
std::ofstream f("dna.txt");
|
std::ofstream f("dna.txt");
|
||||||
if (f.fail()) {
|
if (f.fail()) {
|
||||||
DefaultLogger::get()->error("Could not dump dna to dna.txt");
|
DefaultLogger::get()->error("Could not dump dna to dna.txt");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
f << "Field format: type name offset size" << "\n";
|
f << "Field format: type name offset size" << "\n";
|
||||||
f << "Structure format: name size" << "\n";
|
f << "Structure format: name size" << "\n";
|
||||||
|
|
||||||
for_each(const Structure& s, structures) {
|
for_each(const Structure& s, structures) {
|
||||||
f << s.name << " " << s.size << "\n\n";
|
f << s.name << " " << s.size << "\n\n";
|
||||||
for_each(const Field& ff, s.fields) {
|
for_each(const Field& ff, s.fields) {
|
||||||
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
|
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
|
||||||
}
|
}
|
||||||
f << std::endl;
|
f << std::endl;
|
||||||
}
|
}
|
||||||
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
|
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/*static*/ void DNA :: ExtractArraySize(
|
/*static*/ void DNA :: ExtractArraySize(
|
||||||
const std::string& out,
|
const std::string& out,
|
||||||
size_t array_sizes[2]
|
size_t array_sizes[2]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
array_sizes[0] = array_sizes[1] = 1;
|
array_sizes[0] = array_sizes[1] = 1;
|
||||||
std::string::size_type pos = out.find('[');
|
std::string::size_type pos = out.find('[');
|
||||||
if (pos++ == std::string::npos) {
|
if (pos++ == std::string::npos) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
array_sizes[0] = strtoul10(&out[pos]);
|
array_sizes[0] = strtoul10(&out[pos]);
|
||||||
|
|
||||||
pos = out.find('[',pos);
|
pos = out.find('[',pos);
|
||||||
if (pos++ == std::string::npos) {
|
if (pos++ == std::string::npos) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
array_sizes[1] = strtoul10(&out[pos]);
|
array_sizes[1] = strtoul10(&out[pos]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
|
boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
|
||||||
const Structure& structure,
|
const Structure& structure,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
|
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
|
||||||
if (it == converters.end()) {
|
if (it == converters.end()) {
|
||||||
return boost::shared_ptr< ElemBase >();
|
return boost::shared_ptr< ElemBase >();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
|
boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
|
||||||
(structure.*((*it).second.second))(ret,db);
|
(structure.*((*it).second.second))(ret,db);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
DNA::FactoryPair DNA :: GetBlobToStructureConverter(
|
DNA::FactoryPair DNA :: GetBlobToStructureConverter(
|
||||||
const Structure& structure,
|
const Structure& structure,
|
||||||
const FileDatabase& /*db*/
|
const FileDatabase& /*db*/
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
|
std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
|
||||||
return it == converters.end() ? FactoryPair() : (*it).second;
|
return it == converters.end() ? FactoryPair() : (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// basing on http://www.blender.org/development/architecture/notes-on-sdna/
|
// basing on http://www.blender.org/development/architecture/notes-on-sdna/
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void DNA :: AddPrimitiveStructures()
|
void DNA :: AddPrimitiveStructures()
|
||||||
{
|
{
|
||||||
// NOTE: these are just dummies. Their presence enforces
|
// NOTE: these are just dummies. Their presence enforces
|
||||||
// Structure::Convert<target_type> to be called on these
|
// Structure::Convert<target_type> to be called on these
|
||||||
// empty structures. These converters are special
|
// empty structures. These converters are special
|
||||||
// overloads which scan the name of the structure and
|
// overloads which scan the name of the structure and
|
||||||
// perform the required data type conversion if one
|
// perform the required data type conversion if one
|
||||||
// of these special names is found in the structure
|
// of these special names is found in the structure
|
||||||
// in question.
|
// in question.
|
||||||
|
|
||||||
indices["int"] = structures.size();
|
indices["int"] = structures.size();
|
||||||
structures.push_back( Structure() );
|
structures.push_back( Structure() );
|
||||||
structures.back().name = "int";
|
structures.back().name = "int";
|
||||||
structures.back().size = 4;
|
structures.back().size = 4;
|
||||||
|
|
||||||
indices["short"] = structures.size();
|
indices["short"] = structures.size();
|
||||||
structures.push_back( Structure() );
|
structures.push_back( Structure() );
|
||||||
structures.back().name = "short";
|
structures.back().name = "short";
|
||||||
structures.back().size = 2;
|
structures.back().size = 2;
|
||||||
|
|
||||||
|
|
||||||
indices["char"] = structures.size();
|
indices["char"] = structures.size();
|
||||||
structures.push_back( Structure() );
|
structures.push_back( Structure() );
|
||||||
structures.back().name = "char";
|
structures.back().name = "char";
|
||||||
structures.back().size = 1;
|
structures.back().size = 1;
|
||||||
|
|
||||||
|
|
||||||
indices["float"] = structures.size();
|
indices["float"] = structures.size();
|
||||||
structures.push_back( Structure() );
|
structures.push_back( Structure() );
|
||||||
structures.back().name = "float";
|
structures.back().name = "float";
|
||||||
structures.back().size = 4;
|
structures.back().size = 4;
|
||||||
|
|
||||||
|
|
||||||
indices["double"] = structures.size();
|
indices["double"] = structures.size();
|
||||||
structures.push_back( Structure() );
|
structures.push_back( Structure() );
|
||||||
structures.back().name = "double";
|
structures.back().name = "double";
|
||||||
structures.back().size = 8;
|
structures.back().size = 8;
|
||||||
|
|
||||||
// no long, seemingly.
|
// no long, seemingly.
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SectionParser :: Next()
|
void SectionParser :: Next()
|
||||||
{
|
{
|
||||||
stream.SetCurrentPos(current.start + current.size);
|
stream.SetCurrentPos(current.start + current.size);
|
||||||
|
|
||||||
const char tmp[] = {
|
const char tmp[] = {
|
||||||
stream.GetI1(),
|
stream.GetI1(),
|
||||||
stream.GetI1(),
|
stream.GetI1(),
|
||||||
stream.GetI1(),
|
stream.GetI1(),
|
||||||
stream.GetI1()
|
stream.GetI1()
|
||||||
};
|
};
|
||||||
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
|
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
|
||||||
|
|
||||||
current.size = stream.GetI4();
|
current.size = stream.GetI4();
|
||||||
current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
|
current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
|
||||||
|
|
||||||
current.dna_index = stream.GetI4();
|
current.dna_index = stream.GetI4();
|
||||||
current.num = stream.GetI4();
|
current.num = stream.GetI4();
|
||||||
|
|
||||||
current.start = stream.GetCurrentPos();
|
current.start = stream.GetCurrentPos();
|
||||||
if (stream.GetRemainingSizeToLimit() < current.size) {
|
if (stream.GetRemainingSizeToLimit() < current.size) {
|
||||||
throw DeadlyImportError("BLEND: invalid size of file block");
|
throw DeadlyImportError("BLEND: invalid size of file block");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
|
||||||
DefaultLogger::get()->debug(current.id);
|
DefaultLogger::get()->debug(current.id);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -60,142 +60,142 @@ struct aiTexture;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
|
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
template <template <typename,typename> class TCLASS, typename T>
|
template <template <typename,typename> class TCLASS, typename T>
|
||||||
struct TempArray {
|
struct TempArray {
|
||||||
typedef TCLASS< T*,std::allocator<T*> > mywrap;
|
typedef TCLASS< T*,std::allocator<T*> > mywrap;
|
||||||
|
|
||||||
TempArray() {
|
TempArray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
~TempArray () {
|
~TempArray () {
|
||||||
for_each(T* elem, arr) {
|
for_each(T* elem, arr) {
|
||||||
delete elem;
|
delete elem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dismiss() {
|
void dismiss() {
|
||||||
arr.clear();
|
arr.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
mywrap* operator -> () {
|
mywrap* operator -> () {
|
||||||
return &arr;
|
return &arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator mywrap& () {
|
operator mywrap& () {
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const mywrap& () const {
|
operator const mywrap& () const {
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
mywrap& get () {
|
mywrap& get () {
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mywrap& get () const {
|
const mywrap& get () const {
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* operator[] (size_t idx) const {
|
T* operator[] (size_t idx) const {
|
||||||
return arr[idx];
|
return arr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
T*& operator[] (size_t idx) {
|
T*& operator[] (size_t idx) {
|
||||||
return arr[idx];
|
return arr[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// no copy semantics
|
// no copy semantics
|
||||||
void operator= (const TempArray&) {
|
void operator= (const TempArray&) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TempArray(const TempArray& arr) {
|
TempArray(const TempArray& arr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mywrap arr;
|
mywrap arr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(disable:4351)
|
# pragma warning(disable:4351)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ObjectCompare {
|
struct ObjectCompare {
|
||||||
bool operator() (const Object* left, const Object* right) const {
|
bool operator() (const Object* left, const Object* right) const {
|
||||||
return strcmp(left->id.name, right->id.name) == -1;
|
return strcmp(left->id.name, right->id.name) == -1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// When keeping objects in sets, sort them by their name.
|
// When keeping objects in sets, sort them by their name.
|
||||||
typedef std::set<const Object*, ObjectCompare> ObjectSet;
|
typedef std::set<const Object*, ObjectCompare> ObjectSet;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** ConversionData acts as intermediate storage location for
|
/** ConversionData acts as intermediate storage location for
|
||||||
* the various ConvertXXX routines in BlenderImporter.*/
|
* the various ConvertXXX routines in BlenderImporter.*/
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
struct ConversionData
|
struct ConversionData
|
||||||
{
|
{
|
||||||
ConversionData(const FileDatabase& db)
|
ConversionData(const FileDatabase& db)
|
||||||
: sentinel_cnt()
|
: sentinel_cnt()
|
||||||
, next_texture()
|
, next_texture()
|
||||||
, db(db)
|
, db(db)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
struct ObjectCompare {
|
struct ObjectCompare {
|
||||||
bool operator() (const Object* left, const Object* right) const {
|
bool operator() (const Object* left, const Object* right) const {
|
||||||
return strcmp(left->id.name, right->id.name) == -1;
|
return strcmp(left->id.name, right->id.name) == -1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ObjectSet objects;
|
ObjectSet objects;
|
||||||
|
|
||||||
TempArray <std::vector, aiMesh> meshes;
|
TempArray <std::vector, aiMesh> meshes;
|
||||||
TempArray <std::vector, aiCamera> cameras;
|
TempArray <std::vector, aiCamera> cameras;
|
||||||
TempArray <std::vector, aiLight> lights;
|
TempArray <std::vector, aiLight> lights;
|
||||||
TempArray <std::vector, aiMaterial> materials;
|
TempArray <std::vector, aiMaterial> materials;
|
||||||
TempArray <std::vector, aiTexture> textures;
|
TempArray <std::vector, aiTexture> textures;
|
||||||
|
|
||||||
// set of all materials referenced by at least one mesh in the scene
|
// set of all materials referenced by at least one mesh in the scene
|
||||||
std::deque< boost::shared_ptr< Material > > materials_raw;
|
std::deque< boost::shared_ptr< Material > > materials_raw;
|
||||||
|
|
||||||
// counter to name sentinel textures inserted as substitutes for procedural textures.
|
// counter to name sentinel textures inserted as substitutes for procedural textures.
|
||||||
unsigned int sentinel_cnt;
|
unsigned int sentinel_cnt;
|
||||||
|
|
||||||
// next texture ID for each texture type, respectively
|
// next texture ID for each texture type, respectively
|
||||||
unsigned int next_texture[aiTextureType_UNKNOWN+1];
|
unsigned int next_texture[aiTextureType_UNKNOWN+1];
|
||||||
|
|
||||||
// original file data
|
// original file data
|
||||||
const FileDatabase& db;
|
const FileDatabase& db;
|
||||||
};
|
};
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(default:4351)
|
# pragma warning(default:4351)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
inline const char* GetTextureTypeDisplayString(Tex::Type t)
|
inline const char* GetTextureTypeDisplayString(Tex::Type t)
|
||||||
{
|
{
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case Tex::Type_CLOUDS : return "Clouds";
|
case Tex::Type_CLOUDS : return "Clouds";
|
||||||
case Tex::Type_WOOD : return "Wood";
|
case Tex::Type_WOOD : return "Wood";
|
||||||
case Tex::Type_MARBLE : return "Marble";
|
case Tex::Type_MARBLE : return "Marble";
|
||||||
case Tex::Type_MAGIC : return "Magic";
|
case Tex::Type_MAGIC : return "Magic";
|
||||||
case Tex::Type_BLEND : return "Blend";
|
case Tex::Type_BLEND : return "Blend";
|
||||||
case Tex::Type_STUCCI : return "Stucci";
|
case Tex::Type_STUCCI : return "Stucci";
|
||||||
case Tex::Type_NOISE : return "Noise";
|
case Tex::Type_NOISE : return "Noise";
|
||||||
case Tex::Type_PLUGIN : return "Plugin";
|
case Tex::Type_PLUGIN : return "Plugin";
|
||||||
case Tex::Type_MUSGRAVE : return "Musgrave";
|
case Tex::Type_MUSGRAVE : return "Musgrave";
|
||||||
case Tex::Type_VORONOI : return "Voronoi";
|
case Tex::Type_VORONOI : return "Voronoi";
|
||||||
case Tex::Type_DISTNOISE : return "DistortedNoise";
|
case Tex::Type_DISTNOISE : return "DistortedNoise";
|
||||||
case Tex::Type_ENVMAP : return "EnvMap";
|
case Tex::Type_ENVMAP : return "EnvMap";
|
||||||
case Tex::Type_IMAGE : return "Image";
|
case Tex::Type_IMAGE : return "Image";
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return "<Unknown>";
|
return "<Unknown>";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // ! Blender
|
} // ! Blender
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -54,43 +54,43 @@ struct aiLight;
|
||||||
struct aiCamera;
|
struct aiCamera;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter {
|
namespace Formatter {
|
||||||
template <typename T,typename TR, typename A> class basic_formatter;
|
template <typename T,typename TR, typename A> class basic_formatter;
|
||||||
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderDNA.h
|
// BlenderDNA.h
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
class FileDatabase;
|
class FileDatabase;
|
||||||
struct ElemBase;
|
struct ElemBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderScene.h
|
// BlenderScene.h
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
struct Scene;
|
struct Scene;
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Mesh;
|
struct Mesh;
|
||||||
struct Camera;
|
struct Camera;
|
||||||
struct Lamp;
|
struct Lamp;
|
||||||
struct MTex;
|
struct MTex;
|
||||||
struct Image;
|
struct Image;
|
||||||
struct Material;
|
struct Material;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderIntermediate.h
|
// BlenderIntermediate.h
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
struct ConversionData;
|
struct ConversionData;
|
||||||
template <template <typename,typename> class TCLASS, typename T> struct TempArray;
|
template <template <typename,typename> class TCLASS, typename T> struct TempArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderModifier.h
|
// BlenderModifier.h
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
class BlenderModifierShowcase;
|
class BlenderModifierShowcase;
|
||||||
class BlenderModifier;
|
class BlenderModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,127 +102,127 @@ namespace Assimp {
|
||||||
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
|
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlenderImporter();
|
BlenderImporter();
|
||||||
~BlenderImporter();
|
~BlenderImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
bool CanRead( const std::string& pFile,
|
bool CanRead( const std::string& pFile,
|
||||||
IOSystem* pIOHandler,
|
IOSystem* pIOHandler,
|
||||||
bool checkSig
|
bool checkSig
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void GetExtensionList(std::set<std::string>& app);
|
void GetExtensionList(std::set<std::string>& app);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void InternReadFile( const std::string& pFile,
|
void InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene,
|
aiScene* pScene,
|
||||||
IOSystem* pIOHandler
|
IOSystem* pIOHandler
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ParseBlendFile(Blender::FileDatabase& out,
|
void ParseBlendFile(Blender::FileDatabase& out,
|
||||||
boost::shared_ptr<IOStream> stream
|
boost::shared_ptr<IOStream> stream
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ExtractScene(Blender::Scene& out,
|
void ExtractScene(Blender::Scene& out,
|
||||||
const Blender::FileDatabase& file
|
const Blender::FileDatabase& file
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ConvertBlendFile(aiScene* out,
|
void ConvertBlendFile(aiScene* out,
|
||||||
const Blender::Scene& in,
|
const Blender::Scene& in,
|
||||||
const Blender::FileDatabase& file
|
const Blender::FileDatabase& file
|
||||||
);
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
aiNode* ConvertNode(const Blender::Scene& in,
|
aiNode* ConvertNode(const Blender::Scene& in,
|
||||||
const Blender::Object* obj,
|
const Blender::Object* obj,
|
||||||
Blender::ConversionData& conv_info,
|
Blender::ConversionData& conv_info,
|
||||||
const aiMatrix4x4& parentTransform
|
const aiMatrix4x4& parentTransform
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ConvertMesh(const Blender::Scene& in,
|
void ConvertMesh(const Blender::Scene& in,
|
||||||
const Blender::Object* obj,
|
const Blender::Object* obj,
|
||||||
const Blender::Mesh* mesh,
|
const Blender::Mesh* mesh,
|
||||||
Blender::ConversionData& conv_data,
|
Blender::ConversionData& conv_data,
|
||||||
Blender::TempArray<std::vector,aiMesh>& temp
|
Blender::TempArray<std::vector,aiMesh>& temp
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
aiLight* ConvertLight(const Blender::Scene& in,
|
aiLight* ConvertLight(const Blender::Scene& in,
|
||||||
const Blender::Object* obj,
|
const Blender::Object* obj,
|
||||||
const Blender::Lamp* mesh,
|
const Blender::Lamp* mesh,
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
aiCamera* ConvertCamera(const Blender::Scene& in,
|
aiCamera* ConvertCamera(const Blender::Scene& in,
|
||||||
const Blender::Object* obj,
|
const Blender::Object* obj,
|
||||||
const Blender::Camera* mesh,
|
const Blender::Camera* mesh,
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void BuildMaterials(
|
void BuildMaterials(
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
) ;
|
) ;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ResolveTexture(
|
void ResolveTexture(
|
||||||
aiMaterial* out,
|
aiMaterial* out,
|
||||||
const Blender::Material* mat,
|
const Blender::Material* mat,
|
||||||
const Blender::MTex* tex,
|
const Blender::MTex* tex,
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ResolveImage(
|
void ResolveImage(
|
||||||
aiMaterial* out,
|
aiMaterial* out,
|
||||||
const Blender::Material* mat,
|
const Blender::Material* mat,
|
||||||
const Blender::MTex* tex,
|
const Blender::MTex* tex,
|
||||||
const Blender::Image* img,
|
const Blender::Image* img,
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
);
|
);
|
||||||
|
|
||||||
void AddSentinelTexture(
|
void AddSentinelTexture(
|
||||||
aiMaterial* out,
|
aiMaterial* out,
|
||||||
const Blender::Material* mat,
|
const Blender::Material* mat,
|
||||||
const Blender::MTex* tex,
|
const Blender::MTex* tex,
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
);
|
);
|
||||||
|
|
||||||
private: // static stuff, mostly logging and error reporting.
|
private: // static stuff, mostly logging and error reporting.
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
static void CheckActualType(const Blender::ElemBase* dt,
|
static void CheckActualType(const Blender::ElemBase* dt,
|
||||||
const char* check
|
const char* check
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
static void NotSupportedObjectType(const Blender::Object* obj,
|
static void NotSupportedObjectType(const Blender::Object* obj,
|
||||||
const char* type
|
const char* type
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Blender::BlenderModifierShowcase* modifier_cache;
|
Blender::BlenderModifierShowcase* modifier_cache;
|
||||||
|
|
||||||
}; // !class BlenderImporter
|
}; // !class BlenderImporter
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -58,120 +58,120 @@ using namespace Assimp;
|
||||||
using namespace Assimp::Blender;
|
using namespace Assimp::Blender;
|
||||||
|
|
||||||
template <typename T> BlenderModifier* god() {
|
template <typename T> BlenderModifier* god() {
|
||||||
return new T();
|
return new T();
|
||||||
}
|
}
|
||||||
|
|
||||||
// add all available modifiers here
|
// add all available modifiers here
|
||||||
typedef BlenderModifier* (*fpCreateModifier)();
|
typedef BlenderModifier* (*fpCreateModifier)();
|
||||||
static const fpCreateModifier creators[] = {
|
static const fpCreateModifier creators[] = {
|
||||||
&god<BlenderModifier_Mirror>,
|
&god<BlenderModifier_Mirror>,
|
||||||
&god<BlenderModifier_Subdivision>,
|
&god<BlenderModifier_Subdivision>,
|
||||||
|
|
||||||
NULL // sentinel
|
NULL // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// just testing out some new macros to simplify logging
|
// just testing out some new macros to simplify logging
|
||||||
#define ASSIMP_LOG_WARN_F(string,...)\
|
#define ASSIMP_LOG_WARN_F(string,...)\
|
||||||
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
|
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
|
||||||
|
|
||||||
#define ASSIMP_LOG_ERROR_F(string,...)\
|
#define ASSIMP_LOG_ERROR_F(string,...)\
|
||||||
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
|
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
|
||||||
|
|
||||||
#define ASSIMP_LOG_DEBUG_F(string,...)\
|
#define ASSIMP_LOG_DEBUG_F(string,...)\
|
||||||
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
|
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
|
||||||
|
|
||||||
#define ASSIMP_LOG_INFO_F(string,...)\
|
#define ASSIMP_LOG_INFO_F(string,...)\
|
||||||
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
|
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
|
||||||
|
|
||||||
|
|
||||||
#define ASSIMP_LOG_WARN(string)\
|
#define ASSIMP_LOG_WARN(string)\
|
||||||
DefaultLogger::get()->warn(string)
|
DefaultLogger::get()->warn(string)
|
||||||
|
|
||||||
#define ASSIMP_LOG_ERROR(string)\
|
#define ASSIMP_LOG_ERROR(string)\
|
||||||
DefaultLogger::get()->error(string)
|
DefaultLogger::get()->error(string)
|
||||||
|
|
||||||
#define ASSIMP_LOG_DEBUG(string)\
|
#define ASSIMP_LOG_DEBUG(string)\
|
||||||
DefaultLogger::get()->debug(string)
|
DefaultLogger::get()->debug(string)
|
||||||
|
|
||||||
#define ASSIMP_LOG_INFO(string)\
|
#define ASSIMP_LOG_INFO(string)\
|
||||||
DefaultLogger::get()->info(string)
|
DefaultLogger::get()->info(string)
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
struct SharedModifierData : ElemBase
|
struct SharedModifierData : ElemBase
|
||||||
{
|
{
|
||||||
ModifierData modifier;
|
ModifierData modifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
|
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
|
||||||
{
|
{
|
||||||
size_t cnt = 0u, ful = 0u;
|
size_t cnt = 0u, ful = 0u;
|
||||||
|
|
||||||
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
|
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
|
||||||
// we're allowed to dereference the pointers without risking to crash. We might still be
|
// we're allowed to dereference the pointers without risking to crash. We might still be
|
||||||
// invoking UB btw - we're assuming that the ModifierData member of the respective modifier
|
// invoking UB btw - we're assuming that the ModifierData member of the respective modifier
|
||||||
// structures is at offset sizeof(vftable) with no padding.
|
// structures is at offset sizeof(vftable) with no padding.
|
||||||
const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
|
const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
|
||||||
for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
|
for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
|
||||||
ai_assert(cur->dna_type);
|
ai_assert(cur->dna_type);
|
||||||
|
|
||||||
const Structure* s = conv_data.db.dna.Get( cur->dna_type );
|
const Structure* s = conv_data.db.dna.Get( cur->dna_type );
|
||||||
if (!s) {
|
if (!s) {
|
||||||
ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
|
ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is a common trait of all XXXMirrorData structures in BlenderDNA
|
// this is a common trait of all XXXMirrorData structures in BlenderDNA
|
||||||
const Field* f = s->Get("modifier");
|
const Field* f = s->Get("modifier");
|
||||||
if (!f || f->offset != 0) {
|
if (!f || f->offset != 0) {
|
||||||
ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
|
ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
s = conv_data.db.dna.Get( f->type );
|
s = conv_data.db.dna.Get( f->type );
|
||||||
if (!s || s->name != "ModifierData") {
|
if (!s || s->name != "ModifierData") {
|
||||||
ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
|
ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now, we can be sure that we should be fine to dereference *cur* as
|
// now, we can be sure that we should be fine to dereference *cur* as
|
||||||
// ModifierData (with the above note).
|
// ModifierData (with the above note).
|
||||||
const ModifierData& dat = cur->modifier;
|
const ModifierData& dat = cur->modifier;
|
||||||
|
|
||||||
const fpCreateModifier* curgod = creators;
|
const fpCreateModifier* curgod = creators;
|
||||||
std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
|
std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
|
||||||
|
|
||||||
for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
|
for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
|
||||||
if (curmod == endmod) {
|
if (curmod == endmod) {
|
||||||
cached_modifiers->push_back((*curgod)());
|
cached_modifiers->push_back((*curgod)());
|
||||||
|
|
||||||
endmod = cached_modifiers->end();
|
endmod = cached_modifiers->end();
|
||||||
curmod = endmod-1;
|
curmod = endmod-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlenderModifier* const modifier = *curmod;
|
BlenderModifier* const modifier = *curmod;
|
||||||
if(modifier->IsActive(dat)) {
|
if(modifier->IsActive(dat)) {
|
||||||
modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
|
modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
curgod = NULL;
|
curgod = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (curgod) {
|
if (curgod) {
|
||||||
ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
|
ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Even though we managed to resolve some or all of the modifiers on this
|
// Even though we managed to resolve some or all of the modifiers on this
|
||||||
// object, we still can't say whether our modifier implementations were
|
// object, we still can't say whether our modifier implementations were
|
||||||
// able to fully do their job.
|
// able to fully do their job.
|
||||||
if (ful) {
|
if (ful) {
|
||||||
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
|
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
|
||||||
"`, check log messages above for errors");
|
"`, check log messages above for errors");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -179,102 +179,102 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_d
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
|
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
|
||||||
{
|
{
|
||||||
return modin.type == ModifierData::eModifierType_Mirror;
|
return modin.type == ModifierData::eModifierType_Mirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
|
void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
|
||||||
const Scene& /*in*/,
|
const Scene& /*in*/,
|
||||||
const Object& orig_object )
|
const Object& orig_object )
|
||||||
{
|
{
|
||||||
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
|
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
|
||||||
const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
|
const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
|
||||||
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
|
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
|
||||||
|
|
||||||
conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
|
conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
|
||||||
|
|
||||||
// XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
|
// XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
|
||||||
|
|
||||||
// take all input meshes and clone them
|
// take all input meshes and clone them
|
||||||
for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
|
||||||
aiMesh* mesh;
|
aiMesh* mesh;
|
||||||
SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
|
SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
|
||||||
|
|
||||||
const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
|
const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
|
||||||
const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
|
const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
|
||||||
const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
|
const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
|
||||||
|
|
||||||
if (mir.mirror_ob) {
|
if (mir.mirror_ob) {
|
||||||
const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
|
const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
aiVector3D& v = mesh->mVertices[i];
|
aiVector3D& v = mesh->mVertices[i];
|
||||||
|
|
||||||
v.x = center.x + xs*(center.x - v.x);
|
v.x = center.x + xs*(center.x - v.x);
|
||||||
v.y = center.y + ys*(center.y - v.y);
|
v.y = center.y + ys*(center.y - v.y);
|
||||||
v.z = center.z + zs*(center.z - v.z);
|
v.z = center.z + zs*(center.z - v.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
aiVector3D& v = mesh->mVertices[i];
|
aiVector3D& v = mesh->mVertices[i];
|
||||||
v.x *= xs;v.y *= ys;v.z *= zs;
|
v.x *= xs;v.y *= ys;v.z *= zs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->mNormals) {
|
if (mesh->mNormals) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
aiVector3D& v = mesh->mNormals[i];
|
aiVector3D& v = mesh->mNormals[i];
|
||||||
v.x *= xs;v.y *= ys;v.z *= zs;
|
v.x *= xs;v.y *= ys;v.z *= zs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->mTangents) {
|
if (mesh->mTangents) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
aiVector3D& v = mesh->mTangents[i];
|
aiVector3D& v = mesh->mTangents[i];
|
||||||
v.x *= xs;v.y *= ys;v.z *= zs;
|
v.x *= xs;v.y *= ys;v.z *= zs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh->mBitangents) {
|
if (mesh->mBitangents) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
aiVector3D& v = mesh->mBitangents[i];
|
aiVector3D& v = mesh->mBitangents[i];
|
||||||
v.x *= xs;v.y *= ys;v.z *= zs;
|
v.x *= xs;v.y *= ys;v.z *= zs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
|
const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
|
||||||
const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
|
const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
|
||||||
|
|
||||||
for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
|
for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
aiVector3D& v = mesh->mTextureCoords[n][i];
|
aiVector3D& v = mesh->mTextureCoords[n][i];
|
||||||
v.x *= us;v.y *= vs;
|
v.x *= us;v.y *= vs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only reverse the winding order if an odd number of axes were mirrored.
|
// Only reverse the winding order if an odd number of axes were mirrored.
|
||||||
if (xs * ys * zs < 0) {
|
if (xs * ys * zs < 0) {
|
||||||
for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
|
for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
|
||||||
aiFace& face = mesh->mFaces[i];
|
aiFace& face = mesh->mFaces[i];
|
||||||
for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
|
for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
|
||||||
std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
|
std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conv_data.meshes->push_back(mesh);
|
conv_data.meshes->push_back(mesh);
|
||||||
}
|
}
|
||||||
unsigned int* nind = new unsigned int[out.mNumMeshes*2];
|
unsigned int* nind = new unsigned int[out.mNumMeshes*2];
|
||||||
|
|
||||||
std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
|
std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
|
||||||
std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
|
std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
|
||||||
std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
|
std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
|
||||||
|
|
||||||
delete[] out.mMeshes;
|
delete[] out.mMeshes;
|
||||||
out.mMeshes = nind;
|
out.mMeshes = nind;
|
||||||
out.mNumMeshes *= 2;
|
out.mNumMeshes *= 2;
|
||||||
|
|
||||||
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
|
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
|
||||||
orig_object.id.name,"`");
|
orig_object.id.name,"`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -283,46 +283,46 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
|
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
|
||||||
{
|
{
|
||||||
return modin.type == ModifierData::eModifierType_Subsurf;
|
return modin.type == ModifierData::eModifierType_Subsurf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
|
void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
|
||||||
const Scene& /*in*/,
|
const Scene& /*in*/,
|
||||||
const Object& orig_object )
|
const Object& orig_object )
|
||||||
{
|
{
|
||||||
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
|
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
|
||||||
const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
|
const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
|
||||||
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
|
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
|
||||||
|
|
||||||
Subdivider::Algorithm algo;
|
Subdivider::Algorithm algo;
|
||||||
switch (mir.subdivType)
|
switch (mir.subdivType)
|
||||||
{
|
{
|
||||||
case SubsurfModifierData::TYPE_CatmullClarke:
|
case SubsurfModifierData::TYPE_CatmullClarke:
|
||||||
algo = Subdivider::CATMULL_CLARKE;
|
algo = Subdivider::CATMULL_CLARKE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SubsurfModifierData::TYPE_Simple:
|
case SubsurfModifierData::TYPE_Simple:
|
||||||
ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
|
ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
|
||||||
algo = Subdivider::CATMULL_CLARKE;
|
algo = Subdivider::CATMULL_CLARKE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
|
ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
|
boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
|
||||||
ai_assert(subd);
|
ai_assert(subd);
|
||||||
|
|
||||||
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
||||||
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
|
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
|
||||||
|
|
||||||
subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
|
subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
|
||||||
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
|
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
|
||||||
|
|
||||||
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
|
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
|
||||||
orig_object.id.name,"`");
|
orig_object.id.name,"`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderIntermediate.h"
|
#include "BlenderIntermediate.h"
|
||||||
#include "TinyFormatter.h"
|
#include "TinyFormatter.h"
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
|
/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
|
||||||
|
@ -57,30 +57,30 @@ class BlenderModifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~BlenderModifier() {
|
virtual ~BlenderModifier() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
/** Check if *this* modifier is active, given a ModifierData& block.*/
|
/** Check if *this* modifier is active, given a ModifierData& block.*/
|
||||||
virtual bool IsActive( const ModifierData& /*modin*/) {
|
virtual bool IsActive( const ModifierData& /*modin*/) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
/** Apply the modifier to a given output node. The original data used
|
/** Apply the modifier to a given output node. The original data used
|
||||||
* to construct the node is given as well. Not called unless IsActive()
|
* to construct the node is given as well. Not called unless IsActive()
|
||||||
* was called and gave positive response. */
|
* was called and gave positive response. */
|
||||||
virtual void DoIt(aiNode& /*out*/,
|
virtual void DoIt(aiNode& /*out*/,
|
||||||
ConversionData& /*conv_data*/,
|
ConversionData& /*conv_data*/,
|
||||||
const ElemBase& orig_modifier,
|
const ElemBase& orig_modifier,
|
||||||
const Scene& /*in*/,
|
const Scene& /*in*/,
|
||||||
const Object& /*orig_object*/
|
const Object& /*orig_object*/
|
||||||
) {
|
) {
|
||||||
DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
|
DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,17 +91,17 @@ class BlenderModifierShowcase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
/** Apply all requested modifiers provided we support them. */
|
/** Apply all requested modifiers provided we support them. */
|
||||||
void ApplyModifiers(aiNode& out,
|
void ApplyModifiers(aiNode& out,
|
||||||
ConversionData& conv_data,
|
ConversionData& conv_data,
|
||||||
const Scene& in,
|
const Scene& in,
|
||||||
const Object& orig_object
|
const Object& orig_object
|
||||||
);
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TempArray< std::vector,BlenderModifier > cached_modifiers;
|
TempArray< std::vector,BlenderModifier > cached_modifiers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,16 +119,16 @@ class BlenderModifier_Mirror : public BlenderModifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
virtual bool IsActive( const ModifierData& modin);
|
virtual bool IsActive( const ModifierData& modin);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
virtual void DoIt(aiNode& out,
|
virtual void DoIt(aiNode& out,
|
||||||
ConversionData& conv_data,
|
ConversionData& conv_data,
|
||||||
const ElemBase& orig_modifier,
|
const ElemBase& orig_modifier,
|
||||||
const Scene& in,
|
const Scene& in,
|
||||||
const Object& orig_object
|
const Object& orig_object
|
||||||
) ;
|
) ;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
|
@ -138,16 +138,16 @@ class BlenderModifier_Subdivision : public BlenderModifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
virtual bool IsActive( const ModifierData& modin);
|
virtual bool IsActive( const ModifierData& modin);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
virtual void DoIt(aiNode& out,
|
virtual void DoIt(aiNode& out,
|
||||||
ConversionData& conv_data,
|
ConversionData& conv_data,
|
||||||
const ElemBase& orig_modifier,
|
const ElemBase& orig_modifier,
|
||||||
const Scene& in,
|
const Scene& in,
|
||||||
const Object& orig_object
|
const Object& orig_object
|
||||||
) ;
|
) ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ template <> void Structure :: Convert<Object> (
|
||||||
ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.modifiers,"modifiers",db);
|
ReadField<ErrorPolicy_Igno>(dest.modifiers,"modifiers",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -90,7 +90,7 @@ template <> void Structure :: Convert<Group> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
|
ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -129,7 +129,7 @@ template <> void Structure :: Convert<MTex> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.hardfac,"hardfac",db);
|
ReadField<ErrorPolicy_Igno>(dest.hardfac,"hardfac",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.norfac,"norfac",db);
|
ReadField<ErrorPolicy_Igno>(dest.norfac,"norfac",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -146,7 +146,7 @@ template <> void Structure :: Convert<TFace> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
|
ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -162,7 +162,7 @@ template <> void Structure :: Convert<SubsurfModifierData> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.renderLevels,"renderLevels",db);
|
ReadField<ErrorPolicy_Igno>(dest.renderLevels,"renderLevels",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -179,7 +179,7 @@ template <> void Structure :: Convert<MFace> (
|
||||||
ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
|
ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -207,7 +207,7 @@ template <> void Structure :: Convert<Lamp> (
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
|
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -220,7 +220,7 @@ template <> void Structure :: Convert<MDeformWeight> (
|
||||||
ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
|
ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
|
||||||
ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
|
ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -234,7 +234,7 @@ template <> void Structure :: Convert<PackedFile> (
|
||||||
ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
|
ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -243,36 +243,36 @@ template <> void Structure :: Convert<Base> (
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// note: as per https://github.com/assimp/assimp/issues/128,
|
// note: as per https://github.com/assimp/assimp/issues/128,
|
||||||
// reading the Object linked list recursively is prone to stack overflow.
|
// reading the Object linked list recursively is prone to stack overflow.
|
||||||
// This structure converter is therefore an hand-written exception that
|
// This structure converter is therefore an hand-written exception that
|
||||||
// does it iteratively.
|
// does it iteratively.
|
||||||
|
|
||||||
const int initial_pos = db.reader->GetCurrentPos();
|
const int initial_pos = db.reader->GetCurrentPos();
|
||||||
|
|
||||||
std::pair<Base*, int> todo = std::make_pair(&dest, initial_pos);
|
std::pair<Base*, int> todo = std::make_pair(&dest, initial_pos);
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
|
|
||||||
Base& cur_dest = *todo.first;
|
Base& cur_dest = *todo.first;
|
||||||
db.reader->SetCurrentPos(todo.second);
|
db.reader->SetCurrentPos(todo.second);
|
||||||
|
|
||||||
// we know that this is a double-linked, circular list which we never
|
// we know that this is a double-linked, circular list which we never
|
||||||
// traverse backwards, so don't bother resolving the back links.
|
// traverse backwards, so don't bother resolving the back links.
|
||||||
cur_dest.prev = NULL;
|
cur_dest.prev = NULL;
|
||||||
|
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.object,"*object",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.object,"*object",db);
|
||||||
|
|
||||||
// the return value of ReadFieldPtr indicates whether the object
|
// the return value of ReadFieldPtr indicates whether the object
|
||||||
// was already cached. In this case, we don't need to resolve
|
// was already cached. In this case, we don't need to resolve
|
||||||
// it again.
|
// it again.
|
||||||
if(!ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.next,"*next",db, true) && cur_dest.next) {
|
if(!ReadFieldPtr<ErrorPolicy_Warn>(cur_dest.next,"*next",db, true) && cur_dest.next) {
|
||||||
todo = std::make_pair(&*cur_dest.next, db.reader->GetCurrentPos());
|
todo = std::make_pair(&*cur_dest.next, db.reader->GetCurrentPos());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
db.reader->SetCurrentPos(initial_pos + size);
|
db.reader->SetCurrentPos(initial_pos + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -288,7 +288,7 @@ template <> void Structure :: Convert<MTFace> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
|
ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -324,7 +324,7 @@ template <> void Structure :: Convert<Material> (
|
||||||
ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
|
ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -345,7 +345,7 @@ template <> void Structure :: Convert<MTexPoly> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
|
ReadField<ErrorPolicy_Igno>(dest.pad,"pad",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -379,7 +379,7 @@ template <> void Structure :: Convert<Mesh> (
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -392,7 +392,7 @@ template <> void Structure :: Convert<MDeformVert> (
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
|
ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -404,7 +404,7 @@ template <> void Structure :: Convert<World> (
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -419,7 +419,7 @@ template <> void Structure :: Convert<MLoopCol> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.a,"a",db);
|
ReadField<ErrorPolicy_Igno>(dest.a,"a",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -435,7 +435,7 @@ template <> void Structure :: Convert<MVert> (
|
||||||
ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -451,7 +451,7 @@ template <> void Structure :: Convert<MEdge> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -464,7 +464,7 @@ template <> void Structure :: Convert<MLoopUV> (
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.uv,"uv",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.uv,"uv",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -478,7 +478,7 @@ template <> void Structure :: Convert<GroupObject> (
|
||||||
ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -491,7 +491,7 @@ template <> void Structure :: Convert<ListBase> (
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.first,"*first",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.first,"*first",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.last,"*last",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.last,"*last",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -504,7 +504,7 @@ template <> void Structure :: Convert<MLoop> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v,"v",db);
|
ReadField<ErrorPolicy_Igno>(dest.v,"v",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.e,"e",db);
|
ReadField<ErrorPolicy_Igno>(dest.e,"e",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -520,7 +520,7 @@ template <> void Structure :: Convert<ModifierData> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
|
ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -533,7 +533,7 @@ template <> void Structure :: Convert<ID> (
|
||||||
ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -548,7 +548,7 @@ template <> void Structure :: Convert<MCol> (
|
||||||
ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
|
ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -563,7 +563,7 @@ template <> void Structure :: Convert<MPoly> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db);
|
ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -579,7 +579,7 @@ template <> void Structure :: Convert<Scene> (
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
|
ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -594,7 +594,7 @@ template <> void Structure :: Convert<Library> (
|
||||||
ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -607,7 +607,7 @@ template <> void Structure :: Convert<Tex> (
|
||||||
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -622,7 +622,7 @@ template <> void Structure :: Convert<Camera> (
|
||||||
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.angle,"angle",db);
|
ReadField<ErrorPolicy_Warn>(dest.angle,"angle",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -638,7 +638,7 @@ template <> void Structure :: Convert<MirrorModifierData> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.tolerance,"tolerance",db);
|
ReadField<ErrorPolicy_Igno>(dest.tolerance,"tolerance",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob,"*mirror_ob",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob,"*mirror_ob",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -671,7 +671,7 @@ template <> void Structure :: Convert<Image> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db);
|
ReadField<ErrorPolicy_Igno>(dest.gen_y,"gen_y",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db);
|
ReadField<ErrorPolicy_Igno>(dest.gen_type,"gen_type",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
// Minor parts of this file are extracts from blender data structures,
|
// Minor parts of this file are extracts from blender data structures,
|
||||||
// declared in the ./source/blender/makesdna directory.
|
// declared in the ./source/blender/makesdna directory.
|
||||||
|
@ -65,7 +65,7 @@ namespace Assimp {
|
||||||
//
|
//
|
||||||
// * Structures may include the primitive types char, int, short,
|
// * Structures may include the primitive types char, int, short,
|
||||||
// float, double. Signedness specifiers are not allowed on
|
// float, double. Signedness specifiers are not allowed on
|
||||||
// integers. Enum types are allowed, but they must have been
|
// integers. Enum types are allowed, but they must have been
|
||||||
// defined in this header.
|
// defined in this header.
|
||||||
//
|
//
|
||||||
// * Structures may aggregate other structures, unless not defined
|
// * Structures may aggregate other structures, unless not defined
|
||||||
|
@ -103,15 +103,15 @@ struct Image;
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ID : ElemBase {
|
struct ID : ElemBase {
|
||||||
|
|
||||||
char name[24] WARN;
|
char name[24] WARN;
|
||||||
short flag;
|
short flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ListBase : ElemBase {
|
struct ListBase : ElemBase {
|
||||||
|
|
||||||
boost::shared_ptr<ElemBase> first;
|
boost::shared_ptr<ElemBase> first;
|
||||||
boost::shared_ptr<ElemBase> last;
|
boost::shared_ptr<ElemBase> last;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,37 +119,37 @@ struct ListBase : ElemBase {
|
||||||
struct PackedFile : ElemBase {
|
struct PackedFile : ElemBase {
|
||||||
int size WARN;
|
int size WARN;
|
||||||
int seek WARN;
|
int seek WARN;
|
||||||
boost::shared_ptr< FileOffset > data WARN;
|
boost::shared_ptr< FileOffset > data WARN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct GroupObject : ElemBase {
|
struct GroupObject : ElemBase {
|
||||||
|
|
||||||
boost::shared_ptr<GroupObject> prev,next FAIL;
|
boost::shared_ptr<GroupObject> prev,next FAIL;
|
||||||
boost::shared_ptr<Object> ob;
|
boost::shared_ptr<Object> ob;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Group : ElemBase {
|
struct Group : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
int layer;
|
int layer;
|
||||||
|
|
||||||
boost::shared_ptr<GroupObject> gobject;
|
boost::shared_ptr<GroupObject> gobject;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct World : ElemBase {
|
struct World : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MVert : ElemBase {
|
struct MVert : ElemBase {
|
||||||
float co[3] FAIL;
|
float co[3] FAIL;
|
||||||
float no[3] FAIL;
|
float no[3] FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
int mat_nr WARN;
|
int mat_nr WARN;
|
||||||
int bweight;
|
int bweight;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -161,68 +161,68 @@ struct MEdge : ElemBase {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MLoop : ElemBase {
|
struct MLoop : ElemBase {
|
||||||
int v, e;
|
int v, e;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MLoopUV : ElemBase {
|
struct MLoopUV : ElemBase {
|
||||||
float uv[2];
|
float uv[2];
|
||||||
int flag;
|
int flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
// Note that red and blue are not swapped, as with MCol
|
// Note that red and blue are not swapped, as with MCol
|
||||||
struct MLoopCol : ElemBase {
|
struct MLoopCol : ElemBase {
|
||||||
char r, g, b, a;
|
char r, g, b, a;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MPoly : ElemBase {
|
struct MPoly : ElemBase {
|
||||||
int loopstart;
|
int loopstart;
|
||||||
int totloop;
|
int totloop;
|
||||||
short mat_nr;
|
short mat_nr;
|
||||||
char flag;
|
char flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTexPoly : ElemBase {
|
struct MTexPoly : ElemBase {
|
||||||
Image* tpage;
|
Image* tpage;
|
||||||
char flag, transp;
|
char flag, transp;
|
||||||
short mode, tile, pad;
|
short mode, tile, pad;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MCol : ElemBase {
|
struct MCol : ElemBase {
|
||||||
char r,g,b,a FAIL;
|
char r,g,b,a FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MFace : ElemBase {
|
struct MFace : ElemBase {
|
||||||
int v1,v2,v3,v4 FAIL;
|
int v1,v2,v3,v4 FAIL;
|
||||||
int mat_nr FAIL;
|
int mat_nr FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct TFace : ElemBase {
|
struct TFace : ElemBase {
|
||||||
float uv[4][2] FAIL;
|
float uv[4][2] FAIL;
|
||||||
int col[4] FAIL;
|
int col[4] FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
short mode;
|
short mode;
|
||||||
short tile;
|
short tile;
|
||||||
short unwrap;
|
short unwrap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTFace : ElemBase {
|
struct MTFace : ElemBase {
|
||||||
|
|
||||||
float uv[4][2] FAIL;
|
float uv[4][2] FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
short mode;
|
short mode;
|
||||||
short tile;
|
short tile;
|
||||||
short unwrap;
|
short unwrap;
|
||||||
|
|
||||||
// boost::shared_ptr<Image> tpage;
|
// boost::shared_ptr<Image> tpage;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -234,124 +234,124 @@ struct MDeformWeight : ElemBase {
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MDeformVert : ElemBase {
|
struct MDeformVert : ElemBase {
|
||||||
|
|
||||||
vector<MDeformWeight> dw WARN;
|
vector<MDeformWeight> dw WARN;
|
||||||
int totweight;
|
int totweight;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Material : ElemBase {
|
struct Material : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
float r,g,b WARN;
|
float r,g,b WARN;
|
||||||
float specr,specg,specb WARN;
|
float specr,specg,specb WARN;
|
||||||
short har;
|
short har;
|
||||||
float ambr,ambg,ambb WARN;
|
float ambr,ambg,ambb WARN;
|
||||||
float mirr,mirg,mirb;
|
float mirr,mirg,mirb;
|
||||||
float emit WARN;
|
float emit WARN;
|
||||||
float alpha WARN;
|
float alpha WARN;
|
||||||
float ref;
|
float ref;
|
||||||
float translucency;
|
float translucency;
|
||||||
float roughness;
|
float roughness;
|
||||||
float darkness;
|
float darkness;
|
||||||
float refrac;
|
float refrac;
|
||||||
|
|
||||||
boost::shared_ptr<Group> group;
|
boost::shared_ptr<Group> group;
|
||||||
|
|
||||||
short diff_shader WARN;
|
short diff_shader WARN;
|
||||||
short spec_shader WARN;
|
short spec_shader WARN;
|
||||||
|
|
||||||
boost::shared_ptr<MTex> mtex[18];
|
boost::shared_ptr<MTex> mtex[18];
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Mesh : ElemBase {
|
struct Mesh : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
int totface FAIL;
|
int totface FAIL;
|
||||||
int totedge FAIL;
|
int totedge FAIL;
|
||||||
int totvert FAIL;
|
int totvert FAIL;
|
||||||
int totloop;
|
int totloop;
|
||||||
int totpoly;
|
int totpoly;
|
||||||
|
|
||||||
short subdiv;
|
short subdiv;
|
||||||
short subdivr;
|
short subdivr;
|
||||||
short subsurftype;
|
short subsurftype;
|
||||||
short smoothresh;
|
short smoothresh;
|
||||||
|
|
||||||
vector<MFace> mface FAIL;
|
vector<MFace> mface FAIL;
|
||||||
vector<MTFace> mtface;
|
vector<MTFace> mtface;
|
||||||
vector<TFace> tface;
|
vector<TFace> tface;
|
||||||
vector<MVert> mvert FAIL;
|
vector<MVert> mvert FAIL;
|
||||||
vector<MEdge> medge WARN;
|
vector<MEdge> medge WARN;
|
||||||
vector<MLoop> mloop;
|
vector<MLoop> mloop;
|
||||||
vector<MLoopUV> mloopuv;
|
vector<MLoopUV> mloopuv;
|
||||||
vector<MLoopCol> mloopcol;
|
vector<MLoopCol> mloopcol;
|
||||||
vector<MPoly> mpoly;
|
vector<MPoly> mpoly;
|
||||||
vector<MTexPoly> mtpoly;
|
vector<MTexPoly> mtpoly;
|
||||||
vector<MDeformVert> dvert;
|
vector<MDeformVert> dvert;
|
||||||
vector<MCol> mcol;
|
vector<MCol> mcol;
|
||||||
|
|
||||||
vector< boost::shared_ptr<Material> > mat FAIL;
|
vector< boost::shared_ptr<Material> > mat FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Library : ElemBase {
|
struct Library : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
char name[240] WARN;
|
char name[240] WARN;
|
||||||
char filename[240] FAIL;
|
char filename[240] FAIL;
|
||||||
boost::shared_ptr<Library> parent WARN;
|
boost::shared_ptr<Library> parent WARN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Camera : ElemBase {
|
struct Camera : ElemBase {
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_PERSP = 0
|
Type_PERSP = 0
|
||||||
,Type_ORTHO = 1
|
,Type_ORTHO = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
// struct AnimData *adt;
|
// struct AnimData *adt;
|
||||||
|
|
||||||
Type type,flag WARN;
|
Type type,flag WARN;
|
||||||
float angle WARN;
|
float angle WARN;
|
||||||
//float passepartalpha, angle;
|
//float passepartalpha, angle;
|
||||||
//float clipsta, clipend;
|
//float clipsta, clipend;
|
||||||
//float lens, ortho_scale, drawsize;
|
//float lens, ortho_scale, drawsize;
|
||||||
//float shiftx, shifty;
|
//float shiftx, shifty;
|
||||||
|
|
||||||
//float YF_dofdist, YF_aperture;
|
//float YF_dofdist, YF_aperture;
|
||||||
//short YF_bkhtype, YF_bkhbias;
|
//short YF_bkhtype, YF_bkhbias;
|
||||||
//float YF_bkhrot;
|
//float YF_bkhrot;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Lamp : ElemBase {
|
struct Lamp : ElemBase {
|
||||||
|
|
||||||
enum FalloffType {
|
enum FalloffType {
|
||||||
FalloffType_Constant = 0x0
|
FalloffType_Constant = 0x0
|
||||||
,FalloffType_InvLinear = 0x1
|
,FalloffType_InvLinear = 0x1
|
||||||
,FalloffType_InvSquare = 0x2
|
,FalloffType_InvSquare = 0x2
|
||||||
//,FalloffType_Curve = 0x3
|
//,FalloffType_Curve = 0x3
|
||||||
//,FalloffType_Sliders = 0x4
|
//,FalloffType_Sliders = 0x4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_Local = 0x0
|
Type_Local = 0x0
|
||||||
,Type_Sun = 0x1
|
,Type_Sun = 0x1
|
||||||
,Type_Spot = 0x2
|
,Type_Spot = 0x2
|
||||||
,Type_Hemi = 0x3
|
,Type_Hemi = 0x3
|
||||||
,Type_Area = 0x4
|
,Type_Area = 0x4
|
||||||
//,Type_YFPhoton = 0x5
|
//,Type_YFPhoton = 0x5
|
||||||
};
|
};
|
||||||
|
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
//AnimData *adt;
|
//AnimData *adt;
|
||||||
|
|
||||||
Type type FAIL;
|
Type type FAIL;
|
||||||
short flags;
|
short flags;
|
||||||
|
|
||||||
//int mode;
|
//int mode;
|
||||||
|
|
||||||
|
@ -374,33 +374,33 @@ struct Lamp : ElemBase {
|
||||||
//short ray_samp, ray_sampy, ray_sampz;
|
//short ray_samp, ray_sampy, ray_sampz;
|
||||||
//short ray_samp_type;
|
//short ray_samp_type;
|
||||||
//short area_shape;
|
//short area_shape;
|
||||||
//float area_size, area_sizey, area_sizez;
|
//float area_size, area_sizey, area_sizez;
|
||||||
//float adapt_thresh;
|
//float adapt_thresh;
|
||||||
//short ray_samp_method;
|
//short ray_samp_method;
|
||||||
|
|
||||||
//short texact, shadhalostep;
|
//short texact, shadhalostep;
|
||||||
|
|
||||||
//short sun_effect_type;
|
//short sun_effect_type;
|
||||||
//short skyblendtype;
|
//short skyblendtype;
|
||||||
//float horizon_brightness;
|
//float horizon_brightness;
|
||||||
//float spread;
|
//float spread;
|
||||||
float sun_brightness;
|
float sun_brightness;
|
||||||
//float sun_size;
|
//float sun_size;
|
||||||
//float backscattered_light;
|
//float backscattered_light;
|
||||||
//float sun_intensity;
|
//float sun_intensity;
|
||||||
//float atm_turbidity;
|
//float atm_turbidity;
|
||||||
//float atm_inscattering_factor;
|
//float atm_inscattering_factor;
|
||||||
//float atm_extinction_factor;
|
//float atm_extinction_factor;
|
||||||
//float atm_distance_factor;
|
//float atm_distance_factor;
|
||||||
//float skyblendfac;
|
//float skyblendfac;
|
||||||
//float sky_exposure;
|
//float sky_exposure;
|
||||||
//short sky_colorspace;
|
//short sky_colorspace;
|
||||||
|
|
||||||
// int YF_numphotons, YF_numsearch;
|
// int YF_numphotons, YF_numsearch;
|
||||||
// short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
|
// short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
|
||||||
// float YF_causticblur, YF_ltradius;
|
// float YF_causticblur, YF_ltradius;
|
||||||
|
|
||||||
// float YF_glowint, YF_glowofs;
|
// float YF_glowint, YF_glowofs;
|
||||||
// short YF_glowtype, YF_pad2;
|
// short YF_glowtype, YF_pad2;
|
||||||
|
|
||||||
//struct Ipo *ipo;
|
//struct Ipo *ipo;
|
||||||
|
@ -412,7 +412,7 @@ struct Lamp : ElemBase {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ModifierData : ElemBase {
|
struct ModifierData : ElemBase {
|
||||||
enum ModifierType {
|
enum ModifierType {
|
||||||
eModifierType_None = 0,
|
eModifierType_None = 0,
|
||||||
eModifierType_Subsurf,
|
eModifierType_Subsurf,
|
||||||
eModifierType_Lattice,
|
eModifierType_Lattice,
|
||||||
|
@ -446,314 +446,314 @@ struct ModifierData : ElemBase {
|
||||||
eModifierType_Surface,
|
eModifierType_Surface,
|
||||||
eModifierType_Smoke,
|
eModifierType_Smoke,
|
||||||
eModifierType_ShapeKey
|
eModifierType_ShapeKey
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::shared_ptr<ElemBase> next WARN;
|
boost::shared_ptr<ElemBase> next WARN;
|
||||||
boost::shared_ptr<ElemBase> prev WARN;
|
boost::shared_ptr<ElemBase> prev WARN;
|
||||||
|
|
||||||
int type, mode;
|
int type, mode;
|
||||||
char name[32];
|
char name[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct SubsurfModifierData : ElemBase {
|
struct SubsurfModifierData : ElemBase {
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
|
|
||||||
TYPE_CatmullClarke = 0x0,
|
TYPE_CatmullClarke = 0x0,
|
||||||
TYPE_Simple = 0x1
|
TYPE_Simple = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
// some omitted
|
// some omitted
|
||||||
FLAGS_SubsurfUV =1<<3
|
FLAGS_SubsurfUV =1<<3
|
||||||
};
|
};
|
||||||
|
|
||||||
ModifierData modifier FAIL;
|
ModifierData modifier FAIL;
|
||||||
short subdivType WARN;
|
short subdivType WARN;
|
||||||
short levels FAIL;
|
short levels FAIL;
|
||||||
short renderLevels ;
|
short renderLevels ;
|
||||||
short flags;
|
short flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MirrorModifierData : ElemBase {
|
struct MirrorModifierData : ElemBase {
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
Flags_CLIPPING =1<<0,
|
Flags_CLIPPING =1<<0,
|
||||||
Flags_MIRROR_U =1<<1,
|
Flags_MIRROR_U =1<<1,
|
||||||
Flags_MIRROR_V =1<<2,
|
Flags_MIRROR_V =1<<2,
|
||||||
Flags_AXIS_X =1<<3,
|
Flags_AXIS_X =1<<3,
|
||||||
Flags_AXIS_Y =1<<4,
|
Flags_AXIS_Y =1<<4,
|
||||||
Flags_AXIS_Z =1<<5,
|
Flags_AXIS_Z =1<<5,
|
||||||
Flags_VGROUP =1<<6
|
Flags_VGROUP =1<<6
|
||||||
};
|
};
|
||||||
|
|
||||||
ModifierData modifier FAIL;
|
ModifierData modifier FAIL;
|
||||||
|
|
||||||
short axis, flag;
|
short axis, flag;
|
||||||
float tolerance;
|
float tolerance;
|
||||||
boost::shared_ptr<Object> mirror_ob;
|
boost::shared_ptr<Object> mirror_ob;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Object : ElemBase {
|
struct Object : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_EMPTY = 0
|
Type_EMPTY = 0
|
||||||
,Type_MESH = 1
|
,Type_MESH = 1
|
||||||
,Type_CURVE = 2
|
,Type_CURVE = 2
|
||||||
,Type_SURF = 3
|
,Type_SURF = 3
|
||||||
,Type_FONT = 4
|
,Type_FONT = 4
|
||||||
,Type_MBALL = 5
|
,Type_MBALL = 5
|
||||||
|
|
||||||
,Type_LAMP = 10
|
,Type_LAMP = 10
|
||||||
,Type_CAMERA = 11
|
,Type_CAMERA = 11
|
||||||
|
|
||||||
,Type_WAVE = 21
|
,Type_WAVE = 21
|
||||||
,Type_LATTICE = 22
|
,Type_LATTICE = 22
|
||||||
};
|
};
|
||||||
|
|
||||||
Type type FAIL;
|
Type type FAIL;
|
||||||
float obmat[4][4] WARN;
|
float obmat[4][4] WARN;
|
||||||
float parentinv[4][4] WARN;
|
float parentinv[4][4] WARN;
|
||||||
char parsubstr[32] WARN;
|
char parsubstr[32] WARN;
|
||||||
|
|
||||||
Object* parent WARN;
|
Object* parent WARN;
|
||||||
boost::shared_ptr<Object> track WARN;
|
boost::shared_ptr<Object> track WARN;
|
||||||
|
|
||||||
boost::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
|
boost::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
|
||||||
boost::shared_ptr<Group> dup_group WARN;
|
boost::shared_ptr<Group> dup_group WARN;
|
||||||
boost::shared_ptr<ElemBase> data FAIL;
|
boost::shared_ptr<ElemBase> data FAIL;
|
||||||
|
|
||||||
ListBase modifiers;
|
ListBase modifiers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Base : ElemBase {
|
struct Base : ElemBase {
|
||||||
Base* prev WARN;
|
Base* prev WARN;
|
||||||
boost::shared_ptr<Base> next WARN;
|
boost::shared_ptr<Base> next WARN;
|
||||||
boost::shared_ptr<Object> object WARN;
|
boost::shared_ptr<Object> object WARN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Scene : ElemBase {
|
struct Scene : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
boost::shared_ptr<Object> camera WARN;
|
boost::shared_ptr<Object> camera WARN;
|
||||||
boost::shared_ptr<World> world WARN;
|
boost::shared_ptr<World> world WARN;
|
||||||
boost::shared_ptr<Base> basact WARN;
|
boost::shared_ptr<Base> basact WARN;
|
||||||
|
|
||||||
ListBase base;
|
ListBase base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Image : ElemBase {
|
struct Image : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
char name[240] WARN;
|
char name[240] WARN;
|
||||||
|
|
||||||
//struct anim *anim;
|
//struct anim *anim;
|
||||||
|
|
||||||
short ok, flag;
|
short ok, flag;
|
||||||
short source, type, pad, pad1;
|
short source, type, pad, pad1;
|
||||||
int lastframe;
|
int lastframe;
|
||||||
|
|
||||||
short tpageflag, totbind;
|
short tpageflag, totbind;
|
||||||
short xrep, yrep;
|
short xrep, yrep;
|
||||||
short twsta, twend;
|
short twsta, twend;
|
||||||
//unsigned int bindcode;
|
//unsigned int bindcode;
|
||||||
//unsigned int *repbind;
|
//unsigned int *repbind;
|
||||||
|
|
||||||
boost::shared_ptr<PackedFile> packedfile;
|
boost::shared_ptr<PackedFile> packedfile;
|
||||||
//struct PreviewImage * preview;
|
//struct PreviewImage * preview;
|
||||||
|
|
||||||
float lastupdate;
|
float lastupdate;
|
||||||
int lastused;
|
int lastused;
|
||||||
short animspeed;
|
short animspeed;
|
||||||
|
|
||||||
short gen_x, gen_y, gen_type;
|
short gen_x, gen_y, gen_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Tex : ElemBase {
|
struct Tex : ElemBase {
|
||||||
|
|
||||||
// actually, the only texture type we support is Type_IMAGE
|
// actually, the only texture type we support is Type_IMAGE
|
||||||
enum Type {
|
enum Type {
|
||||||
Type_CLOUDS = 1
|
Type_CLOUDS = 1
|
||||||
,Type_WOOD = 2
|
,Type_WOOD = 2
|
||||||
,Type_MARBLE = 3
|
,Type_MARBLE = 3
|
||||||
,Type_MAGIC = 4
|
,Type_MAGIC = 4
|
||||||
,Type_BLEND = 5
|
,Type_BLEND = 5
|
||||||
,Type_STUCCI = 6
|
,Type_STUCCI = 6
|
||||||
,Type_NOISE = 7
|
,Type_NOISE = 7
|
||||||
,Type_IMAGE = 8
|
,Type_IMAGE = 8
|
||||||
,Type_PLUGIN = 9
|
,Type_PLUGIN = 9
|
||||||
,Type_ENVMAP = 10
|
,Type_ENVMAP = 10
|
||||||
,Type_MUSGRAVE = 11
|
,Type_MUSGRAVE = 11
|
||||||
,Type_VORONOI = 12
|
,Type_VORONOI = 12
|
||||||
,Type_DISTNOISE = 13
|
,Type_DISTNOISE = 13
|
||||||
,Type_POINTDENSITY = 14
|
,Type_POINTDENSITY = 14
|
||||||
,Type_VOXELDATA = 15
|
,Type_VOXELDATA = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ImageFlags {
|
enum ImageFlags {
|
||||||
ImageFlags_INTERPOL = 1
|
ImageFlags_INTERPOL = 1
|
||||||
,ImageFlags_USEALPHA = 2
|
,ImageFlags_USEALPHA = 2
|
||||||
,ImageFlags_MIPMAP = 4
|
,ImageFlags_MIPMAP = 4
|
||||||
,ImageFlags_IMAROT = 16
|
,ImageFlags_IMAROT = 16
|
||||||
,ImageFlags_CALCALPHA = 32
|
,ImageFlags_CALCALPHA = 32
|
||||||
,ImageFlags_NORMALMAP = 2048
|
,ImageFlags_NORMALMAP = 2048
|
||||||
,ImageFlags_GAUSS_MIP = 4096
|
,ImageFlags_GAUSS_MIP = 4096
|
||||||
,ImageFlags_FILTER_MIN = 8192
|
,ImageFlags_FILTER_MIN = 8192
|
||||||
,ImageFlags_DERIVATIVEMAP = 16384
|
,ImageFlags_DERIVATIVEMAP = 16384
|
||||||
};
|
};
|
||||||
|
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
// AnimData *adt;
|
// AnimData *adt;
|
||||||
|
|
||||||
//float noisesize, turbul;
|
//float noisesize, turbul;
|
||||||
//float bright, contrast, rfac, gfac, bfac;
|
//float bright, contrast, rfac, gfac, bfac;
|
||||||
//float filtersize;
|
//float filtersize;
|
||||||
|
|
||||||
//float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
|
//float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
|
||||||
//float dist_amount, ns_outscale;
|
//float dist_amount, ns_outscale;
|
||||||
|
|
||||||
//float vn_w1;
|
//float vn_w1;
|
||||||
//float vn_w2;
|
//float vn_w2;
|
||||||
//float vn_w3;
|
//float vn_w3;
|
||||||
//float vn_w4;
|
//float vn_w4;
|
||||||
//float vn_mexp;
|
//float vn_mexp;
|
||||||
//short vn_distm, vn_coltype;
|
//short vn_distm, vn_coltype;
|
||||||
|
|
||||||
//short noisedepth, noisetype;
|
//short noisedepth, noisetype;
|
||||||
//short noisebasis, noisebasis2;
|
//short noisebasis, noisebasis2;
|
||||||
|
|
||||||
//short flag;
|
//short flag;
|
||||||
ImageFlags imaflag;
|
ImageFlags imaflag;
|
||||||
Type type FAIL;
|
Type type FAIL;
|
||||||
//short stype;
|
//short stype;
|
||||||
|
|
||||||
//float cropxmin, cropymin, cropxmax, cropymax;
|
//float cropxmin, cropymin, cropxmax, cropymax;
|
||||||
//int texfilter;
|
//int texfilter;
|
||||||
//int afmax;
|
//int afmax;
|
||||||
//short xrepeat, yrepeat;
|
//short xrepeat, yrepeat;
|
||||||
//short extend;
|
//short extend;
|
||||||
|
|
||||||
//short fie_ima;
|
//short fie_ima;
|
||||||
//int len;
|
//int len;
|
||||||
//int frames, offset, sfra;
|
//int frames, offset, sfra;
|
||||||
|
|
||||||
//float checkerdist, nabla;
|
//float checkerdist, nabla;
|
||||||
//float norfac;
|
//float norfac;
|
||||||
|
|
||||||
//ImageUser iuser;
|
//ImageUser iuser;
|
||||||
|
|
||||||
//bNodeTree *nodetree;
|
//bNodeTree *nodetree;
|
||||||
//Ipo *ipo;
|
//Ipo *ipo;
|
||||||
boost::shared_ptr<Image> ima WARN;
|
boost::shared_ptr<Image> ima WARN;
|
||||||
//PluginTex *plugin;
|
//PluginTex *plugin;
|
||||||
//ColorBand *coba;
|
//ColorBand *coba;
|
||||||
//EnvMap *env;
|
//EnvMap *env;
|
||||||
//PreviewImage * preview;
|
//PreviewImage * preview;
|
||||||
//PointDensity *pd;
|
//PointDensity *pd;
|
||||||
//VoxelData *vd;
|
//VoxelData *vd;
|
||||||
|
|
||||||
//char use_nodes;
|
//char use_nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTex : ElemBase {
|
struct MTex : ElemBase {
|
||||||
|
|
||||||
enum Projection {
|
enum Projection {
|
||||||
Proj_N = 0
|
Proj_N = 0
|
||||||
,Proj_X = 1
|
,Proj_X = 1
|
||||||
,Proj_Y = 2
|
,Proj_Y = 2
|
||||||
,Proj_Z = 3
|
,Proj_Z = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Flag {
|
enum Flag {
|
||||||
Flag_RGBTOINT = 0x1
|
Flag_RGBTOINT = 0x1
|
||||||
,Flag_STENCIL = 0x2
|
,Flag_STENCIL = 0x2
|
||||||
,Flag_NEGATIVE = 0x4
|
,Flag_NEGATIVE = 0x4
|
||||||
,Flag_ALPHAMIX = 0x8
|
,Flag_ALPHAMIX = 0x8
|
||||||
,Flag_VIEWSPACE = 0x10
|
,Flag_VIEWSPACE = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BlendType {
|
enum BlendType {
|
||||||
BlendType_BLEND = 0
|
BlendType_BLEND = 0
|
||||||
,BlendType_MUL = 1
|
,BlendType_MUL = 1
|
||||||
,BlendType_ADD = 2
|
,BlendType_ADD = 2
|
||||||
,BlendType_SUB = 3
|
,BlendType_SUB = 3
|
||||||
,BlendType_DIV = 4
|
,BlendType_DIV = 4
|
||||||
,BlendType_DARK = 5
|
,BlendType_DARK = 5
|
||||||
,BlendType_DIFF = 6
|
,BlendType_DIFF = 6
|
||||||
,BlendType_LIGHT = 7
|
,BlendType_LIGHT = 7
|
||||||
,BlendType_SCREEN = 8
|
,BlendType_SCREEN = 8
|
||||||
,BlendType_OVERLAY = 9
|
,BlendType_OVERLAY = 9
|
||||||
,BlendType_BLEND_HUE = 10
|
,BlendType_BLEND_HUE = 10
|
||||||
,BlendType_BLEND_SAT = 11
|
,BlendType_BLEND_SAT = 11
|
||||||
,BlendType_BLEND_VAL = 12
|
,BlendType_BLEND_VAL = 12
|
||||||
,BlendType_BLEND_COLOR = 13
|
,BlendType_BLEND_COLOR = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MapType {
|
enum MapType {
|
||||||
MapType_COL = 1
|
MapType_COL = 1
|
||||||
,MapType_NORM = 2
|
,MapType_NORM = 2
|
||||||
,MapType_COLSPEC = 4
|
,MapType_COLSPEC = 4
|
||||||
,MapType_COLMIR = 8
|
,MapType_COLMIR = 8
|
||||||
,MapType_REF = 16
|
,MapType_REF = 16
|
||||||
,MapType_SPEC = 32
|
,MapType_SPEC = 32
|
||||||
,MapType_EMIT = 64
|
,MapType_EMIT = 64
|
||||||
,MapType_ALPHA = 128
|
,MapType_ALPHA = 128
|
||||||
,MapType_HAR = 256
|
,MapType_HAR = 256
|
||||||
,MapType_RAYMIRR = 512
|
,MapType_RAYMIRR = 512
|
||||||
,MapType_TRANSLU = 1024
|
,MapType_TRANSLU = 1024
|
||||||
,MapType_AMB = 2048
|
,MapType_AMB = 2048
|
||||||
,MapType_DISPLACE = 4096
|
,MapType_DISPLACE = 4096
|
||||||
,MapType_WARP = 8192
|
,MapType_WARP = 8192
|
||||||
};
|
};
|
||||||
|
|
||||||
// short texco, maptoneg;
|
// short texco, maptoneg;
|
||||||
MapType mapto;
|
MapType mapto;
|
||||||
|
|
||||||
BlendType blendtype;
|
BlendType blendtype;
|
||||||
boost::shared_ptr<Object> object;
|
boost::shared_ptr<Object> object;
|
||||||
boost::shared_ptr<Tex> tex;
|
boost::shared_ptr<Tex> tex;
|
||||||
char uvname[32];
|
char uvname[32];
|
||||||
|
|
||||||
Projection projx,projy,projz;
|
Projection projx,projy,projz;
|
||||||
char mapping;
|
char mapping;
|
||||||
float ofs[3], size[3], rot;
|
float ofs[3], size[3], rot;
|
||||||
|
|
||||||
int texflag;
|
int texflag;
|
||||||
short colormodel, pmapto, pmaptoneg;
|
short colormodel, pmapto, pmaptoneg;
|
||||||
//short normapspace, which_output;
|
//short normapspace, which_output;
|
||||||
//char brush_map_mode;
|
//char brush_map_mode;
|
||||||
float r,g,b,k WARN;
|
float r,g,b,k WARN;
|
||||||
//float def_var, rt;
|
//float def_var, rt;
|
||||||
|
|
||||||
//float colfac, varfac;
|
//float colfac, varfac;
|
||||||
|
|
||||||
float norfac;
|
float norfac;
|
||||||
//float dispfac, warpfac;
|
//float dispfac, warpfac;
|
||||||
float colspecfac, mirrfac, alphafac;
|
float colspecfac, mirrfac, alphafac;
|
||||||
float difffac, specfac, emitfac, hardfac;
|
float difffac, specfac, emitfac, hardfac;
|
||||||
//float raymirrfac, translfac, ambfac;
|
//float raymirrfac, translfac, ambfac;
|
||||||
//float colemitfac, colreflfac, coltransfac;
|
//float colemitfac, colreflfac, coltransfac;
|
||||||
//float densfac, scatterfac, reflfac;
|
//float densfac, scatterfac, reflfac;
|
||||||
|
|
||||||
//float timefac, lengthfac, clumpfac;
|
//float timefac, lengthfac, clumpfac;
|
||||||
//float kinkfac, roughfac, padensfac;
|
//float kinkfac, roughfac, padensfac;
|
||||||
//float lifefac, sizefac, ivelfac, pvelfac;
|
//float lifefac, sizefac, ivelfac, pvelfac;
|
||||||
//float shadowfac;
|
//float shadowfac;
|
||||||
//float zenupfac, zendownfac, blendfac;
|
//float zenupfac, zendownfac, blendfac;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,8 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
#include "BlenderScene.h"
|
#include "BlenderScene.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
|
|
||||||
template <> void Structure :: Convert<Object> (
|
template <> void Structure :: Convert<Object> (
|
||||||
|
@ -250,7 +250,7 @@ template <> void Structure :: Convert<Image> (
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,7 +56,7 @@ static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
|
||||||
|
|
||||||
namspace Assimp
|
namspace Assimp
|
||||||
{
|
{
|
||||||
template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: ";
|
template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: ";
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -68,7 +68,7 @@ using namespace Assimp::Blender;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
|
BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
|
||||||
converter( &converter )
|
converter( &converter )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,167 +80,167 @@ BlenderTessellatorGL::~BlenderTessellatorGL( )
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
{
|
{
|
||||||
AssertVertexCount( vertexCount );
|
AssertVertexCount( vertexCount );
|
||||||
|
|
||||||
std::vector< VertexGL > polyLoopGL;
|
std::vector< VertexGL > polyLoopGL;
|
||||||
GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices );
|
GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices );
|
||||||
|
|
||||||
TessDataGL tessData;
|
TessDataGL tessData;
|
||||||
Tesssellate( polyLoopGL, tessData );
|
Tesssellate( polyLoopGL, tessData );
|
||||||
|
|
||||||
TriangulateDrawCalls( tessData );
|
TriangulateDrawCalls( tessData );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::AssertVertexCount( int vertexCount )
|
void BlenderTessellatorGL::AssertVertexCount( int vertexCount )
|
||||||
{
|
{
|
||||||
if ( vertexCount <= 4 )
|
if ( vertexCount <= 4 )
|
||||||
{
|
{
|
||||||
ThrowException( "Expected more than 4 vertices for tessellation" );
|
ThrowException( "Expected more than 4 vertices for tessellation" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < vertexCount; ++i )
|
for ( int i = 0; i < vertexCount; ++i )
|
||||||
{
|
{
|
||||||
const MLoop& loopItem = polyLoop[ i ];
|
const MLoop& loopItem = polyLoop[ i ];
|
||||||
const MVert& vertex = vertices[ loopItem.v ];
|
const MVert& vertex = vertices[ loopItem.v ];
|
||||||
polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) );
|
polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData )
|
void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData )
|
||||||
{
|
{
|
||||||
GLUtesselator* tessellator = gluNewTess( );
|
GLUtesselator* tessellator = gluNewTess( );
|
||||||
gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) );
|
gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) );
|
||||||
gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) );
|
gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) );
|
||||||
gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) );
|
gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) );
|
||||||
gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) );
|
gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) );
|
||||||
gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) );
|
gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) );
|
||||||
gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) );
|
gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) );
|
||||||
gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO );
|
gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO );
|
||||||
|
|
||||||
gluTessBeginPolygon( tessellator, &tessData );
|
gluTessBeginPolygon( tessellator, &tessData );
|
||||||
gluTessBeginContour( tessellator );
|
gluTessBeginContour( tessellator );
|
||||||
|
|
||||||
for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i )
|
for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i )
|
||||||
{
|
{
|
||||||
gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] );
|
gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
gluTessEndContour( tessellator );
|
gluTessEndContour( tessellator );
|
||||||
gluTessEndPolygon( tessellator );
|
gluTessEndPolygon( tessellator );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
|
void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
|
||||||
{
|
{
|
||||||
// NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
|
// NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
|
||||||
// need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
|
// need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
|
||||||
// GLU tessellate changes or tristrips and fans are wanted.
|
// GLU tessellate changes or tristrips and fans are wanted.
|
||||||
// See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
|
// See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
|
||||||
for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
|
for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
|
||||||
{
|
{
|
||||||
const DrawCallGL& drawCallGL = tessData.drawCalls[ i ];
|
const DrawCallGL& drawCallGL = tessData.drawCalls[ i ];
|
||||||
const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ];
|
const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ];
|
||||||
if ( drawCallGL.drawMode == GL_TRIANGLES )
|
if ( drawCallGL.drawMode == GL_TRIANGLES )
|
||||||
{
|
{
|
||||||
MakeFacesFromTris( vertices, drawCallGL.vertexCount );
|
MakeFacesFromTris( vertices, drawCallGL.vertexCount );
|
||||||
}
|
}
|
||||||
else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP )
|
else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP )
|
||||||
{
|
{
|
||||||
MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount );
|
MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount );
|
||||||
}
|
}
|
||||||
else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN )
|
else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN )
|
||||||
{
|
{
|
||||||
MakeFacesFromTriFan( vertices, drawCallGL.vertexCount );
|
MakeFacesFromTriFan( vertices, drawCallGL.vertexCount );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
|
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
|
||||||
{
|
{
|
||||||
int triangleCount = vertexCount / 3;
|
int triangleCount = vertexCount / 3;
|
||||||
for ( int i = 0; i < triangleCount; ++i )
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
{
|
{
|
||||||
int vertexBase = i * 3;
|
int vertexBase = i * 3;
|
||||||
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
|
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
|
||||||
{
|
{
|
||||||
int triangleCount = vertexCount - 2;
|
int triangleCount = vertexCount - 2;
|
||||||
for ( int i = 0; i < triangleCount; ++i )
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
{
|
{
|
||||||
int vertexBase = i;
|
int vertexBase = i;
|
||||||
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
|
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
|
||||||
{
|
{
|
||||||
int triangleCount = vertexCount - 2;
|
int triangleCount = vertexCount - 2;
|
||||||
for ( int i = 0; i < triangleCount; ++i )
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
{
|
{
|
||||||
int vertexBase = i;
|
int vertexBase = i;
|
||||||
converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData )
|
void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData )
|
||||||
{
|
{
|
||||||
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
|
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
|
||||||
tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) );
|
tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TessellateEnd( void* )
|
void BlenderTessellatorGL::TessellateEnd( void* )
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData )
|
void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData )
|
||||||
{
|
{
|
||||||
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
|
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
|
||||||
|
|
||||||
const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData );
|
const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData );
|
||||||
if ( vertex.magic != BLEND_TESS_MAGIC )
|
if ( vertex.magic != BLEND_TESS_MAGIC )
|
||||||
{
|
{
|
||||||
ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" );
|
ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" );
|
||||||
}
|
}
|
||||||
tessData.vertices.push_back( vertex );
|
tessData.vertices.push_back( vertex );
|
||||||
if ( tessData.drawCalls.size( ) == 0 )
|
if ( tessData.drawCalls.size( ) == 0 )
|
||||||
{
|
{
|
||||||
ThrowException( "\"Vertex\" callback received before \"Begin\"" );
|
ThrowException( "\"Vertex\" callback received before \"Begin\"" );
|
||||||
}
|
}
|
||||||
++( tessData.drawCalls.back( ).vertexCount );
|
++( tessData.drawCalls.back( ).vertexCount );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData )
|
void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData )
|
||||||
{
|
{
|
||||||
ThrowException( "Intersected polygon loops are not yet supported" );
|
ThrowException( "Intersected polygon loops are not yet supported" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* )
|
void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* )
|
||||||
{
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
||||||
{
|
{
|
||||||
ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) );
|
ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
@ -249,7 +249,7 @@ void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: ";
|
template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: ";
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -257,7 +257,7 @@ using namespace Assimp::Blender;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ):
|
BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ):
|
||||||
converter( &converter )
|
converter( &converter )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,178 +269,178 @@ BlenderTessellatorP2T::~BlenderTessellatorP2T( )
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
|
||||||
{
|
{
|
||||||
AssertVertexCount( vertexCount );
|
AssertVertexCount( vertexCount );
|
||||||
|
|
||||||
// NOTE - We have to hope that points in a Blender polygon are roughly on the same plane.
|
// NOTE - We have to hope that points in a Blender polygon are roughly on the same plane.
|
||||||
// There may be some triangulation artifacts if they are wildly different.
|
// There may be some triangulation artifacts if they are wildly different.
|
||||||
|
|
||||||
std::vector< PointP2T > points;
|
std::vector< PointP2T > points;
|
||||||
Copy3DVertices( polyLoop, vertexCount, vertices, points );
|
Copy3DVertices( polyLoop, vertexCount, vertices, points );
|
||||||
|
|
||||||
PlaneP2T plane = FindLLSQPlane( points );
|
PlaneP2T plane = FindLLSQPlane( points );
|
||||||
|
|
||||||
aiMatrix4x4 transform = GeneratePointTransformMatrix( plane );
|
aiMatrix4x4 transform = GeneratePointTransformMatrix( plane );
|
||||||
|
|
||||||
TransformAndFlattenVectices( transform, points );
|
TransformAndFlattenVectices( transform, points );
|
||||||
|
|
||||||
std::vector< p2t::Point* > pointRefs;
|
std::vector< p2t::Point* > pointRefs;
|
||||||
ReferencePoints( points, pointRefs );
|
ReferencePoints( points, pointRefs );
|
||||||
|
|
||||||
p2t::CDT cdt( pointRefs );
|
p2t::CDT cdt( pointRefs );
|
||||||
|
|
||||||
cdt.Triangulate( );
|
cdt.Triangulate( );
|
||||||
std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( );
|
std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( );
|
||||||
|
|
||||||
MakeFacesFromTriangles( triangles );
|
MakeFacesFromTriangles( triangles );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::AssertVertexCount( int vertexCount )
|
void BlenderTessellatorP2T::AssertVertexCount( int vertexCount )
|
||||||
{
|
{
|
||||||
if ( vertexCount <= 4 )
|
if ( vertexCount <= 4 )
|
||||||
{
|
{
|
||||||
ThrowException( "Expected more than 4 vertices for tessellation" );
|
ThrowException( "Expected more than 4 vertices for tessellation" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const
|
void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const
|
||||||
{
|
{
|
||||||
points.resize( vertexCount );
|
points.resize( vertexCount );
|
||||||
for ( int i = 0; i < vertexCount; ++i )
|
for ( int i = 0; i < vertexCount; ++i )
|
||||||
{
|
{
|
||||||
const MLoop& loop = polyLoop[ i ];
|
const MLoop& loop = polyLoop[ i ];
|
||||||
const MVert& vert = vertices[ loop.v ];
|
const MVert& vert = vertices[ loop.v ];
|
||||||
|
|
||||||
PointP2T& point = points[ i ];
|
PointP2T& point = points[ i ];
|
||||||
point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] );
|
point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] );
|
||||||
point.index = loop.v;
|
point.index = loop.v;
|
||||||
point.magic = BLEND_TESS_MAGIC;
|
point.magic = BLEND_TESS_MAGIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
|
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
|
||||||
{
|
{
|
||||||
aiVector3D sideA( 1.0f, 0.0f, 0.0f );
|
aiVector3D sideA( 1.0f, 0.0f, 0.0f );
|
||||||
if ( std::fabs( plane.normal * sideA ) > 0.999f )
|
if ( std::fabs( plane.normal * sideA ) > 0.999f )
|
||||||
{
|
{
|
||||||
sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
|
sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
aiVector3D sideB( plane.normal ^ sideA );
|
aiVector3D sideB( plane.normal ^ sideA );
|
||||||
sideB.Normalize( );
|
sideB.Normalize( );
|
||||||
sideA = sideB ^ plane.normal;
|
sideA = sideB ^ plane.normal;
|
||||||
|
|
||||||
aiMatrix4x4 result;
|
aiMatrix4x4 result;
|
||||||
result.a1 = sideA.x;
|
result.a1 = sideA.x;
|
||||||
result.a2 = sideA.y;
|
result.a2 = sideA.y;
|
||||||
result.a3 = sideA.z;
|
result.a3 = sideA.z;
|
||||||
result.b1 = sideB.x;
|
result.b1 = sideB.x;
|
||||||
result.b2 = sideB.y;
|
result.b2 = sideB.y;
|
||||||
result.b3 = sideB.z;
|
result.b3 = sideB.z;
|
||||||
result.c1 = plane.normal.x;
|
result.c1 = plane.normal.x;
|
||||||
result.c2 = plane.normal.y;
|
result.c2 = plane.normal.y;
|
||||||
result.c3 = plane.normal.z;
|
result.c3 = plane.normal.z;
|
||||||
result.a4 = plane.centre.x;
|
result.a4 = plane.centre.x;
|
||||||
result.b4 = plane.centre.y;
|
result.b4 = plane.centre.y;
|
||||||
result.c4 = plane.centre.z;
|
result.c4 = plane.centre.z;
|
||||||
result.Inverse( );
|
result.Inverse( );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
|
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < vertices.size( ); ++i )
|
for ( unsigned int i = 0; i < vertices.size( ); ++i )
|
||||||
{
|
{
|
||||||
PointP2T& point = vertices[ i ];
|
PointP2T& point = vertices[ i ];
|
||||||
point.point3D = transform * point.point3D;
|
point.point3D = transform * point.point3D;
|
||||||
point.point2D.set( point.point3D.y, point.point3D.z );
|
point.point2D.set( point.point3D.y, point.point3D.z );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
|
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
|
||||||
{
|
{
|
||||||
pointRefs.resize( points.size( ) );
|
pointRefs.resize( points.size( ) );
|
||||||
for ( unsigned int i = 0; i < points.size( ); ++i )
|
for ( unsigned int i = 0; i < points.size( ); ++i )
|
||||||
{
|
{
|
||||||
pointRefs[ i ] = &points[ i ].point2D;
|
pointRefs[ i ] = &points[ i ].point2D;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Yes this is filthy... but we have no choice
|
// Yes this is filthy... but we have no choice
|
||||||
#define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \
|
#define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \
|
||||||
reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \
|
reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \
|
||||||
static_cast<uint8_t*>(NULL) ) )
|
static_cast<uint8_t*>(NULL) ) )
|
||||||
|
|
||||||
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
|
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
|
||||||
{
|
{
|
||||||
unsigned int pointOffset = OffsetOf( PointP2T, point2D );
|
unsigned int pointOffset = OffsetOf( PointP2T, point2D );
|
||||||
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
|
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
|
||||||
if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
|
if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
|
||||||
{
|
{
|
||||||
ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" );
|
ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" );
|
||||||
}
|
}
|
||||||
return pointStruct;
|
return pointStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
|
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < triangles.size( ); ++i )
|
for ( unsigned int i = 0; i < triangles.size( ); ++i )
|
||||||
{
|
{
|
||||||
p2t::Triangle& Triangle = *triangles[ i ];
|
p2t::Triangle& Triangle = *triangles[ i ];
|
||||||
|
|
||||||
PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) );
|
PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) );
|
||||||
PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) );
|
PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) );
|
||||||
PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) );
|
PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) );
|
||||||
|
|
||||||
converter->AddFace( pointA.index, pointB.index, pointC.index );
|
converter->AddFace( pointA.index, pointB.index, pointC.index );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
inline float p2tMax( float a, float b )
|
inline float p2tMax( float a, float b )
|
||||||
{
|
{
|
||||||
return a > b ? a : b;
|
return a > b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const
|
float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const
|
||||||
{
|
{
|
||||||
float result = 0.0f;
|
float result = 0.0f;
|
||||||
|
|
||||||
for ( int x = 0; x < 3; ++x )
|
for ( int x = 0; x < 3; ++x )
|
||||||
{
|
{
|
||||||
for ( int y = 0; y < 3; ++y )
|
for ( int y = 0; y < 3; ++y )
|
||||||
{
|
{
|
||||||
result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
|
result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Aparently Assimp doesn't have matrix scaling
|
// Aparently Assimp doesn't have matrix scaling
|
||||||
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
|
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
|
||||||
{
|
{
|
||||||
aiMatrix3x3 result;
|
aiMatrix3x3 result;
|
||||||
|
|
||||||
for ( int x = 0; x < 3; ++x )
|
for ( int x = 0; x < 3; ++x )
|
||||||
{
|
{
|
||||||
for ( int y = 0; y < 3; ++y )
|
for ( int y = 0; y < 3; ++y )
|
||||||
{
|
{
|
||||||
result[ x ][ y ] = mtx[ x ][ y ] * scale;
|
result[ x ][ y ] = mtx[ x ][ y ] * scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,70 +448,70 @@ aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float sc
|
||||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
|
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
|
||||||
{
|
{
|
||||||
float scale = FindLargestMatrixElem( mtx );
|
float scale = FindLargestMatrixElem( mtx );
|
||||||
aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
|
aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
|
||||||
mc = mc * mc * mc;
|
mc = mc * mc * mc;
|
||||||
|
|
||||||
aiVector3D v( 1.0f );
|
aiVector3D v( 1.0f );
|
||||||
aiVector3D lastV = v;
|
aiVector3D lastV = v;
|
||||||
for ( int i = 0; i < 100; ++i )
|
for ( int i = 0; i < 100; ++i )
|
||||||
{
|
{
|
||||||
v = mc * v;
|
v = mc * v;
|
||||||
v.Normalize( );
|
v.Normalize( );
|
||||||
if ( ( v - lastV ).SquareLength( ) < 1e-16f )
|
if ( ( v - lastV ).SquareLength( ) < 1e-16f )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastV = v;
|
lastV = v;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const
|
PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const
|
||||||
{
|
{
|
||||||
PlaneP2T result;
|
PlaneP2T result;
|
||||||
|
|
||||||
aiVector3D sum( 0.0f );
|
aiVector3D sum( 0.0f );
|
||||||
for ( unsigned int i = 0; i < points.size( ); ++i )
|
for ( unsigned int i = 0; i < points.size( ); ++i )
|
||||||
{
|
{
|
||||||
sum += points[ i ].point3D;
|
sum += points[ i ].point3D;
|
||||||
}
|
}
|
||||||
result.centre = sum * ( 1.0f / points.size( ) );
|
result.centre = sum * ( 1.0f / points.size( ) );
|
||||||
|
|
||||||
float sumXX = 0.0f;
|
float sumXX = 0.0f;
|
||||||
float sumXY = 0.0f;
|
float sumXY = 0.0f;
|
||||||
float sumXZ = 0.0f;
|
float sumXZ = 0.0f;
|
||||||
float sumYY = 0.0f;
|
float sumYY = 0.0f;
|
||||||
float sumYZ = 0.0f;
|
float sumYZ = 0.0f;
|
||||||
float sumZZ = 0.0f;
|
float sumZZ = 0.0f;
|
||||||
for ( unsigned int i = 0; i < points.size( ); ++i )
|
for ( unsigned int i = 0; i < points.size( ); ++i )
|
||||||
{
|
{
|
||||||
aiVector3D offset = points[ i ].point3D - result.centre;
|
aiVector3D offset = points[ i ].point3D - result.centre;
|
||||||
sumXX += offset.x * offset.x;
|
sumXX += offset.x * offset.x;
|
||||||
sumXY += offset.x * offset.y;
|
sumXY += offset.x * offset.y;
|
||||||
sumXZ += offset.x * offset.z;
|
sumXZ += offset.x * offset.z;
|
||||||
sumYY += offset.y * offset.y;
|
sumYY += offset.y * offset.y;
|
||||||
sumYZ += offset.y * offset.z;
|
sumYZ += offset.y * offset.z;
|
||||||
sumZZ += offset.z * offset.z;
|
sumZZ += offset.z * offset.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
|
aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
|
||||||
|
|
||||||
float det = mtx.Determinant( );
|
float det = mtx.Determinant( );
|
||||||
if ( det == 0.0f )
|
if ( det == 0.0f )
|
||||||
{
|
{
|
||||||
result.normal = aiVector3D( 0.0f );
|
result.normal = aiVector3D( 0.0f );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aiMatrix3x3 invMtx = mtx;
|
aiMatrix3x3 invMtx = mtx;
|
||||||
invMtx.Inverse( );
|
invMtx.Inverse( );
|
||||||
result.normal = GetEigenVectorFromLargestEigenValue( invMtx );
|
result.normal = GetEigenVectorFromLargestEigenValue( invMtx );
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
|
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
|
@ -50,11 +50,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// made configurable in CMake and potentially not wanted by most users
|
// made configurable in CMake and potentially not wanted by most users
|
||||||
// as it requires a Gl environment.
|
// as it requires a Gl environment.
|
||||||
#ifndef ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
#ifndef ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
# define ASSIMP_BLEND_WITH_GLU_TESSELLATE 0
|
# define ASSIMP_BLEND_WITH_GLU_TESSELLATE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BLEND_WITH_POLY_2_TRI
|
#ifndef ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
# define ASSIMP_BLEND_WITH_POLY_2_TRI 1
|
# define ASSIMP_BLEND_WITH_POLY_2_TRI 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "LogAux.h"
|
#include "LogAux.h"
|
||||||
|
@ -68,74 +68,74 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
class BlenderBMeshConverter;
|
class BlenderBMeshConverter;
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter
|
namespace Formatter
|
||||||
{
|
{
|
||||||
template < typename T,typename TR, typename A > class basic_formatter;
|
template < typename T,typename TR, typename A > class basic_formatter;
|
||||||
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderScene.h
|
// BlenderScene.h
|
||||||
namespace Blender
|
namespace Blender
|
||||||
{
|
{
|
||||||
struct MLoop;
|
struct MLoop;
|
||||||
struct MVert;
|
struct MVert;
|
||||||
|
|
||||||
struct VertexGL
|
struct VertexGL
|
||||||
{
|
{
|
||||||
GLdouble X;
|
GLdouble X;
|
||||||
GLdouble Y;
|
GLdouble Y;
|
||||||
GLdouble Z;
|
GLdouble Z;
|
||||||
int index;
|
int index;
|
||||||
int magic;
|
int magic;
|
||||||
|
|
||||||
VertexGL( GLdouble X, GLdouble Y, GLdouble Z, int index, int magic ): X( X ), Y( Y ), Z( Z ), index( index ), magic( magic ) { }
|
VertexGL( GLdouble X, GLdouble Y, GLdouble Z, int index, int magic ): X( X ), Y( Y ), Z( Z ), index( index ), magic( magic ) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DrawCallGL
|
struct DrawCallGL
|
||||||
{
|
{
|
||||||
GLenum drawMode;
|
GLenum drawMode;
|
||||||
int baseVertex;
|
int baseVertex;
|
||||||
int vertexCount;
|
int vertexCount;
|
||||||
|
|
||||||
DrawCallGL( GLenum drawMode, int baseVertex ): drawMode( drawMode ), baseVertex( baseVertex ), vertexCount( 0 ) { }
|
DrawCallGL( GLenum drawMode, int baseVertex ): drawMode( drawMode ), baseVertex( baseVertex ), vertexCount( 0 ) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TessDataGL
|
struct TessDataGL
|
||||||
{
|
{
|
||||||
std::vector< DrawCallGL > drawCalls;
|
std::vector< DrawCallGL > drawCalls;
|
||||||
std::vector< VertexGL > vertices;
|
std::vector< VertexGL > vertices;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlenderTessellatorGL: public LogFunctions< BlenderTessellatorGL >
|
class BlenderTessellatorGL: public LogFunctions< BlenderTessellatorGL >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlenderTessellatorGL( BlenderBMeshConverter& converter );
|
BlenderTessellatorGL( BlenderBMeshConverter& converter );
|
||||||
~BlenderTessellatorGL( );
|
~BlenderTessellatorGL( );
|
||||||
|
|
||||||
void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AssertVertexCount( int vertexCount );
|
void AssertVertexCount( int vertexCount );
|
||||||
void GenerateLoopVerts( std::vector< Blender::VertexGL >& polyLoopGL, const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
void GenerateLoopVerts( std::vector< Blender::VertexGL >& polyLoopGL, const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
||||||
void Tesssellate( std::vector< Blender::VertexGL >& polyLoopGL, Blender::TessDataGL& tessData );
|
void Tesssellate( std::vector< Blender::VertexGL >& polyLoopGL, Blender::TessDataGL& tessData );
|
||||||
void TriangulateDrawCalls( const Blender::TessDataGL& tessData );
|
void TriangulateDrawCalls( const Blender::TessDataGL& tessData );
|
||||||
void MakeFacesFromTris( const Blender::VertexGL* vertices, int vertexCount );
|
void MakeFacesFromTris( const Blender::VertexGL* vertices, int vertexCount );
|
||||||
void MakeFacesFromTriStrip( const Blender::VertexGL* vertices, int vertexCount );
|
void MakeFacesFromTriStrip( const Blender::VertexGL* vertices, int vertexCount );
|
||||||
void MakeFacesFromTriFan( const Blender::VertexGL* vertices, int vertexCount );
|
void MakeFacesFromTriFan( const Blender::VertexGL* vertices, int vertexCount );
|
||||||
|
|
||||||
static void TessellateBegin( GLenum drawModeGL, void* userData );
|
static void TessellateBegin( GLenum drawModeGL, void* userData );
|
||||||
static void TessellateEnd( void* userData );
|
static void TessellateEnd( void* userData );
|
||||||
static void TessellateVertex( const void* vtxData, void* userData );
|
static void TessellateVertex( const void* vtxData, void* userData );
|
||||||
static void TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData );
|
static void TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData );
|
||||||
static void TessellateEdgeFlag( GLboolean edgeFlag, void* userData );
|
static void TessellateEdgeFlag( GLboolean edgeFlag, void* userData );
|
||||||
static void TessellateError( GLenum errorCode, void* userData );
|
static void TessellateError( GLenum errorCode, void* userData );
|
||||||
|
|
||||||
BlenderBMeshConverter* converter;
|
BlenderBMeshConverter* converter;
|
||||||
};
|
};
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
@ -146,61 +146,61 @@ namespace Assimp
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
class BlenderBMeshConverter;
|
class BlenderBMeshConverter;
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter
|
namespace Formatter
|
||||||
{
|
{
|
||||||
template < typename T,typename TR, typename A > class basic_formatter;
|
template < typename T,typename TR, typename A > class basic_formatter;
|
||||||
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
typedef class basic_formatter< char, std::char_traits< char >, std::allocator< char > > format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlenderScene.h
|
// BlenderScene.h
|
||||||
namespace Blender
|
namespace Blender
|
||||||
{
|
{
|
||||||
struct MLoop;
|
struct MLoop;
|
||||||
struct MVert;
|
struct MVert;
|
||||||
|
|
||||||
struct PointP2T
|
struct PointP2T
|
||||||
{
|
{
|
||||||
aiVector3D point3D;
|
aiVector3D point3D;
|
||||||
p2t::Point point2D;
|
p2t::Point point2D;
|
||||||
int magic;
|
int magic;
|
||||||
int index;
|
int index;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlaneP2T
|
struct PlaneP2T
|
||||||
{
|
{
|
||||||
aiVector3D centre;
|
aiVector3D centre;
|
||||||
aiVector3D normal;
|
aiVector3D normal;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class BlenderTessellatorP2T: public LogFunctions< BlenderTessellatorP2T >
|
class BlenderTessellatorP2T: public LogFunctions< BlenderTessellatorP2T >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BlenderTessellatorP2T( BlenderBMeshConverter& converter );
|
BlenderTessellatorP2T( BlenderBMeshConverter& converter );
|
||||||
~BlenderTessellatorP2T( );
|
~BlenderTessellatorP2T( );
|
||||||
|
|
||||||
void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
void Tessellate( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AssertVertexCount( int vertexCount );
|
void AssertVertexCount( int vertexCount );
|
||||||
void Copy3DVertices( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices, std::vector< Blender::PointP2T >& targetVertices ) const;
|
void Copy3DVertices( const Blender::MLoop* polyLoop, int vertexCount, const std::vector< Blender::MVert >& vertices, std::vector< Blender::PointP2T >& targetVertices ) const;
|
||||||
aiMatrix4x4 GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const;
|
aiMatrix4x4 GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const;
|
||||||
void TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const;
|
void TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const;
|
||||||
void ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const;
|
void ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const;
|
||||||
inline Blender::PointP2T& GetActualPointStructure( p2t::Point& point ) const;
|
inline Blender::PointP2T& GetActualPointStructure( p2t::Point& point ) const;
|
||||||
void MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const;
|
void MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const;
|
||||||
|
|
||||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
float FindLargestMatrixElem( const aiMatrix3x3& mtx ) const;
|
float FindLargestMatrixElem( const aiMatrix3x3& mtx ) const;
|
||||||
aiMatrix3x3 ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const;
|
aiMatrix3x3 ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const;
|
||||||
aiVector3D GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const;
|
aiVector3D GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const;
|
||||||
Blender::PlaneP2T FindLLSQPlane( const std::vector< Blender::PointP2T >& points ) const;
|
Blender::PlaneP2T FindLLSQPlane( const std::vector< Blender::PointP2T >& points ) const;
|
||||||
|
|
||||||
BlenderBMeshConverter* converter;
|
BlenderBMeshConverter* converter;
|
||||||
};
|
};
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
|
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -54,8 +54,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
class BlobIOSystem;
|
class BlobIOSystem;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
/** Redirect IOStream to a blob */
|
/** Redirect IOStream to a blob */
|
||||||
|
@ -64,144 +64,144 @@ class BlobIOStream : public IOStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
|
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
|
||||||
: buffer()
|
: buffer()
|
||||||
, cur_size()
|
, cur_size()
|
||||||
, file_size()
|
, file_size()
|
||||||
, cursor()
|
, cursor()
|
||||||
, initial(initial)
|
, initial(initial)
|
||||||
, file(file)
|
, file(file)
|
||||||
, creator(creator)
|
, creator(creator)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual ~BlobIOStream();
|
virtual ~BlobIOStream();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
aiExportDataBlob* GetBlob()
|
aiExportDataBlob* GetBlob()
|
||||||
{
|
{
|
||||||
aiExportDataBlob* blob = new aiExportDataBlob();
|
aiExportDataBlob* blob = new aiExportDataBlob();
|
||||||
blob->size = file_size;
|
blob->size = file_size;
|
||||||
blob->data = buffer;
|
blob->data = buffer;
|
||||||
|
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
||||||
return blob;
|
return blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Read( void *,
|
virtual size_t Read( void *,
|
||||||
size_t,
|
size_t,
|
||||||
size_t )
|
size_t )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Write(const void* pvBuffer,
|
virtual size_t Write(const void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount)
|
size_t pCount)
|
||||||
{
|
{
|
||||||
pSize *= pCount;
|
pSize *= pCount;
|
||||||
if (cursor + pSize > cur_size) {
|
if (cursor + pSize > cur_size) {
|
||||||
Grow(cursor + pSize);
|
Grow(cursor + pSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer+cursor, pvBuffer, pSize);
|
memcpy(buffer+cursor, pvBuffer, pSize);
|
||||||
cursor += pSize;
|
cursor += pSize;
|
||||||
|
|
||||||
file_size = std::max(file_size,cursor);
|
file_size = std::max(file_size,cursor);
|
||||||
return pCount;
|
return pCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual aiReturn Seek(size_t pOffset,
|
virtual aiReturn Seek(size_t pOffset,
|
||||||
aiOrigin pOrigin)
|
aiOrigin pOrigin)
|
||||||
{
|
{
|
||||||
switch(pOrigin)
|
switch(pOrigin)
|
||||||
{
|
{
|
||||||
case aiOrigin_CUR:
|
case aiOrigin_CUR:
|
||||||
cursor += pOffset;
|
cursor += pOffset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aiOrigin_END:
|
case aiOrigin_END:
|
||||||
cursor = file_size - pOffset;
|
cursor = file_size - pOffset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aiOrigin_SET:
|
case aiOrigin_SET:
|
||||||
cursor = pOffset;
|
cursor = pOffset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursor > file_size) {
|
if (cursor > file_size) {
|
||||||
Grow(cursor);
|
Grow(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_size = std::max(cursor,file_size);
|
file_size = std::max(cursor,file_size);
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Tell() const
|
virtual size_t Tell() const
|
||||||
{
|
{
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t FileSize() const
|
virtual size_t FileSize() const
|
||||||
{
|
{
|
||||||
return file_size;
|
return file_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual void Flush()
|
virtual void Flush()
|
||||||
{
|
{
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Grow(size_t need = 0)
|
void Grow(size_t need = 0)
|
||||||
{
|
{
|
||||||
// 1.5 and phi are very heap-friendly growth factors (the first
|
// 1.5 and phi are very heap-friendly growth factors (the first
|
||||||
// allows for frequent re-use of heap blocks, the second
|
// allows for frequent re-use of heap blocks, the second
|
||||||
// forms a fibonacci sequence with similar characteristics -
|
// forms a fibonacci sequence with similar characteristics -
|
||||||
// since this heavily depends on the heap implementation
|
// since this heavily depends on the heap implementation
|
||||||
// and other factors as well, i'll just go with 1.5 since
|
// and other factors as well, i'll just go with 1.5 since
|
||||||
// it is quicker to compute).
|
// it is quicker to compute).
|
||||||
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
|
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
|
||||||
|
|
||||||
const uint8_t* const old = buffer;
|
const uint8_t* const old = buffer;
|
||||||
buffer = new uint8_t[new_size];
|
buffer = new uint8_t[new_size];
|
||||||
|
|
||||||
if (old) {
|
if (old) {
|
||||||
memcpy(buffer,old,cur_size);
|
memcpy(buffer,old,cur_size);
|
||||||
delete[] old;
|
delete[] old;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_size = new_size;
|
cur_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint8_t* buffer;
|
uint8_t* buffer;
|
||||||
size_t cur_size,file_size, cursor, initial;
|
size_t cur_size,file_size, cursor, initial;
|
||||||
|
|
||||||
const std::string file;
|
const std::string file;
|
||||||
BlobIOSystem* const creator;
|
BlobIOSystem* const creator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,122 +213,122 @@ private:
|
||||||
class BlobIOSystem : public IOSystem
|
class BlobIOSystem : public IOSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
friend class BlobIOStream;
|
friend class BlobIOStream;
|
||||||
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
|
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BlobIOSystem()
|
BlobIOSystem()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~BlobIOSystem()
|
virtual ~BlobIOSystem()
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(BlobEntry& blobby, blobs) {
|
BOOST_FOREACH(BlobEntry& blobby, blobs) {
|
||||||
delete blobby.second;
|
delete blobby.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
const char* GetMagicFileName() const
|
const char* GetMagicFileName() const
|
||||||
{
|
{
|
||||||
return AI_BLOBIO_MAGIC;
|
return AI_BLOBIO_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
aiExportDataBlob* GetBlobChain()
|
aiExportDataBlob* GetBlobChain()
|
||||||
{
|
{
|
||||||
// one must be the master
|
// one must be the master
|
||||||
aiExportDataBlob* master = NULL, *cur;
|
aiExportDataBlob* master = NULL, *cur;
|
||||||
BOOST_FOREACH(const BlobEntry& blobby, blobs) {
|
BOOST_FOREACH(const BlobEntry& blobby, blobs) {
|
||||||
if (blobby.first == AI_BLOBIO_MAGIC) {
|
if (blobby.first == AI_BLOBIO_MAGIC) {
|
||||||
master = blobby.second;
|
master = blobby.second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!master) {
|
if (!master) {
|
||||||
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
|
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
master->name.Set("");
|
master->name.Set("");
|
||||||
|
|
||||||
cur = master;
|
cur = master;
|
||||||
BOOST_FOREACH(const BlobEntry& blobby, blobs) {
|
BOOST_FOREACH(const BlobEntry& blobby, blobs) {
|
||||||
if (blobby.second == master) {
|
if (blobby.second == master) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur->next = blobby.second;
|
cur->next = blobby.second;
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
|
|
||||||
// extract the file extension from the file written
|
// extract the file extension from the file written
|
||||||
const std::string::size_type s = blobby.first.find_first_of('.');
|
const std::string::size_type s = blobby.first.find_first_of('.');
|
||||||
cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
|
cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// give up blob ownership
|
// give up blob ownership
|
||||||
blobs.clear();
|
blobs.clear();
|
||||||
return master;
|
return master;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual bool Exists( const char* pFile) const {
|
virtual bool Exists( const char* pFile) const {
|
||||||
return created.find(std::string(pFile)) != created.end();
|
return created.find(std::string(pFile)) != created.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual char getOsSeparator() const {
|
virtual char getOsSeparator() const {
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual IOStream* Open(const char* pFile,
|
virtual IOStream* Open(const char* pFile,
|
||||||
const char* pMode)
|
const char* pMode)
|
||||||
{
|
{
|
||||||
if (pMode[0] != 'w') {
|
if (pMode[0] != 'w') {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
created.insert(std::string(pFile));
|
created.insert(std::string(pFile));
|
||||||
return new BlobIOStream(this,std::string(pFile));
|
return new BlobIOStream(this,std::string(pFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual void Close( IOStream* pFile)
|
virtual void Close( IOStream* pFile)
|
||||||
{
|
{
|
||||||
delete pFile;
|
delete pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void OnDestruct(const std::string& filename, BlobIOStream* child)
|
void OnDestruct(const std::string& filename, BlobIOStream* child)
|
||||||
{
|
{
|
||||||
// we don't know in which the files are closed, so we
|
// we don't know in which the files are closed, so we
|
||||||
// can't reliably say that the first must be the master
|
// can't reliably say that the first must be the master
|
||||||
// file ...
|
// file ...
|
||||||
blobs.push_back( BlobEntry(filename,child->GetBlob()) );
|
blobs.push_back( BlobEntry(filename,child->GetBlob()) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<std::string> created;
|
std::set<std::string> created;
|
||||||
std::vector< BlobEntry > blobs;
|
std::vector< BlobEntry > blobs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
BlobIOStream :: ~BlobIOStream()
|
BlobIOStream :: ~BlobIOStream()
|
||||||
{
|
{
|
||||||
creator->OnDestruct(file,this);
|
creator->OnDestruct(file,this);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
/** Defines some useful byte order swap routines.
|
/** Defines some useful byte order swap routines.
|
||||||
*
|
*
|
||||||
|
@ -60,143 +60,143 @@ namespace Assimp {
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class ByteSwap
|
class ByteSwap
|
||||||
{
|
{
|
||||||
ByteSwap() {}
|
ByteSwap() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** Swap two bytes of data
|
/** Swap two bytes of data
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||||
static inline void Swap2(void* _szOut)
|
static inline void Swap2(void* _szOut)
|
||||||
{
|
{
|
||||||
ai_assert(_szOut);
|
ai_assert(_szOut);
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
||||||
*szOut = _byteswap_ushort(*szOut);
|
*szOut = _byteswap_ushort(*szOut);
|
||||||
#else
|
#else
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||||
std::swap(szOut[0],szOut[1]);
|
std::swap(szOut[0],szOut[1]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** Swap four bytes of data
|
/** Swap four bytes of data
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||||
static inline void Swap4(void* _szOut)
|
static inline void Swap4(void* _szOut)
|
||||||
{
|
{
|
||||||
ai_assert(_szOut);
|
ai_assert(_szOut);
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
||||||
*szOut = _byteswap_ulong(*szOut);
|
*szOut = _byteswap_ulong(*szOut);
|
||||||
#else
|
#else
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||||
std::swap(szOut[0],szOut[3]);
|
std::swap(szOut[0],szOut[3]);
|
||||||
std::swap(szOut[1],szOut[2]);
|
std::swap(szOut[1],szOut[2]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** Swap eight bytes of data
|
/** Swap eight bytes of data
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||||
static inline void Swap8(void* _szOut)
|
static inline void Swap8(void* _szOut)
|
||||||
{
|
{
|
||||||
ai_assert(_szOut);
|
ai_assert(_szOut);
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
||||||
*szOut = _byteswap_uint64(*szOut);
|
*szOut = _byteswap_uint64(*szOut);
|
||||||
#else
|
#else
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||||
std::swap(szOut[0],szOut[7]);
|
std::swap(szOut[0],szOut[7]);
|
||||||
std::swap(szOut[1],szOut[6]);
|
std::swap(szOut[1],szOut[6]);
|
||||||
std::swap(szOut[2],szOut[5]);
|
std::swap(szOut[2],szOut[5]);
|
||||||
std::swap(szOut[3],szOut[4]);
|
std::swap(szOut[3],szOut[4]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** ByteSwap a float. Not a joke.
|
/** ByteSwap a float. Not a joke.
|
||||||
* @param[inout] fOut ehm. .. */
|
* @param[inout] fOut ehm. .. */
|
||||||
static inline void Swap(float* fOut) {
|
static inline void Swap(float* fOut) {
|
||||||
Swap4(fOut);
|
Swap4(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** ByteSwap a double. Not a joke.
|
/** ByteSwap a double. Not a joke.
|
||||||
* @param[inout] fOut ehm. .. */
|
* @param[inout] fOut ehm. .. */
|
||||||
static inline void Swap(double* fOut) {
|
static inline void Swap(double* fOut) {
|
||||||
Swap8(fOut);
|
Swap8(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** ByteSwap an int16t. Not a joke.
|
/** ByteSwap an int16t. Not a joke.
|
||||||
* @param[inout] fOut ehm. .. */
|
* @param[inout] fOut ehm. .. */
|
||||||
static inline void Swap(int16_t* fOut) {
|
static inline void Swap(int16_t* fOut) {
|
||||||
Swap2(fOut);
|
Swap2(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void Swap(uint16_t* fOut) {
|
static inline void Swap(uint16_t* fOut) {
|
||||||
Swap2(fOut);
|
Swap2(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** ByteSwap an int32t. Not a joke.
|
/** ByteSwap an int32t. Not a joke.
|
||||||
* @param[inout] fOut ehm. .. */
|
* @param[inout] fOut ehm. .. */
|
||||||
static inline void Swap(int32_t* fOut){
|
static inline void Swap(int32_t* fOut){
|
||||||
Swap4(fOut);
|
Swap4(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void Swap(uint32_t* fOut){
|
static inline void Swap(uint32_t* fOut){
|
||||||
Swap4(fOut);
|
Swap4(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
/** ByteSwap an int64t. Not a joke.
|
/** ByteSwap an int64t. Not a joke.
|
||||||
* @param[inout] fOut ehm. .. */
|
* @param[inout] fOut ehm. .. */
|
||||||
static inline void Swap(int64_t* fOut) {
|
static inline void Swap(int64_t* fOut) {
|
||||||
Swap8(fOut);
|
Swap8(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void Swap(uint64_t* fOut) {
|
static inline void Swap(uint64_t* fOut) {
|
||||||
Swap8(fOut);
|
Swap8(fOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
//! Templatized ByteSwap
|
//! Templatized ByteSwap
|
||||||
//! \returns param tOut as swapped
|
//! \returns param tOut as swapped
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
static inline Type Swapped(Type tOut)
|
static inline Type Swapped(Type tOut)
|
||||||
{
|
{
|
||||||
return _swapper<Type,sizeof(Type)>()(tOut);
|
return _swapper<Type,sizeof(Type)>()(tOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template <typename T, size_t size> struct _swapper;
|
template <typename T, size_t size> struct _swapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,2> {
|
template <typename T> struct ByteSwap::_swapper<T,2> {
|
||||||
T operator() (T tOut) {
|
T operator() (T tOut) {
|
||||||
Swap2(&tOut);
|
Swap2(&tOut);
|
||||||
return tOut;
|
return tOut;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,4> {
|
template <typename T> struct ByteSwap::_swapper<T,4> {
|
||||||
T operator() (T tOut) {
|
T operator() (T tOut) {
|
||||||
Swap4(&tOut);
|
Swap4(&tOut);
|
||||||
return tOut;
|
return tOut;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,8> {
|
template <typename T> struct ByteSwap::_swapper<T,8> {
|
||||||
T operator() (T tOut) {
|
T operator() (T tOut) {
|
||||||
Swap8(&tOut);
|
Swap8(&tOut);
|
||||||
return tOut;
|
return tOut;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -204,39 +204,39 @@ template <typename T> struct ByteSwap::_swapper<T,8> {
|
||||||
// ByteSwap macros for BigEndian/LittleEndian support
|
// ByteSwap macros for BigEndian/LittleEndian support
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
#if (defined AI_BUILD_BIG_ENDIAN)
|
#if (defined AI_BUILD_BIG_ENDIAN)
|
||||||
# define AI_LE(t) (t)
|
# define AI_LE(t) (t)
|
||||||
# define AI_BE(t) ByteSwap::Swapped(t)
|
# define AI_BE(t) ByteSwap::Swapped(t)
|
||||||
# define AI_LSWAP2(p)
|
# define AI_LSWAP2(p)
|
||||||
# define AI_LSWAP4(p)
|
# define AI_LSWAP4(p)
|
||||||
# define AI_LSWAP8(p)
|
# define AI_LSWAP8(p)
|
||||||
# define AI_LSWAP2P(p)
|
# define AI_LSWAP2P(p)
|
||||||
# define AI_LSWAP4P(p)
|
# define AI_LSWAP4P(p)
|
||||||
# define AI_LSWAP8P(p)
|
# define AI_LSWAP8P(p)
|
||||||
# define LE_NCONST const
|
# define LE_NCONST const
|
||||||
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
||||||
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
||||||
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
||||||
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
||||||
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
||||||
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
||||||
# define BE_NCONST
|
# define BE_NCONST
|
||||||
#else
|
#else
|
||||||
# define AI_BE(t) (t)
|
# define AI_BE(t) (t)
|
||||||
# define AI_LE(t) ByteSwap::Swapped(t)
|
# define AI_LE(t) ByteSwap::Swapped(t)
|
||||||
# define AI_SWAP2(p)
|
# define AI_SWAP2(p)
|
||||||
# define AI_SWAP4(p)
|
# define AI_SWAP4(p)
|
||||||
# define AI_SWAP8(p)
|
# define AI_SWAP8(p)
|
||||||
# define AI_SWAP2P(p)
|
# define AI_SWAP2P(p)
|
||||||
# define AI_SWAP4P(p)
|
# define AI_SWAP4P(p)
|
||||||
# define AI_SWAP8P(p)
|
# define AI_SWAP8P(p)
|
||||||
# define BE_NCONST const
|
# define BE_NCONST const
|
||||||
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
||||||
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
||||||
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
||||||
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
||||||
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
||||||
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
||||||
# define LE_NCONST
|
# define LE_NCONST
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,41 +244,41 @@ namespace Intern {
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
template <typename T, bool doit>
|
template <typename T, bool doit>
|
||||||
struct ByteSwapper {
|
struct ByteSwapper {
|
||||||
void operator() (T* inout) {
|
void operator() (T* inout) {
|
||||||
ByteSwap::Swap(inout);
|
ByteSwap::Swap(inout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ByteSwapper<T,false> {
|
struct ByteSwapper<T,false> {
|
||||||
void operator() (T*) {
|
void operator() (T*) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
||||||
struct Getter {
|
struct Getter {
|
||||||
void operator() (T* inout, bool le) {
|
void operator() (T* inout, bool le) {
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
le = le;
|
le = le;
|
||||||
#else
|
#else
|
||||||
le = !le;
|
le = !le;
|
||||||
#endif
|
#endif
|
||||||
if (le) {
|
if (le) {
|
||||||
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
||||||
}
|
}
|
||||||
else ByteSwapper<T,false> () (inout);
|
else ByteSwapper<T,false> () (inout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <bool SwapEndianess, typename T>
|
template <bool SwapEndianess, typename T>
|
||||||
struct Getter<SwapEndianess,T,false> {
|
struct Getter<SwapEndianess,T,false> {
|
||||||
|
|
||||||
void operator() (T* inout, bool /*le*/) {
|
void operator() (T* inout, bool /*le*/) {
|
||||||
// static branch
|
// static branch
|
||||||
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // end Intern
|
} // end Intern
|
||||||
} // end Assimp
|
} // end Assimp
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -55,19 +55,19 @@ struct aiMaterial;
|
||||||
struct aiImporterDesc;
|
struct aiImporterDesc;
|
||||||
|
|
||||||
namespace _melange_ {
|
namespace _melange_ {
|
||||||
class BaseObject; // c4d_file.h
|
class BaseObject; // c4d_file.h
|
||||||
class PolygonObject;
|
class PolygonObject;
|
||||||
class BaseMaterial;
|
class BaseMaterial;
|
||||||
class BaseShader;
|
class BaseShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter {
|
namespace Formatter {
|
||||||
template <typename T,typename TR, typename A> class basic_formatter;
|
template <typename T,typename TR, typename A> class basic_formatter;
|
||||||
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Importer class to load Cinema4D files using the Melange library to be obtained from
|
/** Importer class to load Cinema4D files using the Melange library to be obtained from
|
||||||
|
@ -79,42 +79,42 @@ class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
C4DImporter();
|
C4DImporter();
|
||||||
~C4DImporter();
|
~C4DImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadMaterials(_melange_::BaseMaterial* mat);
|
void ReadMaterials(_melange_::BaseMaterial* mat);
|
||||||
void RecurseHierarchy(_melange_::BaseObject* object, aiNode* parent);
|
void RecurseHierarchy(_melange_::BaseObject* object, aiNode* parent);
|
||||||
aiMesh* ReadMesh(_melange_::BaseObject* object);
|
aiMesh* ReadMesh(_melange_::BaseObject* object);
|
||||||
unsigned int ResolveMaterial(_melange_::PolygonObject* obj);
|
unsigned int ResolveMaterial(_melange_::PolygonObject* obj);
|
||||||
|
|
||||||
bool ReadShader(aiMaterial* out, _melange_::BaseShader* shader);
|
bool ReadShader(aiMaterial* out, _melange_::BaseShader* shader);
|
||||||
|
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
std::vector<aiMaterial*> materials;
|
std::vector<aiMaterial*> materials;
|
||||||
|
|
||||||
typedef std::map<_melange_::BaseMaterial*, unsigned int> MaterialMap;
|
typedef std::map<_melange_::BaseMaterial*, unsigned int> MaterialMap;
|
||||||
MaterialMap material_mapping;
|
MaterialMap material_mapping;
|
||||||
|
|
||||||
}; // !class C4DImporter
|
}; // !class C4DImporter
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -48,61 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/assimp/IOStream.hpp"
|
#include "../include/assimp/IOStream.hpp"
|
||||||
#include "../include/assimp/IOSystem.hpp"
|
#include "../include/assimp/IOSystem.hpp"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Custom IOStream implementation for the C-API
|
// Custom IOStream implementation for the C-API
|
||||||
class CIOStreamWrapper : public IOStream
|
class CIOStreamWrapper : public IOStream
|
||||||
{
|
{
|
||||||
friend class CIOSystemWrapper;
|
friend class CIOSystemWrapper;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CIOStreamWrapper(aiFile* pFile)
|
CIOStreamWrapper(aiFile* pFile)
|
||||||
: mFile(pFile)
|
: mFile(pFile)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
size_t Read(void* pvBuffer,
|
size_t Read(void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount
|
size_t pCount
|
||||||
){
|
){
|
||||||
// need to typecast here as C has no void*
|
// need to typecast here as C has no void*
|
||||||
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
|
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
size_t Write(const void* pvBuffer,
|
size_t Write(const void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount
|
size_t pCount
|
||||||
){
|
){
|
||||||
// need to typecast here as C has no void*
|
// need to typecast here as C has no void*
|
||||||
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
|
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
aiReturn Seek(size_t pOffset,
|
aiReturn Seek(size_t pOffset,
|
||||||
aiOrigin pOrigin
|
aiOrigin pOrigin
|
||||||
){
|
){
|
||||||
return mFile->SeekProc(mFile,pOffset,pOrigin);
|
return mFile->SeekProc(mFile,pOffset,pOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
size_t Tell(void) const {
|
size_t Tell(void) const {
|
||||||
return mFile->TellProc(mFile);
|
return mFile->TellProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
size_t FileSize() const {
|
size_t FileSize() const {
|
||||||
return mFile->FileSizeProc(mFile);
|
return mFile->FileSizeProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
void Flush () {
|
void Flush () {
|
||||||
return mFile->FlushProc(mFile);
|
return mFile->FlushProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
aiFile* mFile;
|
aiFile* mFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -110,48 +110,48 @@ private:
|
||||||
class CIOSystemWrapper : public IOSystem
|
class CIOSystemWrapper : public IOSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CIOSystemWrapper(aiFileIO* pFile)
|
CIOSystemWrapper(aiFileIO* pFile)
|
||||||
: mFileSystem(pFile)
|
: mFileSystem(pFile)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
bool Exists( const char* pFile) const {
|
bool Exists( const char* pFile) const {
|
||||||
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
|
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
|
||||||
if (p){
|
if (p){
|
||||||
mFileSystem->CloseProc(mFileSystem,p);
|
mFileSystem->CloseProc(mFileSystem,p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
char getOsSeparator() const {
|
char getOsSeparator() const {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return '/';
|
return '/';
|
||||||
#else
|
#else
|
||||||
return '\\';
|
return '\\';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
IOStream* Open(const char* pFile,const char* pMode = "rb") {
|
IOStream* Open(const char* pFile,const char* pMode = "rb") {
|
||||||
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
|
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return new CIOStreamWrapper(p);
|
return new CIOStreamWrapper(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
void Close( IOStream* pFile) {
|
void Close( IOStream* pFile) {
|
||||||
if (!pFile) {
|
if (!pFile) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
|
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
|
||||||
delete pFile;
|
delete pFile;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
aiFileIO* mFileSystem;
|
aiFileIO* mFileSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
1738
code/COBLoader.cpp
1738
code/COBLoader.cpp
File diff suppressed because it is too large
Load Diff
150
code/COBLoader.h
150
code/COBLoader.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -49,21 +49,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
class LineSplitter;
|
class LineSplitter;
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter {
|
namespace Formatter {
|
||||||
template <typename T,typename TR, typename A> class basic_formatter;
|
template <typename T,typename TR, typename A> class basic_formatter;
|
||||||
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
||||||
}
|
}
|
||||||
|
|
||||||
// COBScene.h
|
// COBScene.h
|
||||||
namespace COB {
|
namespace COB {
|
||||||
struct ChunkInfo;
|
struct ChunkInfo;
|
||||||
struct Node;
|
struct Node;
|
||||||
struct Scene;
|
struct Scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Importer class to load TrueSpace files (cob,scn) up to v6.
|
/** Importer class to load TrueSpace files (cob,scn) up to v6.
|
||||||
|
@ -73,99 +73,99 @@ namespace Assimp {
|
||||||
class COBImporter : public BaseImporter
|
class COBImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
COBImporter();
|
COBImporter();
|
||||||
~COBImporter();
|
~COBImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Prepend 'COB: ' and throw msg.*/
|
/** Prepend 'COB: ' and throw msg.*/
|
||||||
AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Read from an ascii scene/object file
|
/** @brief Read from an ascii scene/object file
|
||||||
* @param out Receives output data.
|
* @param out Receives output data.
|
||||||
* @param stream Stream to read from. */
|
* @param stream Stream to read from. */
|
||||||
void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
|
void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Read from a binary scene/object file
|
/** @brief Read from a binary scene/object file
|
||||||
* @param out Receives output data.
|
* @param out Receives output data.
|
||||||
* @param stream Stream to read from. */
|
* @param stream Stream to read from. */
|
||||||
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
|
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Conversion to Assimp output format
|
// Conversion to Assimp output format
|
||||||
|
|
||||||
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
|
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// ASCII file support
|
// ASCII file support
|
||||||
|
|
||||||
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
|
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
|
||||||
void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
|
void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
|
||||||
void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
|
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
|
||||||
|
|
||||||
void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
|
||||||
|
|
||||||
|
|
||||||
// ASCII file logging stuff to add proper line numbers to messages
|
// ASCII file logging stuff to add proper line numbers to messages
|
||||||
|
|
||||||
static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
|
static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
|
||||||
static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
|
static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
|
||||||
static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
|
static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
|
||||||
static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
|
static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
|
||||||
|
|
||||||
static void LogWarn_Ascii (const Formatter::format& message);
|
static void LogWarn_Ascii (const Formatter::format& message);
|
||||||
static void LogError_Ascii (const Formatter::format& message);
|
static void LogError_Ascii (const Formatter::format& message);
|
||||||
static void LogInfo_Ascii (const Formatter::format& message);
|
static void LogInfo_Ascii (const Formatter::format& message);
|
||||||
static void LogDebug_Ascii (const Formatter::format& message);
|
static void LogDebug_Ascii (const Formatter::format& message);
|
||||||
|
|
||||||
|
|
||||||
// Binary file support
|
// Binary file support
|
||||||
|
|
||||||
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
|
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
|
||||||
void ReadString_Binary(std::string& out, StreamReaderLE& reader);
|
void ReadString_Binary(std::string& out, StreamReaderLE& reader);
|
||||||
void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
|
|
||||||
void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
|
||||||
|
|
||||||
|
|
||||||
}; // !class COBImporter
|
}; // !class COBImporter
|
||||||
|
|
220
code/COBScene.h
220
code/COBScene.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -50,208 +50,208 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "./../include/assimp/material.h"
|
#include "./../include/assimp/material.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace COB {
|
namespace COB {
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** Represents a single vertex index in a face */
|
/** Represents a single vertex index in a face */
|
||||||
struct VertexIndex
|
struct VertexIndex
|
||||||
{
|
{
|
||||||
// intentionally uninitialized
|
// intentionally uninitialized
|
||||||
unsigned int pos_idx,uv_idx;
|
unsigned int pos_idx,uv_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Face data structure */
|
/** COB Face data structure */
|
||||||
struct Face
|
struct Face
|
||||||
{
|
{
|
||||||
// intentionally uninitialized
|
// intentionally uninitialized
|
||||||
unsigned int material, flags;
|
unsigned int material, flags;
|
||||||
std::vector<VertexIndex> indices;
|
std::vector<VertexIndex> indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB chunk header information */
|
/** COB chunk header information */
|
||||||
struct ChunkInfo
|
struct ChunkInfo
|
||||||
{
|
{
|
||||||
enum {NO_SIZE=UINT_MAX};
|
enum {NO_SIZE=UINT_MAX};
|
||||||
|
|
||||||
ChunkInfo ()
|
ChunkInfo ()
|
||||||
: id (0)
|
: id (0)
|
||||||
, parent_id (0)
|
, parent_id (0)
|
||||||
, version (0)
|
, version (0)
|
||||||
, size (NO_SIZE)
|
, size (NO_SIZE)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Id of this chunk, unique within file
|
// Id of this chunk, unique within file
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
// and the corresponding parent
|
// and the corresponding parent
|
||||||
unsigned int parent_id;
|
unsigned int parent_id;
|
||||||
|
|
||||||
// version. v1.23 becomes 123
|
// version. v1.23 becomes 123
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
|
|
||||||
// chunk size in bytes, only relevant for binary files
|
// chunk size in bytes, only relevant for binary files
|
||||||
// NO_SIZE is also valid.
|
// NO_SIZE is also valid.
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** A node in the scenegraph */
|
/** A node in the scenegraph */
|
||||||
struct Node : public ChunkInfo
|
struct Node : public ChunkInfo
|
||||||
{
|
{
|
||||||
enum Type {
|
enum Type {
|
||||||
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
|
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Node() {}
|
virtual ~Node() {}
|
||||||
Node(Type type) : type(type), unit_scale(1.f){}
|
Node(Type type) : type(type), unit_scale(1.f){}
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
// used during resolving
|
// used during resolving
|
||||||
typedef std::deque<const Node*> ChildList;
|
typedef std::deque<const Node*> ChildList;
|
||||||
mutable ChildList temp_children;
|
mutable ChildList temp_children;
|
||||||
|
|
||||||
// unique name
|
// unique name
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
// local mesh transformation
|
// local mesh transformation
|
||||||
aiMatrix4x4 transform;
|
aiMatrix4x4 transform;
|
||||||
|
|
||||||
// scaling for this node to get to the metric system
|
// scaling for this node to get to the metric system
|
||||||
float unit_scale;
|
float unit_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Mesh data structure */
|
/** COB Mesh data structure */
|
||||||
struct Mesh : public Node
|
struct Mesh : public Node
|
||||||
{
|
{
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
enum DrawFlags {
|
enum DrawFlags {
|
||||||
SOLID = 0x1,
|
SOLID = 0x1,
|
||||||
TRANS = 0x2,
|
TRANS = 0x2,
|
||||||
WIRED = 0x4,
|
WIRED = 0x4,
|
||||||
BBOX = 0x8,
|
BBOX = 0x8,
|
||||||
HIDE = 0x10
|
HIDE = 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
Mesh()
|
Mesh()
|
||||||
: Node(TYPE_MESH)
|
: Node(TYPE_MESH)
|
||||||
, draw_flags(SOLID)
|
, draw_flags(SOLID)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// vertex elements
|
// vertex elements
|
||||||
std::vector<aiVector2D> texture_coords;
|
std::vector<aiVector2D> texture_coords;
|
||||||
std::vector<aiVector3D> vertex_positions;
|
std::vector<aiVector3D> vertex_positions;
|
||||||
|
|
||||||
// face data
|
// face data
|
||||||
std::vector<Face> faces;
|
std::vector<Face> faces;
|
||||||
|
|
||||||
// misc. drawing flags
|
// misc. drawing flags
|
||||||
unsigned int draw_flags;
|
unsigned int draw_flags;
|
||||||
|
|
||||||
// used during resolving
|
// used during resolving
|
||||||
typedef std::deque<Face*> FaceRefList;
|
typedef std::deque<Face*> FaceRefList;
|
||||||
typedef std::map< unsigned int,FaceRefList > TempMap;
|
typedef std::map< unsigned int,FaceRefList > TempMap;
|
||||||
TempMap temp_map;
|
TempMap temp_map;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Group data structure */
|
/** COB Group data structure */
|
||||||
struct Group : public Node
|
struct Group : public Node
|
||||||
{
|
{
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Group() : Node(TYPE_GROUP) {}
|
Group() : Node(TYPE_GROUP) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Bone data structure */
|
/** COB Bone data structure */
|
||||||
struct Bone : public Node
|
struct Bone : public Node
|
||||||
{
|
{
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Bone() : Node(TYPE_BONE) {}
|
Bone() : Node(TYPE_BONE) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Light data structure */
|
/** COB Light data structure */
|
||||||
struct Light : public Node
|
struct Light : public Node
|
||||||
{
|
{
|
||||||
enum LightType {
|
enum LightType {
|
||||||
SPOT,LOCAL,INFINITE
|
SPOT,LOCAL,INFINITE
|
||||||
};
|
};
|
||||||
|
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
|
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
|
||||||
|
|
||||||
aiColor3D color;
|
aiColor3D color;
|
||||||
float angle,inner_angle;
|
float angle,inner_angle;
|
||||||
|
|
||||||
LightType ltype;
|
LightType ltype;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Camera data structure */
|
/** COB Camera data structure */
|
||||||
struct Camera : public Node
|
struct Camera : public Node
|
||||||
{
|
{
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
Camera() : Node(TYPE_CAMERA) {}
|
Camera() : Node(TYPE_CAMERA) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Texture data structure */
|
/** COB Texture data structure */
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
std::string path;
|
std::string path;
|
||||||
aiUVTransform transform;
|
aiUVTransform transform;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** COB Material data structure */
|
/** COB Material data structure */
|
||||||
struct Material : ChunkInfo
|
struct Material : ChunkInfo
|
||||||
{
|
{
|
||||||
using ChunkInfo::operator=;
|
using ChunkInfo::operator=;
|
||||||
enum Shader {
|
enum Shader {
|
||||||
FLAT,PHONG,METAL
|
FLAT,PHONG,METAL
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AutoFacet {
|
enum AutoFacet {
|
||||||
FACETED,AUTOFACETED,SMOOTH
|
FACETED,AUTOFACETED,SMOOTH
|
||||||
};
|
};
|
||||||
|
|
||||||
Material() : alpha(),exp(),ior(),ka(),ks(1.f),
|
Material() : alpha(),exp(),ior(),ka(),ks(1.f),
|
||||||
matnum(UINT_MAX),
|
matnum(UINT_MAX),
|
||||||
shader(FLAT),autofacet(FACETED),
|
shader(FLAT),autofacet(FACETED),
|
||||||
autofacet_angle()
|
autofacet_angle()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::string type;
|
std::string type;
|
||||||
|
|
||||||
aiColor3D rgb;
|
aiColor3D rgb;
|
||||||
float alpha, exp, ior,ka,ks;
|
float alpha, exp, ior,ka,ks;
|
||||||
|
|
||||||
unsigned int matnum;
|
unsigned int matnum;
|
||||||
Shader shader;
|
Shader shader;
|
||||||
|
|
||||||
AutoFacet autofacet;
|
AutoFacet autofacet;
|
||||||
float autofacet_angle;
|
float autofacet_angle;
|
||||||
|
|
||||||
boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
|
boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
/** Embedded bitmap, for instance for the thumbnail image */
|
/** Embedded bitmap, for instance for the thumbnail image */
|
||||||
struct Bitmap : ChunkInfo
|
struct Bitmap : ChunkInfo
|
||||||
{
|
{
|
||||||
Bitmap() : orig_size() {}
|
Bitmap() : orig_size() {}
|
||||||
struct BitmapHeader
|
struct BitmapHeader
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
BitmapHeader head;
|
BitmapHeader head;
|
||||||
size_t orig_size;
|
size_t orig_size;
|
||||||
std::vector<char> buff_zipped;
|
std::vector<char> buff_zipped;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::deque< boost::shared_ptr<Node> > NodeList;
|
typedef std::deque< boost::shared_ptr<Node> > NodeList;
|
||||||
|
@ -261,14 +261,14 @@ typedef std::vector< Material > MaterialList;
|
||||||
/** Represents a master COB scene, even if we loaded just a single COB file */
|
/** Represents a master COB scene, even if we loaded just a single COB file */
|
||||||
struct Scene
|
struct Scene
|
||||||
{
|
{
|
||||||
NodeList nodes;
|
NodeList nodes;
|
||||||
MaterialList materials;
|
MaterialList materials;
|
||||||
|
|
||||||
// becomes *0 later
|
// becomes *0 later
|
||||||
Bitmap thumbnail;
|
Bitmap thumbnail;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end COB
|
} // end COB
|
||||||
} // end Assimp
|
} // end Assimp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -62,16 +62,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"CharacterStudio Motion Importer (MoCap)",
|
"CharacterStudio Motion Importer (MoCap)",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
aiImporterFlags_SupportTextFlavour,
|
aiImporterFlags_SupportTextFlavour,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"csm"
|
"csm"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,217 +90,217 @@ CSMImporter::~CSMImporter()
|
||||||
// Returns whether the class can handle the format of the given file.
|
// Returns whether the class can handle the format of the given file.
|
||||||
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||||
{
|
{
|
||||||
// check file extension
|
// check file extension
|
||||||
const std::string extension = GetExtension(pFile);
|
const std::string extension = GetExtension(pFile);
|
||||||
|
|
||||||
if( extension == "csm")
|
if( extension == "csm")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ((checkSig || !extension.length()) && pIOHandler) {
|
if ((checkSig || !extension.length()) && pIOHandler) {
|
||||||
const char* tokens[] = {"$Filename"};
|
const char* tokens[] = {"$Filename"};
|
||||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Build a string of all file extensions supported
|
// Build a string of all file extensions supported
|
||||||
const aiImporterDesc* CSMImporter::GetInfo () const
|
const aiImporterDesc* CSMImporter::GetInfo () const
|
||||||
{
|
{
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup configuration properties for the loader
|
// Setup configuration properties for the loader
|
||||||
void CSMImporter::SetupProperties(const Importer* pImp)
|
void CSMImporter::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void CSMImporter::InternReadFile( const std::string& pFile,
|
void CSMImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file.get() == NULL) {
|
if( file.get() == NULL) {
|
||||||
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
|
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate storage and copy the contents of the file to a memory buffer
|
// allocate storage and copy the contents of the file to a memory buffer
|
||||||
std::vector<char> mBuffer2;
|
std::vector<char> mBuffer2;
|
||||||
TextFileToBuffer(file.get(),mBuffer2);
|
TextFileToBuffer(file.get(),mBuffer2);
|
||||||
const char* buffer = &mBuffer2[0];
|
const char* buffer = &mBuffer2[0];
|
||||||
|
|
||||||
aiAnimation* anim = new aiAnimation();
|
aiAnimation* anim = new aiAnimation();
|
||||||
int first = 0, last = 0x00ffffff;
|
int first = 0, last = 0x00ffffff;
|
||||||
|
|
||||||
// now process the file and look out for '$' sections
|
// now process the file and look out for '$' sections
|
||||||
while (1) {
|
while (1) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
if ('\0' == *buffer)
|
if ('\0' == *buffer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ('$' == *buffer) {
|
if ('$' == *buffer) {
|
||||||
++buffer;
|
++buffer;
|
||||||
if (TokenMatchI(buffer,"firstframe",10)) {
|
if (TokenMatchI(buffer,"firstframe",10)) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
first = strtol10(buffer,&buffer);
|
first = strtol10(buffer,&buffer);
|
||||||
}
|
}
|
||||||
else if (TokenMatchI(buffer,"lastframe",9)) {
|
else if (TokenMatchI(buffer,"lastframe",9)) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
last = strtol10(buffer,&buffer);
|
last = strtol10(buffer,&buffer);
|
||||||
}
|
}
|
||||||
else if (TokenMatchI(buffer,"rate",4)) {
|
else if (TokenMatchI(buffer,"rate",4)) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
float d;
|
float d;
|
||||||
buffer = fast_atoreal_move<float>(buffer,d);
|
buffer = fast_atoreal_move<float>(buffer,d);
|
||||||
anim->mTicksPerSecond = d;
|
anim->mTicksPerSecond = d;
|
||||||
}
|
}
|
||||||
else if (TokenMatchI(buffer,"order",5)) {
|
else if (TokenMatchI(buffer,"order",5)) {
|
||||||
std::vector< aiNodeAnim* > anims_temp;
|
std::vector< aiNodeAnim* > anims_temp;
|
||||||
anims_temp.reserve(30);
|
anims_temp.reserve(30);
|
||||||
while (1) {
|
while (1) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
|
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
|
||||||
break; // next section
|
break; // next section
|
||||||
|
|
||||||
// Construct a new node animation channel and setup its name
|
// Construct a new node animation channel and setup its name
|
||||||
anims_temp.push_back(new aiNodeAnim());
|
anims_temp.push_back(new aiNodeAnim());
|
||||||
aiNodeAnim* nda = anims_temp.back();
|
aiNodeAnim* nda = anims_temp.back();
|
||||||
|
|
||||||
char* ot = nda->mNodeName.data;
|
char* ot = nda->mNodeName.data;
|
||||||
while (!IsSpaceOrNewLine(*buffer))
|
while (!IsSpaceOrNewLine(*buffer))
|
||||||
*ot++ = *buffer++;
|
*ot++ = *buffer++;
|
||||||
|
|
||||||
*ot = '\0';
|
*ot = '\0';
|
||||||
nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
|
nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
anim->mNumChannels = anims_temp.size();
|
anim->mNumChannels = anims_temp.size();
|
||||||
if (!anim->mNumChannels)
|
if (!anim->mNumChannels)
|
||||||
throw DeadlyImportError("CSM: Empty $order section");
|
throw DeadlyImportError("CSM: Empty $order section");
|
||||||
|
|
||||||
// copy over to the output animation
|
// copy over to the output animation
|
||||||
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
||||||
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
|
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
|
||||||
}
|
}
|
||||||
else if (TokenMatchI(buffer,"points",6)) {
|
else if (TokenMatchI(buffer,"points",6)) {
|
||||||
if (!anim->mNumChannels)
|
if (!anim->mNumChannels)
|
||||||
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
|
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
|
||||||
|
|
||||||
// If we know how many frames we'll read, we can preallocate some storage
|
// If we know how many frames we'll read, we can preallocate some storage
|
||||||
unsigned int alloc = 100;
|
unsigned int alloc = 100;
|
||||||
if (last != 0x00ffffff)
|
if (last != 0x00ffffff)
|
||||||
{
|
{
|
||||||
alloc = last-first;
|
alloc = last-first;
|
||||||
alloc += alloc>>2u; // + 25%
|
alloc += alloc>>2u; // + 25%
|
||||||
for (unsigned int i = 0; i < anim->mNumChannels;++i)
|
for (unsigned int i = 0; i < anim->mNumChannels;++i)
|
||||||
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
|
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int filled = 0;
|
unsigned int filled = 0;
|
||||||
|
|
||||||
// Now read all point data.
|
// Now read all point data.
|
||||||
while (1) {
|
while (1) {
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
|
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
|
||||||
break; // next section
|
break; // next section
|
||||||
}
|
}
|
||||||
|
|
||||||
// read frame
|
// read frame
|
||||||
const int frame = ::strtoul10(buffer,&buffer);
|
const int frame = ::strtoul10(buffer,&buffer);
|
||||||
last = std::max(frame,last);
|
last = std::max(frame,last);
|
||||||
first = std::min(frame,last);
|
first = std::min(frame,last);
|
||||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||||
|
|
||||||
aiNodeAnim* s = anim->mChannels[i];
|
aiNodeAnim* s = anim->mChannels[i];
|
||||||
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
|
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
|
||||||
|
|
||||||
aiVectorKey* old = s->mPositionKeys;
|
aiVectorKey* old = s->mPositionKeys;
|
||||||
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
|
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
|
||||||
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
|
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
|
||||||
delete[] old;
|
delete[] old;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read x,y,z
|
// read x,y,z
|
||||||
if(!SkipSpacesAndLineEnd(&buffer))
|
if(!SkipSpacesAndLineEnd(&buffer))
|
||||||
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
|
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
|
||||||
|
|
||||||
if (TokenMatchI(buffer, "DROPOUT", 7)) {
|
if (TokenMatchI(buffer, "DROPOUT", 7)) {
|
||||||
// seems this is invalid marker data; at least the doc says it's possible
|
// seems this is invalid marker data; at least the doc says it's possible
|
||||||
DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
|
DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
|
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
|
||||||
sub->mTime = (double)frame;
|
sub->mTime = (double)frame;
|
||||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
|
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
|
||||||
|
|
||||||
if(!SkipSpacesAndLineEnd(&buffer))
|
if(!SkipSpacesAndLineEnd(&buffer))
|
||||||
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
|
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
|
||||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
|
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
|
||||||
|
|
||||||
if(!SkipSpacesAndLineEnd(&buffer))
|
if(!SkipSpacesAndLineEnd(&buffer))
|
||||||
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
|
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
|
||||||
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
|
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
|
||||||
|
|
||||||
++s->mNumPositionKeys;
|
++s->mNumPositionKeys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update allocation granularity
|
// update allocation granularity
|
||||||
if (filled == alloc)
|
if (filled == alloc)
|
||||||
alloc *= 2;
|
alloc *= 2;
|
||||||
|
|
||||||
++filled;
|
++filled;
|
||||||
}
|
}
|
||||||
// all channels must be complete in order to continue safely.
|
// all channels must be complete in order to continue safely.
|
||||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||||
|
|
||||||
if (!anim->mChannels[i]->mNumPositionKeys)
|
if (!anim->mChannels[i]->mNumPositionKeys)
|
||||||
throw DeadlyImportError("CSM: Invalid marker track");
|
throw DeadlyImportError("CSM: Invalid marker track");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// advance to the next line
|
// advance to the next line
|
||||||
SkipLine(&buffer);
|
SkipLine(&buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup a proper animation duration
|
// Setup a proper animation duration
|
||||||
anim->mDuration = last - std::min( first, 0 );
|
anim->mDuration = last - std::min( first, 0 );
|
||||||
|
|
||||||
// build a dummy root node with the tiny markers as children
|
// build a dummy root node with the tiny markers as children
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
pScene->mRootNode->mName.Set("$CSM_DummyRoot");
|
pScene->mRootNode->mName.Set("$CSM_DummyRoot");
|
||||||
|
|
||||||
pScene->mRootNode->mNumChildren = anim->mNumChannels;
|
pScene->mRootNode->mNumChildren = anim->mNumChannels;
|
||||||
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
|
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
for (unsigned int i = 0; i < anim->mNumChannels;++i) {
|
||||||
aiNodeAnim* na = anim->mChannels[i];
|
aiNodeAnim* na = anim->mChannels[i];
|
||||||
|
|
||||||
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
|
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
|
||||||
nd->mName = anim->mChannels[i]->mNodeName;
|
nd->mName = anim->mChannels[i]->mNodeName;
|
||||||
nd->mParent = pScene->mRootNode;
|
nd->mParent = pScene->mRootNode;
|
||||||
|
|
||||||
aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
|
aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the one and only animation in the scene
|
// Store the one and only animation in the scene
|
||||||
pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
|
pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
|
||||||
pScene->mAnimations[0] = anim;
|
pScene->mAnimations[0] = anim;
|
||||||
anim->mName.Set("$CSM_MasterAnim");
|
anim->mName.Set("$CSM_MasterAnim");
|
||||||
|
|
||||||
// mark the scene as incomplete and run SkeletonMeshBuilder on it
|
// mark the scene as incomplete and run SkeletonMeshBuilder on it
|
||||||
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
|
|
||||||
if (!noSkeletonMesh) {
|
if (!noSkeletonMesh) {
|
||||||
SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
|
SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Importer class to load MOCAPs in CharacterStudio Motion format.
|
/** Importer class to load MOCAPs in CharacterStudio Motion format.
|
||||||
|
@ -60,30 +60,30 @@ namespace Assimp {
|
||||||
class CSMImporter : public BaseImporter
|
class CSMImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSMImporter();
|
CSMImporter();
|
||||||
~CSMImporter();
|
~CSMImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
|
|
||||||
}; // end of class CSMImporter
|
}; // end of class CSMImporter
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -56,21 +56,21 @@ using namespace Assimp;
|
||||||
CalcTangentsProcess::CalcTangentsProcess()
|
CalcTangentsProcess::CalcTangentsProcess()
|
||||||
: configMaxAngle( AI_DEG_TO_RAD(45.f) )
|
: configMaxAngle( AI_DEG_TO_RAD(45.f) )
|
||||||
, configSourceUV( 0 ) {
|
, configSourceUV( 0 ) {
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
CalcTangentsProcess::~CalcTangentsProcess()
|
CalcTangentsProcess::~CalcTangentsProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
|
bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
return (pFlags & aiProcess_CalcTangentSpace) != 0;
|
return (pFlags & aiProcess_CalcTangentSpace) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -79,12 +79,12 @@ void CalcTangentsProcess::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
ai_assert( NULL != pImp );
|
ai_assert( NULL != pImp );
|
||||||
|
|
||||||
// get the current value of the property
|
// get the current value of the property
|
||||||
configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f);
|
configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE,45.f);
|
||||||
configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f);
|
configMaxAngle = std::max(std::min(configMaxAngle,45.0f),0.0f);
|
||||||
configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
|
configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
|
||||||
|
|
||||||
configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0);
|
configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -95,12 +95,12 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
|
||||||
|
|
||||||
DefaultLogger::get()->debug("CalcTangentsProcess begin");
|
DefaultLogger::get()->debug("CalcTangentsProcess begin");
|
||||||
|
|
||||||
bool bHas = false;
|
bool bHas = false;
|
||||||
for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) {
|
for ( unsigned int a = 0; a < pScene->mNumMeshes; a++ ) {
|
||||||
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
|
if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bHas ) {
|
if ( bHas ) {
|
||||||
DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated");
|
DefaultLogger::get()->info("CalcTangentsProcess finished. Tangents have been calculated");
|
||||||
} else {
|
} else {
|
||||||
DefaultLogger::get()->debug("CalcTangentsProcess finished");
|
DefaultLogger::get()->debug("CalcTangentsProcess finished");
|
||||||
|
@ -111,106 +111,106 @@ void CalcTangentsProcess::Execute( aiScene* pScene)
|
||||||
// Calculates tangents and bitangents for the given mesh
|
// Calculates tangents and bitangents for the given mesh
|
||||||
bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||||
{
|
{
|
||||||
// we assume that the mesh is still in the verbose vertex format where each face has its own set
|
// we assume that the mesh is still in the verbose vertex format where each face has its own set
|
||||||
// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
|
// of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
|
||||||
// assert() it here.
|
// assert() it here.
|
||||||
// assert( must be verbose, dammit);
|
// assert( must be verbose, dammit);
|
||||||
|
|
||||||
if (pMesh->mTangents) // this implies that mBitangents is also there
|
if (pMesh->mTangents) // this implies that mBitangents is also there
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If the mesh consists of lines and/or points but not of
|
// If the mesh consists of lines and/or points but not of
|
||||||
// triangles or higher-order polygons the normal vectors
|
// triangles or higher-order polygons the normal vectors
|
||||||
// are undefined.
|
// are undefined.
|
||||||
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
|
if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
|
DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
|
// what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
|
||||||
if( pMesh->mNormals == NULL)
|
if( pMesh->mNormals == NULL)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("Failed to compute tangents; need normals");
|
DefaultLogger::get()->error("Failed to compute tangents; need normals");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
|
if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
|
DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float angleEpsilon = 0.9999f;
|
const float angleEpsilon = 0.9999f;
|
||||||
|
|
||||||
std::vector<bool> vertexDone( pMesh->mNumVertices, false);
|
std::vector<bool> vertexDone( pMesh->mNumVertices, false);
|
||||||
const float qnan = get_qnan();
|
const float qnan = get_qnan();
|
||||||
|
|
||||||
// create space for the tangents and bitangents
|
// create space for the tangents and bitangents
|
||||||
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
|
||||||
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
|
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
|
||||||
|
|
||||||
const aiVector3D* meshPos = pMesh->mVertices;
|
const aiVector3D* meshPos = pMesh->mVertices;
|
||||||
const aiVector3D* meshNorm = pMesh->mNormals;
|
const aiVector3D* meshNorm = pMesh->mNormals;
|
||||||
const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV];
|
const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV];
|
||||||
aiVector3D* meshTang = pMesh->mTangents;
|
aiVector3D* meshTang = pMesh->mTangents;
|
||||||
aiVector3D* meshBitang = pMesh->mBitangents;
|
aiVector3D* meshBitang = pMesh->mBitangents;
|
||||||
|
|
||||||
// calculate the tangent and bitangent for every face
|
// calculate the tangent and bitangent for every face
|
||||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||||
{
|
{
|
||||||
const aiFace& face = pMesh->mFaces[a];
|
const aiFace& face = pMesh->mFaces[a];
|
||||||
if (face.mNumIndices < 3)
|
if (face.mNumIndices < 3)
|
||||||
{
|
{
|
||||||
// There are less than three indices, thus the tangent vector
|
// There are less than three indices, thus the tangent vector
|
||||||
// is not defined. We are finished with these vertices now,
|
// is not defined. We are finished with these vertices now,
|
||||||
// their tangent vectors are set to qnan.
|
// their tangent vectors are set to qnan.
|
||||||
for (unsigned int i = 0; i < face.mNumIndices;++i)
|
for (unsigned int i = 0; i < face.mNumIndices;++i)
|
||||||
{
|
{
|
||||||
unsigned int idx = face.mIndices[i];
|
unsigned int idx = face.mIndices[i];
|
||||||
vertexDone [idx] = true;
|
vertexDone [idx] = true;
|
||||||
meshTang [idx] = aiVector3D(qnan);
|
meshTang [idx] = aiVector3D(qnan);
|
||||||
meshBitang [idx] = aiVector3D(qnan);
|
meshBitang [idx] = aiVector3D(qnan);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// triangle or polygon... we always use only the first three indices. A polygon
|
// triangle or polygon... we always use only the first three indices. A polygon
|
||||||
// is supposed to be planar anyways....
|
// is supposed to be planar anyways....
|
||||||
// FIXME: (thom) create correct calculation for multi-vertex polygons maybe?
|
// FIXME: (thom) create correct calculation for multi-vertex polygons maybe?
|
||||||
const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
|
const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
|
||||||
|
|
||||||
// position differences p1->p2 and p1->p3
|
// position differences p1->p2 and p1->p3
|
||||||
aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
|
aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
|
||||||
|
|
||||||
// texture offset p1->p2 and p1->p3
|
// texture offset p1->p2 and p1->p3
|
||||||
float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
|
float sx = meshTex[p1].x - meshTex[p0].x, sy = meshTex[p1].y - meshTex[p0].y;
|
||||||
float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
|
float tx = meshTex[p2].x - meshTex[p0].x, ty = meshTex[p2].y - meshTex[p0].y;
|
||||||
float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
|
float dirCorrection = (tx * sy - ty * sx) < 0.0f ? -1.0f : 1.0f;
|
||||||
// when t1, t2, t3 in same position in UV space, just use default UV direction.
|
// when t1, t2, t3 in same position in UV space, just use default UV direction.
|
||||||
if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) {
|
if ( 0 == sx && 0 ==sy && 0 == tx && 0 == ty ) {
|
||||||
sx = 0.0; sy = 1.0;
|
sx = 0.0; sy = 1.0;
|
||||||
tx = 1.0; ty = 0.0;
|
tx = 1.0; ty = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// tangent points in the direction where to positive X axis of the texture coord's would point in model space
|
// tangent points in the direction where to positive X axis of the texture coord's would point in model space
|
||||||
// bitangent's points along the positive Y axis of the texture coord's, respectively
|
// bitangent's points along the positive Y axis of the texture coord's, respectively
|
||||||
aiVector3D tangent, bitangent;
|
aiVector3D tangent, bitangent;
|
||||||
tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
|
tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
|
||||||
tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
|
tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
|
||||||
tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
|
tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
|
||||||
bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
|
bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
|
||||||
bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
|
bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
|
||||||
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
|
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
|
||||||
|
|
||||||
// store for every vertex of that face
|
// store for every vertex of that face
|
||||||
for( unsigned int b = 0; b < face.mNumIndices; ++b ) {
|
for( unsigned int b = 0; b < face.mNumIndices; ++b ) {
|
||||||
unsigned int p = face.mIndices[b];
|
unsigned int p = face.mIndices[b];
|
||||||
|
|
||||||
// project tangent and bitangent into the plane formed by the vertex' normal
|
// project tangent and bitangent into the plane formed by the vertex' normal
|
||||||
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
|
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
|
||||||
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
|
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
|
||||||
localTangent.Normalize(); localBitangent.Normalize();
|
localTangent.Normalize(); localBitangent.Normalize();
|
||||||
|
|
||||||
// reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
|
// reconstruct tangent/bitangent according to normal and bitangent/tangent when it's infinite or NaN.
|
||||||
bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z);
|
bool invalid_tangent = is_special_float(localTangent.x) || is_special_float(localTangent.y) || is_special_float(localTangent.z);
|
||||||
|
@ -226,92 +226,92 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// and write it into the mesh.
|
// and write it into the mesh.
|
||||||
meshTang[ p ] = localTangent;
|
meshTang[ p ] = localTangent;
|
||||||
meshBitang[ p ] = localBitangent;
|
meshBitang[ p ] = localBitangent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// create a helper to quickly find locally close vertices among the vertex array
|
// create a helper to quickly find locally close vertices among the vertex array
|
||||||
// FIX: check whether we can reuse the SpatialSort of a previous step
|
// FIX: check whether we can reuse the SpatialSort of a previous step
|
||||||
SpatialSort* vertexFinder = NULL;
|
SpatialSort* vertexFinder = NULL;
|
||||||
SpatialSort _vertexFinder;
|
SpatialSort _vertexFinder;
|
||||||
float posEpsilon;
|
float posEpsilon;
|
||||||
if (shared)
|
if (shared)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<SpatialSort,float> >* avf;
|
std::vector<std::pair<SpatialSort,float> >* avf;
|
||||||
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
|
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
|
||||||
if (avf)
|
if (avf)
|
||||||
{
|
{
|
||||||
std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
|
std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
|
||||||
vertexFinder = &blubb.first;
|
vertexFinder = &blubb.first;
|
||||||
posEpsilon = blubb.second;;
|
posEpsilon = blubb.second;;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!vertexFinder)
|
if (!vertexFinder)
|
||||||
{
|
{
|
||||||
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
|
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
|
||||||
vertexFinder = &_vertexFinder;
|
vertexFinder = &_vertexFinder;
|
||||||
posEpsilon = ComputePositionEpsilon(pMesh);
|
posEpsilon = ComputePositionEpsilon(pMesh);
|
||||||
}
|
}
|
||||||
std::vector<unsigned int> verticesFound;
|
std::vector<unsigned int> verticesFound;
|
||||||
|
|
||||||
const float fLimit = cosf(configMaxAngle);
|
const float fLimit = cosf(configMaxAngle);
|
||||||
std::vector<unsigned int> closeVertices;
|
std::vector<unsigned int> closeVertices;
|
||||||
|
|
||||||
// in the second pass we now smooth out all tangents and bitangents at the same local position
|
// in the second pass we now smooth out all tangents and bitangents at the same local position
|
||||||
// if they are not too far off.
|
// if they are not too far off.
|
||||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
|
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
|
||||||
{
|
{
|
||||||
if( vertexDone[a])
|
if( vertexDone[a])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const aiVector3D& origPos = pMesh->mVertices[a];
|
const aiVector3D& origPos = pMesh->mVertices[a];
|
||||||
const aiVector3D& origNorm = pMesh->mNormals[a];
|
const aiVector3D& origNorm = pMesh->mNormals[a];
|
||||||
const aiVector3D& origTang = pMesh->mTangents[a];
|
const aiVector3D& origTang = pMesh->mTangents[a];
|
||||||
const aiVector3D& origBitang = pMesh->mBitangents[a];
|
const aiVector3D& origBitang = pMesh->mBitangents[a];
|
||||||
closeVertices.resize( 0 );
|
closeVertices.resize( 0 );
|
||||||
|
|
||||||
// find all vertices close to that position
|
// find all vertices close to that position
|
||||||
vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
|
vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
|
||||||
|
|
||||||
closeVertices.reserve (verticesFound.size()+5);
|
closeVertices.reserve (verticesFound.size()+5);
|
||||||
closeVertices.push_back( a);
|
closeVertices.push_back( a);
|
||||||
|
|
||||||
// look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
|
// look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
|
||||||
for( unsigned int b = 0; b < verticesFound.size(); b++)
|
for( unsigned int b = 0; b < verticesFound.size(); b++)
|
||||||
{
|
{
|
||||||
unsigned int idx = verticesFound[b];
|
unsigned int idx = verticesFound[b];
|
||||||
if( vertexDone[idx])
|
if( vertexDone[idx])
|
||||||
continue;
|
continue;
|
||||||
if( meshNorm[idx] * origNorm < angleEpsilon)
|
if( meshNorm[idx] * origNorm < angleEpsilon)
|
||||||
continue;
|
continue;
|
||||||
if( meshTang[idx] * origTang < fLimit)
|
if( meshTang[idx] * origTang < fLimit)
|
||||||
continue;
|
continue;
|
||||||
if( meshBitang[idx] * origBitang < fLimit)
|
if( meshBitang[idx] * origBitang < fLimit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// it's similar enough -> add it to the smoothing group
|
// it's similar enough -> add it to the smoothing group
|
||||||
closeVertices.push_back( idx);
|
closeVertices.push_back( idx);
|
||||||
vertexDone[idx] = true;
|
vertexDone[idx] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// smooth the tangents and bitangents of all vertices that were found to be close enough
|
// smooth the tangents and bitangents of all vertices that were found to be close enough
|
||||||
aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
|
aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
|
||||||
for( unsigned int b = 0; b < closeVertices.size(); ++b)
|
for( unsigned int b = 0; b < closeVertices.size(); ++b)
|
||||||
{
|
{
|
||||||
smoothTangent += meshTang[ closeVertices[b] ];
|
smoothTangent += meshTang[ closeVertices[b] ];
|
||||||
smoothBitangent += meshBitang[ closeVertices[b] ];
|
smoothBitangent += meshBitang[ closeVertices[b] ];
|
||||||
}
|
}
|
||||||
smoothTangent.Normalize();
|
smoothTangent.Normalize();
|
||||||
smoothBitangent.Normalize();
|
smoothBitangent.Normalize();
|
||||||
|
|
||||||
// and write it back into all affected tangents
|
// and write it back into all affected tangents
|
||||||
for( unsigned int b = 0; b < closeVertices.size(); ++b)
|
for( unsigned int b = 0; b < closeVertices.size(); ++b)
|
||||||
{
|
{
|
||||||
meshTang[ closeVertices[b] ] = smoothTangent;
|
meshTang[ closeVertices[b] ] = smoothTangent;
|
||||||
meshBitang[ closeVertices[b] ] = smoothBitangent;
|
meshBitang[ closeVertices[b] ] = smoothBitangent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -61,53 +61,53 @@ class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CalcTangentsProcess();
|
CalcTangentsProcess();
|
||||||
~CalcTangentsProcess();
|
~CalcTangentsProcess();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
* @param pFlags The processing flags the importer was called with.
|
* @param pFlags The processing flags the importer was called with.
|
||||||
* A bitwise combination of #aiPostProcessSteps.
|
* A bitwise combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
|
|
||||||
// setter for configMaxAngle
|
// setter for configMaxAngle
|
||||||
inline void SetMaxSmoothAngle(float f)
|
inline void SetMaxSmoothAngle(float f)
|
||||||
{
|
{
|
||||||
configMaxAngle =f;
|
configMaxAngle =f;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Calculates tangents and bitangents for a specific mesh.
|
/** Calculates tangents and bitangents for a specific mesh.
|
||||||
* @param pMesh The mesh to process.
|
* @param pMesh The mesh to process.
|
||||||
* @param meshIndex Index of the mesh
|
* @param meshIndex Index of the mesh
|
||||||
*/
|
*/
|
||||||
bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
|
bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** Configuration option: maximum smoothing angle, in radians*/
|
/** Configuration option: maximum smoothing angle, in radians*/
|
||||||
float configMaxAngle;
|
float configMaxAngle;
|
||||||
unsigned int configSourceUV;
|
unsigned int configSourceUV;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -65,88 +65,88 @@ namespace Assimp
|
||||||
class ColladaExporter
|
class ColladaExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Constructor for a specific scene to export
|
/// Constructor for a specific scene to export
|
||||||
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
|
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
virtual ~ColladaExporter();
|
virtual ~ColladaExporter();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Starts writing the contents
|
/// Starts writing the contents
|
||||||
void WriteFile();
|
void WriteFile();
|
||||||
|
|
||||||
/// Writes the asset header
|
/// Writes the asset header
|
||||||
void WriteHeader();
|
void WriteHeader();
|
||||||
|
|
||||||
/// Writes the embedded textures
|
/// Writes the embedded textures
|
||||||
void WriteTextures();
|
void WriteTextures();
|
||||||
|
|
||||||
/// Writes the material setup
|
/// Writes the material setup
|
||||||
void WriteMaterials();
|
void WriteMaterials();
|
||||||
|
|
||||||
/// Writes the cameras library
|
/// Writes the cameras library
|
||||||
void WriteCamerasLibrary();
|
void WriteCamerasLibrary();
|
||||||
|
|
||||||
// Write a camera entry
|
// Write a camera entry
|
||||||
void WriteCamera(size_t pIndex);
|
void WriteCamera(size_t pIndex);
|
||||||
|
|
||||||
/// Writes the cameras library
|
/// Writes the cameras library
|
||||||
void WriteLightsLibrary();
|
void WriteLightsLibrary();
|
||||||
|
|
||||||
// Write a camera entry
|
// Write a camera entry
|
||||||
void WriteLight(size_t pIndex);
|
void WriteLight(size_t pIndex);
|
||||||
void WritePointLight(const aiLight *const light);
|
void WritePointLight(const aiLight *const light);
|
||||||
void WriteDirectionalLight(const aiLight *const light);
|
void WriteDirectionalLight(const aiLight *const light);
|
||||||
void WriteSpotLight(const aiLight *const light);
|
void WriteSpotLight(const aiLight *const light);
|
||||||
void WriteAmbienttLight(const aiLight *const light);
|
void WriteAmbienttLight(const aiLight *const light);
|
||||||
|
|
||||||
/// Writes the geometry library
|
/// Writes the geometry library
|
||||||
void WriteGeometryLibrary();
|
void WriteGeometryLibrary();
|
||||||
|
|
||||||
/// Writes the given mesh
|
/// Writes the given mesh
|
||||||
void WriteGeometry( size_t pIndex);
|
void WriteGeometry( size_t pIndex);
|
||||||
|
|
||||||
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
|
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
|
||||||
|
|
||||||
/// Writes a float array of the given type
|
/// Writes a float array of the given type
|
||||||
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
|
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
|
||||||
|
|
||||||
/// Writes the scene library
|
/// Writes the scene library
|
||||||
void WriteSceneLibrary();
|
void WriteSceneLibrary();
|
||||||
|
|
||||||
/// Recursively writes the given node
|
/// Recursively writes the given node
|
||||||
void WriteNode( aiNode* pNode);
|
void WriteNode( aiNode* pNode);
|
||||||
|
|
||||||
/// Enters a new xml element, which increases the indentation
|
/// Enters a new xml element, which increases the indentation
|
||||||
void PushTag() { startstr.append( " "); }
|
void PushTag() { startstr.append( " "); }
|
||||||
/// Leaves an element, decreasing the indentation
|
/// Leaves an element, decreasing the indentation
|
||||||
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
|
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
|
||||||
|
|
||||||
/// Creates a mesh ID for the given mesh
|
/// Creates a mesh ID for the given mesh
|
||||||
std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); }
|
std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Stringstream to write all output into
|
/// Stringstream to write all output into
|
||||||
std::stringstream mOutput;
|
std::stringstream mOutput;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// The IOSystem for output
|
/// The IOSystem for output
|
||||||
IOSystem* mIOSystem;
|
IOSystem* mIOSystem;
|
||||||
|
|
||||||
/// Path of the directory where the scene will be exported
|
/// Path of the directory where the scene will be exported
|
||||||
const std::string mPath;
|
const std::string mPath;
|
||||||
|
|
||||||
/// Name of the file (without extension) where the scene will be exported
|
/// Name of the file (without extension) where the scene will be exported
|
||||||
const std::string mFile;
|
const std::string mFile;
|
||||||
|
|
||||||
/// The scene to be written
|
/// The scene to be written
|
||||||
const aiScene* mScene;
|
const aiScene* mScene;
|
||||||
bool mSceneOwned;
|
bool mSceneOwned;
|
||||||
|
|
||||||
/// current line start string, contains the current indentation for simple stream insertion
|
/// current line start string, contains the current indentation for simple stream insertion
|
||||||
std::string startstr;
|
std::string startstr;
|
||||||
/// current line end string for simple stream insertion
|
/// current line end string for simple stream insertion
|
||||||
std::string endstr;
|
std::string endstr;
|
||||||
|
|
||||||
// pair of color and texture - texture precedences color
|
// pair of color and texture - texture precedences color
|
||||||
struct Surface
|
struct Surface
|
||||||
|
@ -161,8 +161,8 @@ protected:
|
||||||
struct Property
|
struct Property
|
||||||
{
|
{
|
||||||
bool exist;
|
bool exist;
|
||||||
float value;
|
float value;
|
||||||
Property()
|
Property()
|
||||||
: exist(false)
|
: exist(false)
|
||||||
, value(0.0f)
|
, value(0.0f)
|
||||||
{}
|
{}
|
||||||
|
@ -174,7 +174,7 @@ protected:
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string shading_model;
|
std::string shading_model;
|
||||||
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
|
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
|
||||||
Property shininess, transparency, index_refraction;
|
Property shininess, transparency, index_refraction;
|
||||||
|
|
||||||
Material() {}
|
Material() {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -53,79 +53,79 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Collada {
|
namespace Collada {
|
||||||
|
|
||||||
/** Collada file versions which evolved during the years ... */
|
/** Collada file versions which evolved during the years ... */
|
||||||
enum FormatVersion
|
enum FormatVersion
|
||||||
{
|
{
|
||||||
FV_1_5_n,
|
FV_1_5_n,
|
||||||
FV_1_4_n,
|
FV_1_4_n,
|
||||||
FV_1_3_n
|
FV_1_3_n
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** Transformation types that can be applied to a node */
|
/** Transformation types that can be applied to a node */
|
||||||
enum TransformType
|
enum TransformType
|
||||||
{
|
{
|
||||||
TF_LOOKAT,
|
TF_LOOKAT,
|
||||||
TF_ROTATE,
|
TF_ROTATE,
|
||||||
TF_TRANSLATE,
|
TF_TRANSLATE,
|
||||||
TF_SCALE,
|
TF_SCALE,
|
||||||
TF_SKEW,
|
TF_SKEW,
|
||||||
TF_MATRIX
|
TF_MATRIX
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Different types of input data to a vertex or face */
|
/** Different types of input data to a vertex or face */
|
||||||
enum InputType
|
enum InputType
|
||||||
{
|
{
|
||||||
IT_Invalid,
|
IT_Invalid,
|
||||||
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
|
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
|
||||||
IT_Position,
|
IT_Position,
|
||||||
IT_Normal,
|
IT_Normal,
|
||||||
IT_Texcoord,
|
IT_Texcoord,
|
||||||
IT_Color,
|
IT_Color,
|
||||||
IT_Tangent,
|
IT_Tangent,
|
||||||
IT_Bitangent
|
IT_Bitangent
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Contains all data for one of the different transformation types */
|
/** Contains all data for one of the different transformation types */
|
||||||
struct Transform
|
struct Transform
|
||||||
{
|
{
|
||||||
std::string mID; ///< SID of the transform step, by which anim channels address their target node
|
std::string mID; ///< SID of the transform step, by which anim channels address their target node
|
||||||
TransformType mType;
|
TransformType mType;
|
||||||
float f[16]; ///< Interpretation of data depends on the type of the transformation
|
float f[16]; ///< Interpretation of data depends on the type of the transformation
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collada camera. */
|
/** A collada camera. */
|
||||||
struct Camera
|
struct Camera
|
||||||
{
|
{
|
||||||
Camera()
|
Camera()
|
||||||
: mOrtho (false)
|
: mOrtho (false)
|
||||||
, mHorFov (10e10f)
|
, mHorFov (10e10f)
|
||||||
, mVerFov (10e10f)
|
, mVerFov (10e10f)
|
||||||
, mAspect (10e10f)
|
, mAspect (10e10f)
|
||||||
, mZNear (0.1f)
|
, mZNear (0.1f)
|
||||||
, mZFar (1000.f)
|
, mZFar (1000.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Name of camera
|
// Name of camera
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
// True if it is an orthografic camera
|
// True if it is an orthografic camera
|
||||||
bool mOrtho;
|
bool mOrtho;
|
||||||
|
|
||||||
//! Horizontal field of view in degrees
|
//! Horizontal field of view in degrees
|
||||||
float mHorFov;
|
float mHorFov;
|
||||||
|
|
||||||
//! Vertical field of view in degrees
|
//! Vertical field of view in degrees
|
||||||
float mVerFov;
|
float mVerFov;
|
||||||
|
|
||||||
//! Screen aspect
|
//! Screen aspect
|
||||||
float mAspect;
|
float mAspect;
|
||||||
|
|
||||||
//! Near& far z
|
//! Near& far z
|
||||||
float mZNear, mZFar;
|
float mZNear, mZFar;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
|
#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
|
||||||
|
@ -133,70 +133,70 @@ struct Camera
|
||||||
/** A collada light source. */
|
/** A collada light source. */
|
||||||
struct Light
|
struct Light
|
||||||
{
|
{
|
||||||
Light()
|
Light()
|
||||||
: mType (aiLightSource_UNDEFINED)
|
: mType (aiLightSource_UNDEFINED)
|
||||||
, mAttConstant (1.f)
|
, mAttConstant (1.f)
|
||||||
, mAttLinear (0.f)
|
, mAttLinear (0.f)
|
||||||
, mAttQuadratic (0.f)
|
, mAttQuadratic (0.f)
|
||||||
, mFalloffAngle (180.f)
|
, mFalloffAngle (180.f)
|
||||||
, mFalloffExponent (0.f)
|
, mFalloffExponent (0.f)
|
||||||
, mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
, mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
||||||
, mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
, mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
|
||||||
, mIntensity (1.f)
|
, mIntensity (1.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//! Type of the light source aiLightSourceType + ambient
|
//! Type of the light source aiLightSourceType + ambient
|
||||||
unsigned int mType;
|
unsigned int mType;
|
||||||
|
|
||||||
//! Color of the light
|
//! Color of the light
|
||||||
aiColor3D mColor;
|
aiColor3D mColor;
|
||||||
|
|
||||||
//! Light attenuation
|
//! Light attenuation
|
||||||
float mAttConstant,mAttLinear,mAttQuadratic;
|
float mAttConstant,mAttLinear,mAttQuadratic;
|
||||||
|
|
||||||
//! Spot light falloff
|
//! Spot light falloff
|
||||||
float mFalloffAngle;
|
float mFalloffAngle;
|
||||||
float mFalloffExponent;
|
float mFalloffExponent;
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
// FCOLLADA extension from here
|
// FCOLLADA extension from here
|
||||||
|
|
||||||
//! ... related stuff from maja and max extensions
|
//! ... related stuff from maja and max extensions
|
||||||
float mPenumbraAngle;
|
float mPenumbraAngle;
|
||||||
float mOuterAngle;
|
float mOuterAngle;
|
||||||
|
|
||||||
//! Common light intensity
|
//! Common light intensity
|
||||||
float mIntensity;
|
float mIntensity;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Short vertex index description */
|
/** Short vertex index description */
|
||||||
struct InputSemanticMapEntry
|
struct InputSemanticMapEntry
|
||||||
{
|
{
|
||||||
InputSemanticMapEntry()
|
InputSemanticMapEntry()
|
||||||
: mSet(0)
|
: mSet(0)
|
||||||
, mType(IT_Invalid)
|
, mType(IT_Invalid)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//! Index of set, optional
|
//! Index of set, optional
|
||||||
unsigned int mSet;
|
unsigned int mSet;
|
||||||
|
|
||||||
//! Type of referenced vertex input
|
//! Type of referenced vertex input
|
||||||
InputType mType;
|
InputType mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Table to map from effect to vertex input semantics */
|
/** Table to map from effect to vertex input semantics */
|
||||||
struct SemanticMappingTable
|
struct SemanticMappingTable
|
||||||
{
|
{
|
||||||
//! Name of material
|
//! Name of material
|
||||||
std::string mMatName;
|
std::string mMatName;
|
||||||
|
|
||||||
//! List of semantic map commands, grouped by effect semantic name
|
//! List of semantic map commands, grouped by effect semantic name
|
||||||
std::map<std::string, InputSemanticMapEntry> mMap;
|
std::map<std::string, InputSemanticMapEntry> mMap;
|
||||||
|
|
||||||
//! For std::find
|
//! For std::find
|
||||||
bool operator == (const std::string& s) const {
|
bool operator == (const std::string& s) const {
|
||||||
return s == mMatName;
|
return s == mMatName;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
|
/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
|
||||||
|
@ -204,414 +204,414 @@ struct SemanticMappingTable
|
||||||
*/
|
*/
|
||||||
struct MeshInstance
|
struct MeshInstance
|
||||||
{
|
{
|
||||||
///< ID of the mesh or controller to be instanced
|
///< ID of the mesh or controller to be instanced
|
||||||
std::string mMeshOrController;
|
std::string mMeshOrController;
|
||||||
|
|
||||||
///< Map of materials by the subgroup ID they're applied to
|
///< Map of materials by the subgroup ID they're applied to
|
||||||
std::map<std::string, SemanticMappingTable> mMaterials;
|
std::map<std::string, SemanticMappingTable> mMaterials;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a camera inside a node*/
|
/** A reference to a camera inside a node*/
|
||||||
struct CameraInstance
|
struct CameraInstance
|
||||||
{
|
{
|
||||||
///< ID of the camera
|
///< ID of the camera
|
||||||
std::string mCamera;
|
std::string mCamera;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a light inside a node*/
|
/** A reference to a light inside a node*/
|
||||||
struct LightInstance
|
struct LightInstance
|
||||||
{
|
{
|
||||||
///< ID of the camera
|
///< ID of the camera
|
||||||
std::string mLight;
|
std::string mLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a node inside a node*/
|
/** A reference to a node inside a node*/
|
||||||
struct NodeInstance
|
struct NodeInstance
|
||||||
{
|
{
|
||||||
///< ID of the node
|
///< ID of the node
|
||||||
std::string mNode;
|
std::string mNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A node in a scene hierarchy */
|
/** A node in a scene hierarchy */
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
std::string mName;
|
std::string mName;
|
||||||
std::string mID;
|
std::string mID;
|
||||||
std::string mSID;
|
std::string mSID;
|
||||||
Node* mParent;
|
Node* mParent;
|
||||||
std::vector<Node*> mChildren;
|
std::vector<Node*> mChildren;
|
||||||
|
|
||||||
/** Operations in order to calculate the resulting transformation to parent. */
|
/** Operations in order to calculate the resulting transformation to parent. */
|
||||||
std::vector<Transform> mTransforms;
|
std::vector<Transform> mTransforms;
|
||||||
|
|
||||||
/** Meshes at this node */
|
/** Meshes at this node */
|
||||||
std::vector<MeshInstance> mMeshes;
|
std::vector<MeshInstance> mMeshes;
|
||||||
|
|
||||||
/** Lights at this node */
|
/** Lights at this node */
|
||||||
std::vector<LightInstance> mLights;
|
std::vector<LightInstance> mLights;
|
||||||
|
|
||||||
/** Cameras at this node */
|
/** Cameras at this node */
|
||||||
std::vector<CameraInstance> mCameras;
|
std::vector<CameraInstance> mCameras;
|
||||||
|
|
||||||
/** Node instances at this node */
|
/** Node instances at this node */
|
||||||
std::vector<NodeInstance> mNodeInstances;
|
std::vector<NodeInstance> mNodeInstances;
|
||||||
|
|
||||||
/** Rootnodes: Name of primary camera, if any */
|
/** Rootnodes: Name of primary camera, if any */
|
||||||
std::string mPrimaryCamera;
|
std::string mPrimaryCamera;
|
||||||
|
|
||||||
//! Constructor. Begin with a zero parent
|
//! Constructor. Begin with a zero parent
|
||||||
Node() {
|
Node() {
|
||||||
mParent = NULL;
|
mParent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Destructor: delete all children subsequently
|
//! Destructor: delete all children subsequently
|
||||||
~Node() {
|
~Node() {
|
||||||
for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
|
for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Data source array: either floats or strings */
|
/** Data source array: either floats or strings */
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
bool mIsStringArray;
|
bool mIsStringArray;
|
||||||
std::vector<float> mValues;
|
std::vector<float> mValues;
|
||||||
std::vector<std::string> mStrings;
|
std::vector<std::string> mStrings;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Accessor to a data array */
|
/** Accessor to a data array */
|
||||||
struct Accessor
|
struct Accessor
|
||||||
{
|
{
|
||||||
size_t mCount; // in number of objects
|
size_t mCount; // in number of objects
|
||||||
size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
|
size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
|
||||||
size_t mOffset; // in number of values
|
size_t mOffset; // in number of values
|
||||||
size_t mStride; // Stride in number of values
|
size_t mStride; // Stride in number of values
|
||||||
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
||||||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
|
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
|
||||||
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
||||||
std::string mSource; // URL of the source array
|
std::string mSource; // URL of the source array
|
||||||
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
|
||||||
|
|
||||||
Accessor()
|
Accessor()
|
||||||
{
|
{
|
||||||
mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL;
|
mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL;
|
||||||
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
|
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A single face in a mesh */
|
/** A single face in a mesh */
|
||||||
struct Face
|
struct Face
|
||||||
{
|
{
|
||||||
std::vector<size_t> mIndices;
|
std::vector<size_t> mIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An input channel for mesh data, referring to a single accessor */
|
/** An input channel for mesh data, referring to a single accessor */
|
||||||
struct InputChannel
|
struct InputChannel
|
||||||
{
|
{
|
||||||
InputType mType; // Type of the data
|
InputType mType; // Type of the data
|
||||||
size_t mIndex; // Optional index, if multiple sets of the same data type are given
|
size_t mIndex; // Optional index, if multiple sets of the same data type are given
|
||||||
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
|
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
|
||||||
std::string mAccessor; // ID of the accessor where to read the actual values from.
|
std::string mAccessor; // ID of the accessor where to read the actual values from.
|
||||||
mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
|
mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
|
||||||
|
|
||||||
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
|
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Subset of a mesh with a certain material */
|
/** Subset of a mesh with a certain material */
|
||||||
struct SubMesh
|
struct SubMesh
|
||||||
{
|
{
|
||||||
std::string mMaterial; ///< subgroup identifier
|
std::string mMaterial; ///< subgroup identifier
|
||||||
size_t mNumFaces; ///< number of faces in this submesh
|
size_t mNumFaces; ///< number of faces in this submesh
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Contains data for a single mesh */
|
/** Contains data for a single mesh */
|
||||||
struct Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
Mesh()
|
Mesh()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
|
||||||
mNumUVComponents[i] = 2;
|
mNumUVComponents[i] = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
// just to check if there's some sophisticated addressing involved...
|
// just to check if there's some sophisticated addressing involved...
|
||||||
// which we don't support, and therefore should warn about.
|
// which we don't support, and therefore should warn about.
|
||||||
std::string mVertexID;
|
std::string mVertexID;
|
||||||
|
|
||||||
// Vertex data addressed by vertex indices
|
// Vertex data addressed by vertex indices
|
||||||
std::vector<InputChannel> mPerVertexData;
|
std::vector<InputChannel> mPerVertexData;
|
||||||
|
|
||||||
// actual mesh data, assembled on encounter of a <p> element. Verbose format, not indexed
|
// actual mesh data, assembled on encounter of a <p> element. Verbose format, not indexed
|
||||||
std::vector<aiVector3D> mPositions;
|
std::vector<aiVector3D> mPositions;
|
||||||
std::vector<aiVector3D> mNormals;
|
std::vector<aiVector3D> mNormals;
|
||||||
std::vector<aiVector3D> mTangents;
|
std::vector<aiVector3D> mTangents;
|
||||||
std::vector<aiVector3D> mBitangents;
|
std::vector<aiVector3D> mBitangents;
|
||||||
std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||||
|
|
||||||
unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
|
|
||||||
// Faces. Stored are only the number of vertices for each face.
|
// Faces. Stored are only the number of vertices for each face.
|
||||||
// 1 == point, 2 == line, 3 == triangle, 4+ == poly
|
// 1 == point, 2 == line, 3 == triangle, 4+ == poly
|
||||||
std::vector<size_t> mFaceSize;
|
std::vector<size_t> mFaceSize;
|
||||||
|
|
||||||
// Position indices for all faces in the sequence given in mFaceSize -
|
// Position indices for all faces in the sequence given in mFaceSize -
|
||||||
// necessary for bone weight assignment
|
// necessary for bone weight assignment
|
||||||
std::vector<size_t> mFacePosIndices;
|
std::vector<size_t> mFacePosIndices;
|
||||||
|
|
||||||
// Submeshes in this mesh, each with a given material
|
// Submeshes in this mesh, each with a given material
|
||||||
std::vector<SubMesh> mSubMeshes;
|
std::vector<SubMesh> mSubMeshes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Which type of primitives the ReadPrimitives() function is going to read */
|
/** Which type of primitives the ReadPrimitives() function is going to read */
|
||||||
enum PrimitiveType
|
enum PrimitiveType
|
||||||
{
|
{
|
||||||
Prim_Invalid,
|
Prim_Invalid,
|
||||||
Prim_Lines,
|
Prim_Lines,
|
||||||
Prim_LineStrip,
|
Prim_LineStrip,
|
||||||
Prim_Triangles,
|
Prim_Triangles,
|
||||||
Prim_TriStrips,
|
Prim_TriStrips,
|
||||||
Prim_TriFans,
|
Prim_TriFans,
|
||||||
Prim_Polylist,
|
Prim_Polylist,
|
||||||
Prim_Polygon
|
Prim_Polygon
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A skeleton controller to deform a mesh with the use of joints */
|
/** A skeleton controller to deform a mesh with the use of joints */
|
||||||
struct Controller
|
struct Controller
|
||||||
{
|
{
|
||||||
// the URL of the mesh deformed by the controller.
|
// the URL of the mesh deformed by the controller.
|
||||||
std::string mMeshId;
|
std::string mMeshId;
|
||||||
|
|
||||||
// accessor URL of the joint names
|
// accessor URL of the joint names
|
||||||
std::string mJointNameSource;
|
std::string mJointNameSource;
|
||||||
|
|
||||||
///< The bind shape matrix, as array of floats. I'm not sure what this matrix actually describes, but it can't be ignored in all cases
|
///< The bind shape matrix, as array of floats. I'm not sure what this matrix actually describes, but it can't be ignored in all cases
|
||||||
float mBindShapeMatrix[16];
|
float mBindShapeMatrix[16];
|
||||||
|
|
||||||
// accessor URL of the joint inverse bind matrices
|
// accessor URL of the joint inverse bind matrices
|
||||||
std::string mJointOffsetMatrixSource;
|
std::string mJointOffsetMatrixSource;
|
||||||
|
|
||||||
// input channel: joint names.
|
// input channel: joint names.
|
||||||
InputChannel mWeightInputJoints;
|
InputChannel mWeightInputJoints;
|
||||||
// input channel: joint weights
|
// input channel: joint weights
|
||||||
InputChannel mWeightInputWeights;
|
InputChannel mWeightInputWeights;
|
||||||
|
|
||||||
// Number of weights per vertex.
|
// Number of weights per vertex.
|
||||||
std::vector<size_t> mWeightCounts;
|
std::vector<size_t> mWeightCounts;
|
||||||
|
|
||||||
// JointIndex-WeightIndex pairs for all vertices
|
// JointIndex-WeightIndex pairs for all vertices
|
||||||
std::vector< std::pair<size_t, size_t> > mWeights;
|
std::vector< std::pair<size_t, size_t> > mWeights;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collada material. Pretty much the only member is a reference to an effect. */
|
/** A collada material. Pretty much the only member is a reference to an effect. */
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
std::string mName;
|
std::string mName;
|
||||||
std::string mEffect;
|
std::string mEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Type of the effect param */
|
/** Type of the effect param */
|
||||||
enum ParamType
|
enum ParamType
|
||||||
{
|
{
|
||||||
Param_Sampler,
|
Param_Sampler,
|
||||||
Param_Surface
|
Param_Surface
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
|
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
|
||||||
struct EffectParam
|
struct EffectParam
|
||||||
{
|
{
|
||||||
ParamType mType;
|
ParamType mType;
|
||||||
std::string mReference; // to which other thing the param is referring to.
|
std::string mReference; // to which other thing the param is referring to.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shading type supported by the standard effect spec of Collada */
|
/** Shading type supported by the standard effect spec of Collada */
|
||||||
enum ShadeType
|
enum ShadeType
|
||||||
{
|
{
|
||||||
Shade_Invalid,
|
Shade_Invalid,
|
||||||
Shade_Constant,
|
Shade_Constant,
|
||||||
Shade_Lambert,
|
Shade_Lambert,
|
||||||
Shade_Phong,
|
Shade_Phong,
|
||||||
Shade_Blinn
|
Shade_Blinn
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Represents a texture sampler in collada */
|
/** Represents a texture sampler in collada */
|
||||||
struct Sampler
|
struct Sampler
|
||||||
{
|
{
|
||||||
Sampler()
|
Sampler()
|
||||||
: mWrapU (true)
|
: mWrapU (true)
|
||||||
, mWrapV (true)
|
, mWrapV (true)
|
||||||
, mMirrorU ()
|
, mMirrorU ()
|
||||||
, mMirrorV ()
|
, mMirrorV ()
|
||||||
, mOp (aiTextureOp_Multiply)
|
, mOp (aiTextureOp_Multiply)
|
||||||
, mUVId (UINT_MAX)
|
, mUVId (UINT_MAX)
|
||||||
, mWeighting (1.f)
|
, mWeighting (1.f)
|
||||||
, mMixWithPrevious (1.f)
|
, mMixWithPrevious (1.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** Name of image reference
|
/** Name of image reference
|
||||||
*/
|
*/
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
/** Wrap U?
|
/** Wrap U?
|
||||||
*/
|
*/
|
||||||
bool mWrapU;
|
bool mWrapU;
|
||||||
|
|
||||||
/** Wrap V?
|
/** Wrap V?
|
||||||
*/
|
*/
|
||||||
bool mWrapV;
|
bool mWrapV;
|
||||||
|
|
||||||
/** Mirror U?
|
/** Mirror U?
|
||||||
*/
|
*/
|
||||||
bool mMirrorU;
|
bool mMirrorU;
|
||||||
|
|
||||||
/** Mirror V?
|
/** Mirror V?
|
||||||
*/
|
*/
|
||||||
bool mMirrorV;
|
bool mMirrorV;
|
||||||
|
|
||||||
/** Blend mode
|
/** Blend mode
|
||||||
*/
|
*/
|
||||||
aiTextureOp mOp;
|
aiTextureOp mOp;
|
||||||
|
|
||||||
/** UV transformation
|
/** UV transformation
|
||||||
*/
|
*/
|
||||||
aiUVTransform mTransform;
|
aiUVTransform mTransform;
|
||||||
|
|
||||||
/** Name of source UV channel
|
/** Name of source UV channel
|
||||||
*/
|
*/
|
||||||
std::string mUVChannel;
|
std::string mUVChannel;
|
||||||
|
|
||||||
/** Resolved UV channel index or UINT_MAX if not known
|
/** Resolved UV channel index or UINT_MAX if not known
|
||||||
*/
|
*/
|
||||||
unsigned int mUVId;
|
unsigned int mUVId;
|
||||||
|
|
||||||
// OKINO/MAX3D extensions from here
|
// OKINO/MAX3D extensions from here
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
||||||
/** Weighting factor
|
/** Weighting factor
|
||||||
*/
|
*/
|
||||||
float mWeighting;
|
float mWeighting;
|
||||||
|
|
||||||
/** Mixing factor from OKINO
|
/** Mixing factor from OKINO
|
||||||
*/
|
*/
|
||||||
float mMixWithPrevious;
|
float mMixWithPrevious;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collada effect. Can contain about anything according to the Collada spec,
|
/** A collada effect. Can contain about anything according to the Collada spec,
|
||||||
but we limit our version to a reasonable subset. */
|
but we limit our version to a reasonable subset. */
|
||||||
struct Effect
|
struct Effect
|
||||||
{
|
{
|
||||||
// Shading mode
|
// Shading mode
|
||||||
ShadeType mShadeType;
|
ShadeType mShadeType;
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
|
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
|
||||||
mTransparent, mReflective;
|
mTransparent, mReflective;
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
|
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
|
||||||
mTexTransparent, mTexBump, mTexReflective;
|
mTexTransparent, mTexBump, mTexReflective;
|
||||||
|
|
||||||
// Scalar factory
|
// Scalar factory
|
||||||
float mShininess, mRefractIndex, mReflectivity;
|
float mShininess, mRefractIndex, mReflectivity;
|
||||||
float mTransparency;
|
float mTransparency;
|
||||||
bool mHasTransparency;
|
bool mHasTransparency;
|
||||||
bool mRGBTransparency;
|
bool mRGBTransparency;
|
||||||
|
|
||||||
// local params referring to each other by their SID
|
// local params referring to each other by their SID
|
||||||
typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
|
typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
|
||||||
ParamLibrary mParams;
|
ParamLibrary mParams;
|
||||||
|
|
||||||
// MAX3D extensions
|
// MAX3D extensions
|
||||||
// ---------------------------------------------------------
|
// ---------------------------------------------------------
|
||||||
// Double-sided?
|
// Double-sided?
|
||||||
bool mDoubleSided, mWireframe, mFaceted;
|
bool mDoubleSided, mWireframe, mFaceted;
|
||||||
|
|
||||||
Effect()
|
Effect()
|
||||||
: mShadeType (Shade_Phong)
|
: mShadeType (Shade_Phong)
|
||||||
, mEmissive ( 0, 0, 0, 1)
|
, mEmissive ( 0, 0, 0, 1)
|
||||||
, mAmbient ( 0.1f, 0.1f, 0.1f, 1)
|
, mAmbient ( 0.1f, 0.1f, 0.1f, 1)
|
||||||
, mDiffuse ( 0.6f, 0.6f, 0.6f, 1)
|
, mDiffuse ( 0.6f, 0.6f, 0.6f, 1)
|
||||||
, mSpecular ( 0.4f, 0.4f, 0.4f, 1)
|
, mSpecular ( 0.4f, 0.4f, 0.4f, 1)
|
||||||
, mTransparent ( 0, 0, 0, 1)
|
, mTransparent ( 0, 0, 0, 1)
|
||||||
, mShininess (10.0f)
|
, mShininess (10.0f)
|
||||||
, mRefractIndex (1.f)
|
, mRefractIndex (1.f)
|
||||||
, mReflectivity (1.f)
|
, mReflectivity (1.f)
|
||||||
, mTransparency (1.f)
|
, mTransparency (1.f)
|
||||||
, mHasTransparency (false)
|
, mHasTransparency (false)
|
||||||
, mRGBTransparency(false)
|
, mRGBTransparency(false)
|
||||||
, mDoubleSided (false)
|
, mDoubleSided (false)
|
||||||
, mWireframe (false)
|
, mWireframe (false)
|
||||||
, mFaceted (false)
|
, mFaceted (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An image, meaning texture */
|
/** An image, meaning texture */
|
||||||
struct Image
|
struct Image
|
||||||
{
|
{
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** If image file name is zero, embedded image data
|
/** If image file name is zero, embedded image data
|
||||||
*/
|
*/
|
||||||
std::vector<uint8_t> mImageData;
|
std::vector<uint8_t> mImageData;
|
||||||
|
|
||||||
/** If image file name is zero, file format of
|
/** If image file name is zero, file format of
|
||||||
* embedded image data.
|
* embedded image data.
|
||||||
*/
|
*/
|
||||||
std::string mEmbeddedFormat;
|
std::string mEmbeddedFormat;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An animation channel. */
|
/** An animation channel. */
|
||||||
struct AnimationChannel
|
struct AnimationChannel
|
||||||
{
|
{
|
||||||
/** URL of the data to animate. Could be about anything, but we support only the
|
/** URL of the data to animate. Could be about anything, but we support only the
|
||||||
* "NodeID/TransformID.SubElement" notation
|
* "NodeID/TransformID.SubElement" notation
|
||||||
*/
|
*/
|
||||||
std::string mTarget;
|
std::string mTarget;
|
||||||
|
|
||||||
/** Source URL of the time values. Collada calls them "input". Meh. */
|
/** Source URL of the time values. Collada calls them "input". Meh. */
|
||||||
std::string mSourceTimes;
|
std::string mSourceTimes;
|
||||||
/** Source URL of the value values. Collada calls them "output". */
|
/** Source URL of the value values. Collada calls them "output". */
|
||||||
std::string mSourceValues;
|
std::string mSourceValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An animation. Container for 0-x animation channels or 0-x animations */
|
/** An animation. Container for 0-x animation channels or 0-x animations */
|
||||||
struct Animation
|
struct Animation
|
||||||
{
|
{
|
||||||
/** Anim name */
|
/** Anim name */
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
/** the animation channels, if any */
|
/** the animation channels, if any */
|
||||||
std::vector<AnimationChannel> mChannels;
|
std::vector<AnimationChannel> mChannels;
|
||||||
|
|
||||||
/** the sub-animations, if any */
|
/** the sub-animations, if any */
|
||||||
std::vector<Animation*> mSubAnims;
|
std::vector<Animation*> mSubAnims;
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~Animation()
|
~Animation()
|
||||||
{
|
{
|
||||||
for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
|
for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Description of a collada animation channel which has been determined to affect the current node */
|
/** Description of a collada animation channel which has been determined to affect the current node */
|
||||||
struct ChannelEntry
|
struct ChannelEntry
|
||||||
{
|
{
|
||||||
const Collada::AnimationChannel* mChannel; ///> the source channel
|
const Collada::AnimationChannel* mChannel; ///> the source channel
|
||||||
std::string mTransformId; // the ID of the transformation step of the node which is influenced
|
std::string mTransformId; // the ID of the transformation step of the node which is influenced
|
||||||
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
|
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
|
||||||
size_t mSubElement; // starting index inside the transform data
|
size_t mSubElement; // starting index inside the transform data
|
||||||
|
|
||||||
// resolved data references
|
// resolved data references
|
||||||
const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values
|
const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values
|
||||||
const Collada::Data* mTimeData; ///> Source data array for the time values
|
const Collada::Data* mTimeData; ///> Source data array for the time values
|
||||||
const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values
|
const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values
|
||||||
const Collada::Data* mValueData; ///> Source datat array for the key value values
|
const Collada::Data* mValueData; ///> Source datat array for the key value values
|
||||||
|
|
||||||
ChannelEntry()
|
ChannelEntry()
|
||||||
: mChannel()
|
: mChannel()
|
||||||
, mTransformIndex()
|
, mTransformIndex()
|
||||||
, mSubElement()
|
, mSubElement()
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -57,26 +57,26 @@ namespace Assimp
|
||||||
|
|
||||||
struct ColladaMeshIndex
|
struct ColladaMeshIndex
|
||||||
{
|
{
|
||||||
std::string mMeshID;
|
std::string mMeshID;
|
||||||
size_t mSubMesh;
|
size_t mSubMesh;
|
||||||
std::string mMaterial;
|
std::string mMaterial;
|
||||||
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
|
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
|
||||||
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
|
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool operator < (const ColladaMeshIndex& p) const
|
bool operator < (const ColladaMeshIndex& p) const
|
||||||
{
|
{
|
||||||
if( mMeshID == p.mMeshID)
|
if( mMeshID == p.mMeshID)
|
||||||
{
|
{
|
||||||
if( mSubMesh == p.mSubMesh)
|
if( mSubMesh == p.mSubMesh)
|
||||||
return mMaterial < p.mMaterial;
|
return mMaterial < p.mMaterial;
|
||||||
else
|
else
|
||||||
return mSubMesh < p.mSubMesh;
|
return mSubMesh < p.mSubMesh;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
return mMeshID < p.mMeshID;
|
return mMeshID < p.mMeshID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
|
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
|
||||||
|
@ -85,166 +85,166 @@ struct ColladaMeshIndex
|
||||||
class ColladaLoader : public BaseImporter
|
class ColladaLoader : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ColladaLoader();
|
ColladaLoader();
|
||||||
~ColladaLoader();
|
~ColladaLoader();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details. */
|
* See BaseImporter::CanRead() for details. */
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
*/
|
*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details
|
* See BaseImporter::InternReadFile() for details
|
||||||
*/
|
*/
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
|
||||||
/** Recursively constructs a scene node for the given parser node and returns it. */
|
/** Recursively constructs a scene node for the given parser node and returns it. */
|
||||||
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
|
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
|
||||||
|
|
||||||
/** Resolve node instances */
|
/** Resolve node instances */
|
||||||
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
|
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
|
||||||
std::vector<const Collada::Node*>& resolved);
|
std::vector<const Collada::Node*>& resolved);
|
||||||
|
|
||||||
/** Builds meshes for the given node and references them */
|
/** Builds meshes for the given node and references them */
|
||||||
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
||||||
aiNode* pTarget);
|
aiNode* pTarget);
|
||||||
|
|
||||||
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
|
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
|
||||||
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
|
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
|
||||||
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
|
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
|
||||||
|
|
||||||
/** Builds cameras for the given node and references them */
|
/** Builds cameras for the given node and references them */
|
||||||
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
||||||
aiNode* pTarget);
|
aiNode* pTarget);
|
||||||
|
|
||||||
/** Builds lights for the given node and references them */
|
/** Builds lights for the given node and references them */
|
||||||
void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
|
||||||
aiNode* pTarget);
|
aiNode* pTarget);
|
||||||
|
|
||||||
/** Stores all meshes in the given scene */
|
/** Stores all meshes in the given scene */
|
||||||
void StoreSceneMeshes( aiScene* pScene);
|
void StoreSceneMeshes( aiScene* pScene);
|
||||||
|
|
||||||
/** Stores all materials in the given scene */
|
/** Stores all materials in the given scene */
|
||||||
void StoreSceneMaterials( aiScene* pScene);
|
void StoreSceneMaterials( aiScene* pScene);
|
||||||
|
|
||||||
/** Stores all lights in the given scene */
|
/** Stores all lights in the given scene */
|
||||||
void StoreSceneLights( aiScene* pScene);
|
void StoreSceneLights( aiScene* pScene);
|
||||||
|
|
||||||
/** Stores all cameras in the given scene */
|
/** Stores all cameras in the given scene */
|
||||||
void StoreSceneCameras( aiScene* pScene);
|
void StoreSceneCameras( aiScene* pScene);
|
||||||
|
|
||||||
/** Stores all textures in the given scene */
|
/** Stores all textures in the given scene */
|
||||||
void StoreSceneTextures( aiScene* pScene);
|
void StoreSceneTextures( aiScene* pScene);
|
||||||
|
|
||||||
/** Stores all animations
|
/** Stores all animations
|
||||||
* @param pScene target scene to store the anims
|
* @param pScene target scene to store the anims
|
||||||
*/
|
*/
|
||||||
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
|
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
|
||||||
|
|
||||||
/** Stores all animations for the given source anim and its nested child animations
|
/** Stores all animations for the given source anim and its nested child animations
|
||||||
* @param pScene target scene to store the anims
|
* @param pScene target scene to store the anims
|
||||||
* @param pSrcAnim the source animation to process
|
* @param pSrcAnim the source animation to process
|
||||||
* @param pPrefix Prefix to the name in case of nested animations
|
* @param pPrefix Prefix to the name in case of nested animations
|
||||||
*/
|
*/
|
||||||
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
|
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
|
||||||
|
|
||||||
/** Constructs the animation for the given source anim */
|
/** Constructs the animation for the given source anim */
|
||||||
void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
|
void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
|
||||||
|
|
||||||
/** Constructs materials from the collada material definitions */
|
/** Constructs materials from the collada material definitions */
|
||||||
void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
|
void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
|
||||||
|
|
||||||
/** Fill materials from the collada material definitions */
|
/** Fill materials from the collada material definitions */
|
||||||
void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
|
void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
|
||||||
|
|
||||||
/** Resolve UV channel mappings*/
|
/** Resolve UV channel mappings*/
|
||||||
void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
|
void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
|
||||||
const Collada::SemanticMappingTable& table);
|
const Collada::SemanticMappingTable& table);
|
||||||
|
|
||||||
/** Add a texture and all of its sampling properties to a material*/
|
/** Add a texture and all of its sampling properties to a material*/
|
||||||
void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
|
void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
|
||||||
const Collada::Effect& effect,
|
const Collada::Effect& effect,
|
||||||
const Collada::Sampler& sampler,
|
const Collada::Sampler& sampler,
|
||||||
aiTextureType type, unsigned int idx = 0);
|
aiTextureType type, unsigned int idx = 0);
|
||||||
|
|
||||||
/** Resolves the texture name for the given effect texture entry */
|
/** Resolves the texture name for the given effect texture entry */
|
||||||
aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
|
aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
|
||||||
const Collada::Effect& pEffect, const std::string& pName);
|
const Collada::Effect& pEffect, const std::string& pName);
|
||||||
|
|
||||||
/** Converts a path read from a collada file to the usual representation */
|
/** Converts a path read from a collada file to the usual representation */
|
||||||
void ConvertPath( aiString& ss);
|
void ConvertPath( aiString& ss);
|
||||||
|
|
||||||
/** Reads a float value from an accessor and its data array.
|
/** Reads a float value from an accessor and its data array.
|
||||||
* @param pAccessor The accessor to use for reading
|
* @param pAccessor The accessor to use for reading
|
||||||
* @param pData The data array to read from
|
* @param pData The data array to read from
|
||||||
* @param pIndex The index of the element to retrieve
|
* @param pIndex The index of the element to retrieve
|
||||||
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices
|
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices
|
||||||
* @return the specified value
|
* @return the specified value
|
||||||
*/
|
*/
|
||||||
float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
|
float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
|
||||||
|
|
||||||
/** Reads a string value from an accessor and its data array.
|
/** Reads a string value from an accessor and its data array.
|
||||||
* @param pAccessor The accessor to use for reading
|
* @param pAccessor The accessor to use for reading
|
||||||
* @param pData The data array to read from
|
* @param pData The data array to read from
|
||||||
* @param pIndex The index of the element to retrieve
|
* @param pIndex The index of the element to retrieve
|
||||||
* @return the specified value
|
* @return the specified value
|
||||||
*/
|
*/
|
||||||
const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
|
const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
|
||||||
|
|
||||||
/** Recursively collects all nodes into the given array */
|
/** Recursively collects all nodes into the given array */
|
||||||
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
|
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
|
||||||
|
|
||||||
/** Finds a node in the collada scene by the given name */
|
/** Finds a node in the collada scene by the given name */
|
||||||
const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
|
const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
|
||||||
/** Finds a node in the collada scene by the given SID */
|
/** Finds a node in the collada scene by the given SID */
|
||||||
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
|
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
|
||||||
|
|
||||||
/** Finds a proper name for a node derived from the collada-node's properties */
|
/** Finds a proper name for a node derived from the collada-node's properties */
|
||||||
std::string FindNameForNode( const Collada::Node* pNode);
|
std::string FindNameForNode( const Collada::Node* pNode);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Filename, for a verbose error message */
|
/** Filename, for a verbose error message */
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** Which mesh-material compound was stored under which mesh ID */
|
/** Which mesh-material compound was stored under which mesh ID */
|
||||||
std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
|
std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
|
||||||
|
|
||||||
/** Which material was stored under which index in the scene */
|
/** Which material was stored under which index in the scene */
|
||||||
std::map<std::string, size_t> mMaterialIndexByName;
|
std::map<std::string, size_t> mMaterialIndexByName;
|
||||||
|
|
||||||
/** Accumulated meshes for the target scene */
|
/** Accumulated meshes for the target scene */
|
||||||
std::vector<aiMesh*> mMeshes;
|
std::vector<aiMesh*> mMeshes;
|
||||||
|
|
||||||
/** Temporary material list */
|
/** Temporary material list */
|
||||||
std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
|
std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
|
||||||
|
|
||||||
/** Temporary camera list */
|
/** Temporary camera list */
|
||||||
std::vector<aiCamera*> mCameras;
|
std::vector<aiCamera*> mCameras;
|
||||||
|
|
||||||
/** Temporary light list */
|
/** Temporary light list */
|
||||||
std::vector<aiLight*> mLights;
|
std::vector<aiLight*> mLights;
|
||||||
|
|
||||||
/** Temporary texture list */
|
/** Temporary texture list */
|
||||||
std::vector<aiTexture*> mTextures;
|
std::vector<aiTexture*> mTextures;
|
||||||
|
|
||||||
/** Accumulated animations for the target scene */
|
/** Accumulated animations for the target scene */
|
||||||
std::vector<aiAnimation*> mAnims;
|
std::vector<aiAnimation*> mAnims;
|
||||||
|
|
||||||
bool noSkeletonMesh;
|
bool noSkeletonMesh;
|
||||||
bool ignoreUpDirection;
|
bool ignoreUpDirection;
|
||||||
bool invertTransparency;
|
bool invertTransparency;
|
||||||
|
|
||||||
/** Used by FindNameForNode() to generate unique node names */
|
/** Used by FindNameForNode() to generate unique node names */
|
||||||
unsigned int mNodeNameCounter;
|
unsigned int mNodeNameCounter;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -61,279 +61,279 @@ namespace Assimp
|
||||||
*/
|
*/
|
||||||
class ColladaParser
|
class ColladaParser
|
||||||
{
|
{
|
||||||
friend class ColladaLoader;
|
friend class ColladaLoader;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Constructor from XML file */
|
/** Constructor from XML file */
|
||||||
ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
|
ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~ColladaParser();
|
~ColladaParser();
|
||||||
|
|
||||||
/** Reads the contents of the file */
|
/** Reads the contents of the file */
|
||||||
void ReadContents();
|
void ReadContents();
|
||||||
|
|
||||||
/** Reads the structure of the file */
|
/** Reads the structure of the file */
|
||||||
void ReadStructure();
|
void ReadStructure();
|
||||||
|
|
||||||
/** Reads asset informations such as coordinate system informations and legal blah */
|
/** Reads asset informations such as coordinate system informations and legal blah */
|
||||||
void ReadAssetInfo();
|
void ReadAssetInfo();
|
||||||
|
|
||||||
/** Reads the animation library */
|
/** Reads the animation library */
|
||||||
void ReadAnimationLibrary();
|
void ReadAnimationLibrary();
|
||||||
|
|
||||||
/** Reads an animation into the given parent structure */
|
/** Reads an animation into the given parent structure */
|
||||||
void ReadAnimation( Collada::Animation* pParent);
|
void ReadAnimation( Collada::Animation* pParent);
|
||||||
|
|
||||||
/** Reads an animation sampler into the given anim channel */
|
/** Reads an animation sampler into the given anim channel */
|
||||||
void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
|
void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
|
||||||
|
|
||||||
/** Reads the skeleton controller library */
|
/** Reads the skeleton controller library */
|
||||||
void ReadControllerLibrary();
|
void ReadControllerLibrary();
|
||||||
|
|
||||||
/** Reads a controller into the given mesh structure */
|
/** Reads a controller into the given mesh structure */
|
||||||
void ReadController( Collada::Controller& pController);
|
void ReadController( Collada::Controller& pController);
|
||||||
|
|
||||||
/** Reads the joint definitions for the given controller */
|
/** Reads the joint definitions for the given controller */
|
||||||
void ReadControllerJoints( Collada::Controller& pController);
|
void ReadControllerJoints( Collada::Controller& pController);
|
||||||
|
|
||||||
/** Reads the joint weights for the given controller */
|
/** Reads the joint weights for the given controller */
|
||||||
void ReadControllerWeights( Collada::Controller& pController);
|
void ReadControllerWeights( Collada::Controller& pController);
|
||||||
|
|
||||||
/** Reads the image library contents */
|
/** Reads the image library contents */
|
||||||
void ReadImageLibrary();
|
void ReadImageLibrary();
|
||||||
|
|
||||||
/** Reads an image entry into the given image */
|
/** Reads an image entry into the given image */
|
||||||
void ReadImage( Collada::Image& pImage);
|
void ReadImage( Collada::Image& pImage);
|
||||||
|
|
||||||
/** Reads the material library */
|
/** Reads the material library */
|
||||||
void ReadMaterialLibrary();
|
void ReadMaterialLibrary();
|
||||||
|
|
||||||
/** Reads a material entry into the given material */
|
/** Reads a material entry into the given material */
|
||||||
void ReadMaterial( Collada::Material& pMaterial);
|
void ReadMaterial( Collada::Material& pMaterial);
|
||||||
|
|
||||||
/** Reads the camera library */
|
/** Reads the camera library */
|
||||||
void ReadCameraLibrary();
|
void ReadCameraLibrary();
|
||||||
|
|
||||||
/** Reads a camera entry into the given camera */
|
/** Reads a camera entry into the given camera */
|
||||||
void ReadCamera( Collada::Camera& pCamera);
|
void ReadCamera( Collada::Camera& pCamera);
|
||||||
|
|
||||||
/** Reads the light library */
|
/** Reads the light library */
|
||||||
void ReadLightLibrary();
|
void ReadLightLibrary();
|
||||||
|
|
||||||
/** Reads a light entry into the given light */
|
/** Reads a light entry into the given light */
|
||||||
void ReadLight( Collada::Light& pLight);
|
void ReadLight( Collada::Light& pLight);
|
||||||
|
|
||||||
/** Reads the effect library */
|
/** Reads the effect library */
|
||||||
void ReadEffectLibrary();
|
void ReadEffectLibrary();
|
||||||
|
|
||||||
/** Reads an effect entry into the given effect*/
|
/** Reads an effect entry into the given effect*/
|
||||||
void ReadEffect( Collada::Effect& pEffect);
|
void ReadEffect( Collada::Effect& pEffect);
|
||||||
|
|
||||||
/** Reads an COMMON effect profile */
|
/** Reads an COMMON effect profile */
|
||||||
void ReadEffectProfileCommon( Collada::Effect& pEffect);
|
void ReadEffectProfileCommon( Collada::Effect& pEffect);
|
||||||
|
|
||||||
/** Read sampler properties */
|
/** Read sampler properties */
|
||||||
void ReadSamplerProperties( Collada::Sampler& pSampler);
|
void ReadSamplerProperties( Collada::Sampler& pSampler);
|
||||||
|
|
||||||
/** Reads an effect entry containing a color or a texture defining that color */
|
/** Reads an effect entry containing a color or a texture defining that color */
|
||||||
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
|
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
|
||||||
|
|
||||||
/** Reads an effect entry containing a float */
|
/** Reads an effect entry containing a float */
|
||||||
void ReadEffectFloat( float& pFloat);
|
void ReadEffectFloat( float& pFloat);
|
||||||
|
|
||||||
/** Reads an effect parameter specification of any kind */
|
/** Reads an effect parameter specification of any kind */
|
||||||
void ReadEffectParam( Collada::EffectParam& pParam);
|
void ReadEffectParam( Collada::EffectParam& pParam);
|
||||||
|
|
||||||
/** Reads the geometry library contents */
|
/** Reads the geometry library contents */
|
||||||
void ReadGeometryLibrary();
|
void ReadGeometryLibrary();
|
||||||
|
|
||||||
/** Reads a geometry from the geometry library. */
|
/** Reads a geometry from the geometry library. */
|
||||||
void ReadGeometry( Collada::Mesh* pMesh);
|
void ReadGeometry( Collada::Mesh* pMesh);
|
||||||
|
|
||||||
/** Reads a mesh from the geometry library */
|
/** Reads a mesh from the geometry library */
|
||||||
void ReadMesh( Collada::Mesh* pMesh);
|
void ReadMesh( Collada::Mesh* pMesh);
|
||||||
|
|
||||||
/** Reads a source element - a combination of raw data and an accessor defining
|
/** Reads a source element - a combination of raw data and an accessor defining
|
||||||
* things that should not be redefinable. Yes, that's another rant.
|
* things that should not be redefinable. Yes, that's another rant.
|
||||||
*/
|
*/
|
||||||
void ReadSource();
|
void ReadSource();
|
||||||
|
|
||||||
/** Reads a data array holding a number of elements, and stores it in the global library.
|
/** Reads a data array holding a number of elements, and stores it in the global library.
|
||||||
* Currently supported are array of floats and arrays of strings.
|
* Currently supported are array of floats and arrays of strings.
|
||||||
*/
|
*/
|
||||||
void ReadDataArray();
|
void ReadDataArray();
|
||||||
|
|
||||||
/** Reads an accessor and stores it in the global library under the given ID -
|
/** Reads an accessor and stores it in the global library under the given ID -
|
||||||
* accessors use the ID of the parent <source> element
|
* accessors use the ID of the parent <source> element
|
||||||
*/
|
*/
|
||||||
void ReadAccessor( const std::string& pID);
|
void ReadAccessor( const std::string& pID);
|
||||||
|
|
||||||
/** Reads input declarations of per-vertex mesh data into the given mesh */
|
/** Reads input declarations of per-vertex mesh data into the given mesh */
|
||||||
void ReadVertexData( Collada::Mesh* pMesh);
|
void ReadVertexData( Collada::Mesh* pMesh);
|
||||||
|
|
||||||
/** Reads input declarations of per-index mesh data into the given mesh */
|
/** Reads input declarations of per-index mesh data into the given mesh */
|
||||||
void ReadIndexData( Collada::Mesh* pMesh);
|
void ReadIndexData( Collada::Mesh* pMesh);
|
||||||
|
|
||||||
/** Reads a single input channel element and stores it in the given array, if valid */
|
/** Reads a single input channel element and stores it in the given array, if valid */
|
||||||
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
|
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
|
||||||
|
|
||||||
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
|
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
|
||||||
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
||||||
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
|
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
|
||||||
|
|
||||||
/** Copies the data for a single primitive into the mesh, based on the InputChannels */
|
/** Copies the data for a single primitive into the mesh, based on the InputChannels */
|
||||||
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
|
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
|
||||||
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
|
||||||
size_t currentPrimitive, const std::vector<size_t>& indices);
|
size_t currentPrimitive, const std::vector<size_t>& indices);
|
||||||
|
|
||||||
/** Reads one triangle of a tristrip into the mesh */
|
/** Reads one triangle of a tristrip into the mesh */
|
||||||
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
|
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
|
||||||
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
|
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
|
||||||
|
|
||||||
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
|
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
|
||||||
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
|
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
|
||||||
|
|
||||||
/** Reads the library of node hierarchies and scene parts */
|
/** Reads the library of node hierarchies and scene parts */
|
||||||
void ReadSceneLibrary();
|
void ReadSceneLibrary();
|
||||||
|
|
||||||
/** Reads a scene node's contents including children and stores it in the given node */
|
/** Reads a scene node's contents including children and stores it in the given node */
|
||||||
void ReadSceneNode( Collada::Node* pNode);
|
void ReadSceneNode( Collada::Node* pNode);
|
||||||
|
|
||||||
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
|
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
|
||||||
void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
|
void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
|
||||||
|
|
||||||
/** Reads a mesh reference in a node and adds it to the node's mesh list */
|
/** Reads a mesh reference in a node and adds it to the node's mesh list */
|
||||||
void ReadNodeGeometry( Collada::Node* pNode);
|
void ReadNodeGeometry( Collada::Node* pNode);
|
||||||
|
|
||||||
/** Reads the collada scene */
|
/** Reads the collada scene */
|
||||||
void ReadScene();
|
void ReadScene();
|
||||||
|
|
||||||
// Processes bind_vertex_input and bind elements
|
// Processes bind_vertex_input and bind elements
|
||||||
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
|
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Aborts the file reading with an exception */
|
/** Aborts the file reading with an exception */
|
||||||
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
/** Skips all data until the end node of the current element */
|
/** Skips all data until the end node of the current element */
|
||||||
void SkipElement();
|
void SkipElement();
|
||||||
|
|
||||||
/** Skips all data until the end node of the given element */
|
/** Skips all data until the end node of the given element */
|
||||||
void SkipElement( const char* pElement);
|
void SkipElement( const char* pElement);
|
||||||
|
|
||||||
/** Compares the current xml element name to the given string and returns true if equal */
|
/** Compares the current xml element name to the given string and returns true if equal */
|
||||||
bool IsElement( const char* pName) const;
|
bool IsElement( const char* pName) const;
|
||||||
|
|
||||||
/** Tests for the opening tag of the given element, throws an exception if not found */
|
/** Tests for the opening tag of the given element, throws an exception if not found */
|
||||||
void TestOpening( const char* pName);
|
void TestOpening( const char* pName);
|
||||||
|
|
||||||
/** Tests for the closing tag of the given element, throws an exception if not found */
|
/** Tests for the closing tag of the given element, throws an exception if not found */
|
||||||
void TestClosing( const char* pName);
|
void TestClosing( const char* pName);
|
||||||
|
|
||||||
/** Checks the present element for the presence of the attribute, returns its index
|
/** Checks the present element for the presence of the attribute, returns its index
|
||||||
or throws an exception if not found */
|
or throws an exception if not found */
|
||||||
int GetAttribute( const char* pAttr) const;
|
int GetAttribute( const char* pAttr) const;
|
||||||
|
|
||||||
/** Returns the index of the named attribute or -1 if not found. Does not throw,
|
/** Returns the index of the named attribute or -1 if not found. Does not throw,
|
||||||
therefore useful for optional attributes */
|
therefore useful for optional attributes */
|
||||||
int TestAttribute( const char* pAttr) const;
|
int TestAttribute( const char* pAttr) const;
|
||||||
|
|
||||||
/** Reads the text contents of an element, throws an exception if not given.
|
/** Reads the text contents of an element, throws an exception if not given.
|
||||||
Skips leading whitespace. */
|
Skips leading whitespace. */
|
||||||
const char* GetTextContent();
|
const char* GetTextContent();
|
||||||
|
|
||||||
/** Reads the text contents of an element, returns NULL if not given.
|
/** Reads the text contents of an element, returns NULL if not given.
|
||||||
Skips leading whitespace. */
|
Skips leading whitespace. */
|
||||||
const char* TestTextContent();
|
const char* TestTextContent();
|
||||||
|
|
||||||
/** Reads a single bool from current text content */
|
/** Reads a single bool from current text content */
|
||||||
bool ReadBoolFromTextContent();
|
bool ReadBoolFromTextContent();
|
||||||
|
|
||||||
/** Reads a single float from current text content */
|
/** Reads a single float from current text content */
|
||||||
float ReadFloatFromTextContent();
|
float ReadFloatFromTextContent();
|
||||||
|
|
||||||
/** Calculates the resulting transformation from all the given transform steps */
|
/** Calculates the resulting transformation from all the given transform steps */
|
||||||
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
|
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
|
||||||
|
|
||||||
/** Determines the input data type for the given semantic string */
|
/** Determines the input data type for the given semantic string */
|
||||||
Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
|
Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
|
||||||
|
|
||||||
/** Finds the item in the given library by its reference, throws if not found */
|
/** Finds the item in the given library by its reference, throws if not found */
|
||||||
template <typename Type> const Type& ResolveLibraryReference(
|
template <typename Type> const Type& ResolveLibraryReference(
|
||||||
const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
|
const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Filename, for a verbose error message */
|
/** Filename, for a verbose error message */
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** XML reader, member for everyday use */
|
/** XML reader, member for everyday use */
|
||||||
irr::io::IrrXMLReader* mReader;
|
irr::io::IrrXMLReader* mReader;
|
||||||
|
|
||||||
/** All data arrays found in the file by ID. Might be referred to by actually
|
/** All data arrays found in the file by ID. Might be referred to by actually
|
||||||
everyone. Collada, you are a steaming pile of indirection. */
|
everyone. Collada, you are a steaming pile of indirection. */
|
||||||
typedef std::map<std::string, Collada::Data> DataLibrary;
|
typedef std::map<std::string, Collada::Data> DataLibrary;
|
||||||
DataLibrary mDataLibrary;
|
DataLibrary mDataLibrary;
|
||||||
|
|
||||||
/** Same for accessors which define how the data in a data array is accessed. */
|
/** Same for accessors which define how the data in a data array is accessed. */
|
||||||
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
|
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
|
||||||
AccessorLibrary mAccessorLibrary;
|
AccessorLibrary mAccessorLibrary;
|
||||||
|
|
||||||
/** Mesh library: mesh by ID */
|
/** Mesh library: mesh by ID */
|
||||||
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
|
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
|
||||||
MeshLibrary mMeshLibrary;
|
MeshLibrary mMeshLibrary;
|
||||||
|
|
||||||
/** node library: root node of the hierarchy part by ID */
|
/** node library: root node of the hierarchy part by ID */
|
||||||
typedef std::map<std::string, Collada::Node*> NodeLibrary;
|
typedef std::map<std::string, Collada::Node*> NodeLibrary;
|
||||||
NodeLibrary mNodeLibrary;
|
NodeLibrary mNodeLibrary;
|
||||||
|
|
||||||
/** Image library: stores texture properties by ID */
|
/** Image library: stores texture properties by ID */
|
||||||
typedef std::map<std::string, Collada::Image> ImageLibrary;
|
typedef std::map<std::string, Collada::Image> ImageLibrary;
|
||||||
ImageLibrary mImageLibrary;
|
ImageLibrary mImageLibrary;
|
||||||
|
|
||||||
/** Effect library: surface attributes by ID */
|
/** Effect library: surface attributes by ID */
|
||||||
typedef std::map<std::string, Collada::Effect> EffectLibrary;
|
typedef std::map<std::string, Collada::Effect> EffectLibrary;
|
||||||
EffectLibrary mEffectLibrary;
|
EffectLibrary mEffectLibrary;
|
||||||
|
|
||||||
/** Material library: surface material by ID */
|
/** Material library: surface material by ID */
|
||||||
typedef std::map<std::string, Collada::Material> MaterialLibrary;
|
typedef std::map<std::string, Collada::Material> MaterialLibrary;
|
||||||
MaterialLibrary mMaterialLibrary;
|
MaterialLibrary mMaterialLibrary;
|
||||||
|
|
||||||
/** Light library: surface light by ID */
|
/** Light library: surface light by ID */
|
||||||
typedef std::map<std::string, Collada::Light> LightLibrary;
|
typedef std::map<std::string, Collada::Light> LightLibrary;
|
||||||
LightLibrary mLightLibrary;
|
LightLibrary mLightLibrary;
|
||||||
|
|
||||||
/** Camera library: surface material by ID */
|
/** Camera library: surface material by ID */
|
||||||
typedef std::map<std::string, Collada::Camera> CameraLibrary;
|
typedef std::map<std::string, Collada::Camera> CameraLibrary;
|
||||||
CameraLibrary mCameraLibrary;
|
CameraLibrary mCameraLibrary;
|
||||||
|
|
||||||
/** Controller library: joint controllers by ID */
|
/** Controller library: joint controllers by ID */
|
||||||
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
|
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
|
||||||
ControllerLibrary mControllerLibrary;
|
ControllerLibrary mControllerLibrary;
|
||||||
|
|
||||||
/** Pointer to the root node. Don't delete, it just points to one of
|
/** Pointer to the root node. Don't delete, it just points to one of
|
||||||
the nodes in the node library. */
|
the nodes in the node library. */
|
||||||
Collada::Node* mRootNode;
|
Collada::Node* mRootNode;
|
||||||
|
|
||||||
/** Root animation container */
|
/** Root animation container */
|
||||||
Collada::Animation mAnims;
|
Collada::Animation mAnims;
|
||||||
|
|
||||||
/** Size unit: how large compared to a meter */
|
/** Size unit: how large compared to a meter */
|
||||||
float mUnitSize;
|
float mUnitSize;
|
||||||
|
|
||||||
/** Which is the up vector */
|
/** Which is the up vector */
|
||||||
enum { UP_X, UP_Y, UP_Z } mUpDirection;
|
enum { UP_X, UP_Y, UP_Z } mUpDirection;
|
||||||
|
|
||||||
/** Collada file format version */
|
/** Collada file format version */
|
||||||
Collada::FormatVersion mFormat;
|
Collada::FormatVersion mFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Check for element match
|
// Check for element match
|
||||||
inline bool ColladaParser::IsElement( const char* pName) const
|
inline bool ColladaParser::IsElement( const char* pName) const
|
||||||
{
|
{
|
||||||
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
|
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
|
||||||
return ::strcmp( mReader->getNodeName(), pName) == 0;
|
return ::strcmp( mReader->getNodeName(), pName) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -341,10 +341,10 @@ inline bool ColladaParser::IsElement( const char* pName) const
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
|
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
|
||||||
{
|
{
|
||||||
typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
|
typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
|
||||||
if( it == pLibrary.end())
|
if( it == pLibrary.end())
|
||||||
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
|
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -49,42 +49,42 @@ using namespace Assimp;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const static aiVector3D base_axis_y(0.f,1.f,0.f);
|
const static aiVector3D base_axis_y(0.f,1.f,0.f);
|
||||||
const static aiVector3D base_axis_x(1.f,0.f,0.f);
|
const static aiVector3D base_axis_x(1.f,0.f,0.f);
|
||||||
const static aiVector3D base_axis_z(0.f,0.f,1.f);
|
const static aiVector3D base_axis_z(0.f,0.f,1.f);
|
||||||
const static float angle_epsilon = 0.95f;
|
const static float angle_epsilon = 0.95f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ComputeUVMappingProcess::ComputeUVMappingProcess()
|
ComputeUVMappingProcess::ComputeUVMappingProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
ComputeUVMappingProcess::~ComputeUVMappingProcess()
|
ComputeUVMappingProcess::~ComputeUVMappingProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
|
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
return (pFlags & aiProcess_GenUVCoords) != 0;
|
return (pFlags & aiProcess_GenUVCoords) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Check whether a ray intersects a plane and find the intersection point
|
// Check whether a ray intersects a plane and find the intersection point
|
||||||
inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
|
inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
|
||||||
const aiVector3D& planeNormal, aiVector3D& pos)
|
const aiVector3D& planeNormal, aiVector3D& pos)
|
||||||
{
|
{
|
||||||
const float b = planeNormal * (planePos - ray.pos);
|
const float b = planeNormal * (planePos - ray.pos);
|
||||||
float h = ray.dir * planeNormal;
|
float h = ray.dir * planeNormal;
|
||||||
if ((h < 10e-5f && h > -10e-5f) || (h = b/h) < 0)
|
if ((h < 10e-5f && h > -10e-5f) || (h = b/h) < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pos = ray.pos + (ray.dir * h);
|
pos = ray.pos + (ray.dir * h);
|
||||||
return true;
|
return true;
|
||||||
|
@ -94,411 +94,411 @@ inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
|
||||||
// Find the first empty UV channel in a mesh
|
// Find the first empty UV channel in a mesh
|
||||||
inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
|
inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
|
||||||
{
|
{
|
||||||
for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
|
for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
|
||||||
if (!mesh->mTextureCoords[m])return m;
|
if (!mesh->mTextureCoords[m])return m;
|
||||||
|
|
||||||
DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found");
|
DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found");
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Try to remove UV seams
|
// Try to remove UV seams
|
||||||
void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
|
void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
|
||||||
{
|
{
|
||||||
// TODO: just a very rough algorithm. I think it could be done
|
// TODO: just a very rough algorithm. I think it could be done
|
||||||
// much easier, but I don't know how and am currently too tired to
|
// much easier, but I don't know how and am currently too tired to
|
||||||
// to think about a better solution.
|
// to think about a better solution.
|
||||||
|
|
||||||
const static float LOWER_LIMIT = 0.1f;
|
const static float LOWER_LIMIT = 0.1f;
|
||||||
const static float UPPER_LIMIT = 0.9f;
|
const static float UPPER_LIMIT = 0.9f;
|
||||||
|
|
||||||
const static float LOWER_EPSILON = 10e-3f;
|
const static float LOWER_EPSILON = 10e-3f;
|
||||||
const static float UPPER_EPSILON = 1.f-10e-3f;
|
const static float UPPER_EPSILON = 1.f-10e-3f;
|
||||||
|
|
||||||
for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
|
for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
|
||||||
{
|
{
|
||||||
const aiFace& face = mesh->mFaces[fidx];
|
const aiFace& face = mesh->mFaces[fidx];
|
||||||
if (face.mNumIndices < 3) continue; // triangles and polygons only, please
|
if (face.mNumIndices < 3) continue; // triangles and polygons only, please
|
||||||
|
|
||||||
unsigned int small = face.mNumIndices, large = small;
|
unsigned int small = face.mNumIndices, large = small;
|
||||||
bool zero = false, one = false, round_to_zero = false;
|
bool zero = false, one = false, round_to_zero = false;
|
||||||
|
|
||||||
// Check whether this face lies on a UV seam. We can just guess,
|
// Check whether this face lies on a UV seam. We can just guess,
|
||||||
// but the assumption that a face with at least one very small
|
// but the assumption that a face with at least one very small
|
||||||
// on the one side and one very large U coord on the other side
|
// on the one side and one very large U coord on the other side
|
||||||
// lies on a UV seam should work for most cases.
|
// lies on a UV seam should work for most cases.
|
||||||
for (unsigned int n = 0; n < face.mNumIndices;++n)
|
for (unsigned int n = 0; n < face.mNumIndices;++n)
|
||||||
{
|
{
|
||||||
if (out[face.mIndices[n]].x < LOWER_LIMIT)
|
if (out[face.mIndices[n]].x < LOWER_LIMIT)
|
||||||
{
|
{
|
||||||
small = n;
|
small = n;
|
||||||
|
|
||||||
// If we have a U value very close to 0 we can't
|
// If we have a U value very close to 0 we can't
|
||||||
// round the others to 0, too.
|
// round the others to 0, too.
|
||||||
if (out[face.mIndices[n]].x <= LOWER_EPSILON)
|
if (out[face.mIndices[n]].x <= LOWER_EPSILON)
|
||||||
zero = true;
|
zero = true;
|
||||||
else round_to_zero = true;
|
else round_to_zero = true;
|
||||||
}
|
}
|
||||||
if (out[face.mIndices[n]].x > UPPER_LIMIT)
|
if (out[face.mIndices[n]].x > UPPER_LIMIT)
|
||||||
{
|
{
|
||||||
large = n;
|
large = n;
|
||||||
|
|
||||||
// If we have a U value very close to 1 we can't
|
// If we have a U value very close to 1 we can't
|
||||||
// round the others to 1, too.
|
// round the others to 1, too.
|
||||||
if (out[face.mIndices[n]].x >= UPPER_EPSILON)
|
if (out[face.mIndices[n]].x >= UPPER_EPSILON)
|
||||||
one = true;
|
one = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (small != face.mNumIndices && large != face.mNumIndices)
|
if (small != face.mNumIndices && large != face.mNumIndices)
|
||||||
{
|
{
|
||||||
for (unsigned int n = 0; n < face.mNumIndices;++n)
|
for (unsigned int n = 0; n < face.mNumIndices;++n)
|
||||||
{
|
{
|
||||||
// If the u value is over the upper limit and no other u
|
// If the u value is over the upper limit and no other u
|
||||||
// value of that face is 0, round it to 0
|
// value of that face is 0, round it to 0
|
||||||
if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
|
if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
|
||||||
out[face.mIndices[n]].x = 0.f;
|
out[face.mIndices[n]].x = 0.f;
|
||||||
|
|
||||||
// If the u value is below the lower limit and no other u
|
// If the u value is below the lower limit and no other u
|
||||||
// value of that face is 1, round it to 1
|
// value of that face is 1, round it to 1
|
||||||
else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one)
|
else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one)
|
||||||
out[face.mIndices[n]].x = 1.f;
|
out[face.mIndices[n]].x = 1.f;
|
||||||
|
|
||||||
// The face contains both 0 and 1 as UV coords. This can occur
|
// The face contains both 0 and 1 as UV coords. This can occur
|
||||||
// for faces which have an edge that lies directly on the seam.
|
// for faces which have an edge that lies directly on the seam.
|
||||||
// Due to numerical inaccuracies one U coord becomes 0, the
|
// Due to numerical inaccuracies one U coord becomes 0, the
|
||||||
// other 1. But we do still have a third UV coord to determine
|
// other 1. But we do still have a third UV coord to determine
|
||||||
// to which side we must round to.
|
// to which side we must round to.
|
||||||
else if (one && zero)
|
else if (one && zero)
|
||||||
{
|
{
|
||||||
if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
|
if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
|
||||||
out[face.mIndices[n]].x = 0.f;
|
out[face.mIndices[n]].x = 0.f;
|
||||||
else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
|
else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
|
||||||
out[face.mIndices[n]].x = 1.f;
|
out[face.mIndices[n]].x = 1.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
||||||
{
|
{
|
||||||
aiVector3D center, min, max;
|
aiVector3D center, min, max;
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
|
|
||||||
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
||||||
// currently the mapping axis will always be one of x,y,z, except if the
|
// currently the mapping axis will always be one of x,y,z, except if the
|
||||||
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
||||||
// thus changing the mapping axis)
|
// thus changing the mapping axis)
|
||||||
if (axis * base_axis_x >= angle_epsilon) {
|
if (axis * base_axis_x >= angle_epsilon) {
|
||||||
|
|
||||||
// For each point get a normalized projection vector in the sphere,
|
// For each point get a normalized projection vector in the sphere,
|
||||||
// get its longitude and latitude and map them to their respective
|
// get its longitude and latitude and map them to their respective
|
||||||
// UV axes. Problems occur around the poles ... unsolvable.
|
// UV axes. Problems occur around the poles ... unsolvable.
|
||||||
//
|
//
|
||||||
// The spherical coordinate system looks like this:
|
// The spherical coordinate system looks like this:
|
||||||
// x = cos(lon)*cos(lat)
|
// x = cos(lon)*cos(lat)
|
||||||
// y = sin(lon)*cos(lat)
|
// y = sin(lon)*cos(lat)
|
||||||
// z = sin(lat)
|
// z = sin(lat)
|
||||||
//
|
//
|
||||||
// Thus we can derive:
|
// Thus we can derive:
|
||||||
// lat = arcsin (z)
|
// lat = arcsin (z)
|
||||||
// lon = arctan (y/x)
|
// lon = arctan (y/x)
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
||||||
out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
(std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (axis * base_axis_y >= angle_epsilon) {
|
else if (axis * base_axis_y >= angle_epsilon) {
|
||||||
// ... just the same again
|
// ... just the same again
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
||||||
out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
(std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (axis * base_axis_z >= angle_epsilon) {
|
else if (axis * base_axis_z >= angle_epsilon) {
|
||||||
// ... just the same again
|
// ... just the same again
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
||||||
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||||
(std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
(std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||||
else {
|
else {
|
||||||
aiMatrix4x4 mTrafo;
|
aiMatrix4x4 mTrafo;
|
||||||
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
||||||
|
|
||||||
// again the same, except we're applying a transformation now
|
// again the same, except we're applying a transformation now
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
|
const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
|
||||||
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||||
(asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
(asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
||||||
// close to zero on the one side, and a tcoord close to one on the
|
// close to zero on the one side, and a tcoord close to one on the
|
||||||
// other side.
|
// other side.
|
||||||
RemoveUVSeams(mesh,out);
|
RemoveUVSeams(mesh,out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
||||||
{
|
{
|
||||||
aiVector3D center, min, max;
|
aiVector3D center, min, max;
|
||||||
|
|
||||||
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
||||||
// currently the mapping axis will always be one of x,y,z, except if the
|
// currently the mapping axis will always be one of x,y,z, except if the
|
||||||
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
||||||
// thus changing the mapping axis)
|
// thus changing the mapping axis)
|
||||||
if (axis * base_axis_x >= angle_epsilon) {
|
if (axis * base_axis_x >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
const float diff = max.x - min.x;
|
const float diff = max.x - min.x;
|
||||||
|
|
||||||
// If the main axis is 'z', the z coordinate of a point 'p' is mapped
|
// If the main axis is 'z', the z coordinate of a point 'p' is mapped
|
||||||
// directly to the texture V axis. The other axis is derived from
|
// directly to the texture V axis. The other axis is derived from
|
||||||
// the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
|
// the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
|
||||||
// 'c' is the center point of the mesh.
|
// 'c' is the center point of the mesh.
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D& uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.x - min.x) / diff;
|
uv.y = (pos.x - min.x) / diff;
|
||||||
uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (axis * base_axis_y >= angle_epsilon) {
|
else if (axis * base_axis_y >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
const float diff = max.y - min.y;
|
const float diff = max.y - min.y;
|
||||||
|
|
||||||
// just the same ...
|
// just the same ...
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D& uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.y - min.y) / diff;
|
uv.y = (pos.y - min.y) / diff;
|
||||||
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (axis * base_axis_z >= angle_epsilon) {
|
else if (axis * base_axis_z >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
const float diff = max.z - min.z;
|
const float diff = max.z - min.z;
|
||||||
|
|
||||||
// just the same ...
|
// just the same ...
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D& uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.z - min.z) / diff;
|
uv.y = (pos.z - min.z) / diff;
|
||||||
uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||||
else {
|
else {
|
||||||
aiMatrix4x4 mTrafo;
|
aiMatrix4x4 mTrafo;
|
||||||
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
||||||
FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
|
FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
|
||||||
const float diff = max.y - min.y;
|
const float diff = max.y - min.y;
|
||||||
|
|
||||||
// again the same, except we're applying a transformation now
|
// again the same, except we're applying a transformation now
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){
|
||||||
const aiVector3D pos = mTrafo* mesh->mVertices[pnt];
|
const aiVector3D pos = mTrafo* mesh->mVertices[pnt];
|
||||||
aiVector3D& uv = out[pnt];
|
aiVector3D& uv = out[pnt];
|
||||||
|
|
||||||
uv.y = (pos.y - min.y) / diff;
|
uv.y = (pos.y - min.y) / diff;
|
||||||
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
// Now find and remove UV seams. A seam occurs if a face has a tcoord
|
||||||
// close to zero on the one side, and a tcoord close to one on the
|
// close to zero on the one side, and a tcoord close to one on the
|
||||||
// other side.
|
// other side.
|
||||||
RemoveUVSeams(mesh,out);
|
RemoveUVSeams(mesh,out);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
|
||||||
{
|
{
|
||||||
float diffu,diffv;
|
float diffu,diffv;
|
||||||
aiVector3D center, min, max;
|
aiVector3D center, min, max;
|
||||||
|
|
||||||
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
|
||||||
// currently the mapping axis will always be one of x,y,z, except if the
|
// currently the mapping axis will always be one of x,y,z, except if the
|
||||||
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
// PretransformVertices step is used (it transforms the meshes into worldspace,
|
||||||
// thus changing the mapping axis)
|
// thus changing the mapping axis)
|
||||||
if (axis * base_axis_x >= angle_epsilon) {
|
if (axis * base_axis_x >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
diffu = max.z - min.z;
|
diffu = max.z - min.z;
|
||||||
diffv = max.y - min.y;
|
diffv = max.y - min.y;
|
||||||
|
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.f);
|
out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (axis * base_axis_y >= angle_epsilon) {
|
else if (axis * base_axis_y >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
diffu = max.x - min.x;
|
diffu = max.x - min.x;
|
||||||
diffv = max.z - min.z;
|
diffv = max.z - min.z;
|
||||||
|
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
|
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (axis * base_axis_z >= angle_epsilon) {
|
else if (axis * base_axis_z >= angle_epsilon) {
|
||||||
FindMeshCenter(mesh, center, min, max);
|
FindMeshCenter(mesh, center, min, max);
|
||||||
diffu = max.y - min.y;
|
diffu = max.y - min.y;
|
||||||
diffv = max.z - min.z;
|
diffv = max.z - min.z;
|
||||||
|
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.f);
|
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aiMatrix4x4 mTrafo;
|
aiMatrix4x4 mTrafo;
|
||||||
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
|
||||||
FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
|
FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
|
||||||
diffu = max.x - min.x;
|
diffu = max.x - min.x;
|
||||||
diffv = max.z - min.z;
|
diffv = max.z - min.z;
|
||||||
|
|
||||||
// again the same, except we're applying a transformation now
|
// again the same, except we're applying a transformation now
|
||||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||||
const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
|
const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
|
||||||
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
|
out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldn't be necessary to remove UV seams ...
|
// shouldn't be necessary to remove UV seams ...
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
|
void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("Mapping type currently not implemented");
|
DefaultLogger::get()->error("Mapping type currently not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
void ComputeUVMappingProcess::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("GenUVCoordsProcess begin");
|
DefaultLogger::get()->debug("GenUVCoordsProcess begin");
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
|
if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
|
||||||
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
|
throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
|
||||||
|
|
||||||
std::list<MappingInfo> mappingStack;
|
std::list<MappingInfo> mappingStack;
|
||||||
|
|
||||||
/* Iterate through all materials and search for non-UV mapped textures
|
/* Iterate through all materials and search for non-UV mapped textures
|
||||||
*/
|
*/
|
||||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||||
{
|
{
|
||||||
mappingStack.clear();
|
mappingStack.clear();
|
||||||
aiMaterial* mat = pScene->mMaterials[i];
|
aiMaterial* mat = pScene->mMaterials[i];
|
||||||
for (unsigned int a = 0; a < mat->mNumProperties;++a)
|
for (unsigned int a = 0; a < mat->mNumProperties;++a)
|
||||||
{
|
{
|
||||||
aiMaterialProperty* prop = mat->mProperties[a];
|
aiMaterialProperty* prop = mat->mProperties[a];
|
||||||
if (!::strcmp( prop->mKey.data, "$tex.mapping"))
|
if (!::strcmp( prop->mKey.data, "$tex.mapping"))
|
||||||
{
|
{
|
||||||
aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData);
|
aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData);
|
||||||
if (aiTextureMapping_UV != mapping)
|
if (aiTextureMapping_UV != mapping)
|
||||||
{
|
{
|
||||||
if (!DefaultLogger::isNullLogger())
|
if (!DefaultLogger::isNullLogger())
|
||||||
{
|
{
|
||||||
sprintf(buffer, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
|
sprintf(buffer, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
|
||||||
TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
|
TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
|
||||||
MappingTypeToString(mapping));
|
MappingTypeToString(mapping));
|
||||||
|
|
||||||
DefaultLogger::get()->info(buffer);
|
DefaultLogger::get()->info(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aiTextureMapping_OTHER == mapping)
|
if (aiTextureMapping_OTHER == mapping)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MappingInfo info (mapping);
|
MappingInfo info (mapping);
|
||||||
|
|
||||||
// Get further properties - currently only the major axis
|
// Get further properties - currently only the major axis
|
||||||
for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
|
for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
|
||||||
{
|
{
|
||||||
aiMaterialProperty* prop2 = mat->mProperties[a2];
|
aiMaterialProperty* prop2 = mat->mProperties[a2];
|
||||||
if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
|
if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) {
|
if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) {
|
||||||
info.axis = *((aiVector3D*)prop2->mData);
|
info.axis = *((aiVector3D*)prop2->mData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
|
|
||||||
// Check whether we have this mapping mode already
|
// Check whether we have this mapping mode already
|
||||||
std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info);
|
std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info);
|
||||||
if (mappingStack.end() != it)
|
if (mappingStack.end() != it)
|
||||||
{
|
{
|
||||||
idx = (*it).uv;
|
idx = (*it).uv;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We have found a non-UV mapped texture. Now
|
/* We have found a non-UV mapped texture. Now
|
||||||
* we need to find all meshes using this material
|
* we need to find all meshes using this material
|
||||||
* that we can compute UV channels for them.
|
* that we can compute UV channels for them.
|
||||||
*/
|
*/
|
||||||
for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
|
for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
|
||||||
{
|
{
|
||||||
aiMesh* mesh = pScene->mMeshes[m];
|
aiMesh* mesh = pScene->mMeshes[m];
|
||||||
unsigned int outIdx = 0;
|
unsigned int outIdx = 0;
|
||||||
if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX ||
|
if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX ||
|
||||||
!mesh->mNumVertices)
|
!mesh->mNumVertices)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate output storage
|
// Allocate output storage
|
||||||
aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
|
aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
|
||||||
|
|
||||||
switch (mapping)
|
switch (mapping)
|
||||||
{
|
{
|
||||||
case aiTextureMapping_SPHERE:
|
case aiTextureMapping_SPHERE:
|
||||||
ComputeSphereMapping(mesh,info.axis,p);
|
ComputeSphereMapping(mesh,info.axis,p);
|
||||||
break;
|
break;
|
||||||
case aiTextureMapping_CYLINDER:
|
case aiTextureMapping_CYLINDER:
|
||||||
ComputeCylinderMapping(mesh,info.axis,p);
|
ComputeCylinderMapping(mesh,info.axis,p);
|
||||||
break;
|
break;
|
||||||
case aiTextureMapping_PLANE:
|
case aiTextureMapping_PLANE:
|
||||||
ComputePlaneMapping(mesh,info.axis,p);
|
ComputePlaneMapping(mesh,info.axis,p);
|
||||||
break;
|
break;
|
||||||
case aiTextureMapping_BOX:
|
case aiTextureMapping_BOX:
|
||||||
ComputeBoxMapping(mesh,p);
|
ComputeBoxMapping(mesh,p);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
if (m && idx != outIdx)
|
if (m && idx != outIdx)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to "
|
DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to "
|
||||||
"this material have equal numbers of UV channels. The UV index stored in "
|
"this material have equal numbers of UV channels. The UV index stored in "
|
||||||
"the material structure does therefore not apply for all meshes. ");
|
"the material structure does therefore not apply for all meshes. ");
|
||||||
}
|
}
|
||||||
idx = outIdx;
|
idx = outIdx;
|
||||||
}
|
}
|
||||||
info.uv = idx;
|
info.uv = idx;
|
||||||
mappingStack.push_back(info);
|
mappingStack.push_back(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the material property list
|
// Update the material property list
|
||||||
mapping = aiTextureMapping_UV;
|
mapping = aiTextureMapping_UV;
|
||||||
((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex));
|
((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultLogger::get()->debug("GenUVCoordsProcess finished");
|
DefaultLogger::get()->debug("GenUVCoordsProcess finished");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
class ComputeUVMappingTest;
|
class ComputeUVMappingTest;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** ComputeUVMappingProcess - converts special mappings, such as spherical,
|
/** ComputeUVMappingProcess - converts special mappings, such as spherical,
|
||||||
|
@ -60,86 +60,86 @@ namespace Assimp
|
||||||
class ComputeUVMappingProcess : public BaseProcess
|
class ComputeUVMappingProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ComputeUVMappingProcess();
|
ComputeUVMappingProcess();
|
||||||
~ComputeUVMappingProcess();
|
~ComputeUVMappingProcess();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag field.
|
/** Returns whether the processing step is present in the given flag field.
|
||||||
* @param pFlags The processing flags the importer was called with. A bitwise
|
* @param pFlags The processing flags the importer was called with. A bitwise
|
||||||
* combination of #aiPostProcessSteps.
|
* combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields, false if not.
|
* @return true if the process is present in this flag fields, false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Computes spherical UV coordinates for a mesh
|
/** Computes spherical UV coordinates for a mesh
|
||||||
*
|
*
|
||||||
* @param mesh Mesh to be processed
|
* @param mesh Mesh to be processed
|
||||||
* @param axis Main axis
|
* @param axis Main axis
|
||||||
* @param out Receives output UV coordinates
|
* @param out Receives output UV coordinates
|
||||||
*/
|
*/
|
||||||
void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
|
void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
|
||||||
aiVector3D* out);
|
aiVector3D* out);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Computes cylindrical UV coordinates for a mesh
|
/** Computes cylindrical UV coordinates for a mesh
|
||||||
*
|
*
|
||||||
* @param mesh Mesh to be processed
|
* @param mesh Mesh to be processed
|
||||||
* @param axis Main axis
|
* @param axis Main axis
|
||||||
* @param out Receives output UV coordinates
|
* @param out Receives output UV coordinates
|
||||||
*/
|
*/
|
||||||
void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
|
void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
|
||||||
aiVector3D* out);
|
aiVector3D* out);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Computes planar UV coordinates for a mesh
|
/** Computes planar UV coordinates for a mesh
|
||||||
*
|
*
|
||||||
* @param mesh Mesh to be processed
|
* @param mesh Mesh to be processed
|
||||||
* @param axis Main axis
|
* @param axis Main axis
|
||||||
* @param out Receives output UV coordinates
|
* @param out Receives output UV coordinates
|
||||||
*/
|
*/
|
||||||
void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
|
void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
|
||||||
aiVector3D* out);
|
aiVector3D* out);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Computes cubic UV coordinates for a mesh
|
/** Computes cubic UV coordinates for a mesh
|
||||||
*
|
*
|
||||||
* @param mesh Mesh to be processed
|
* @param mesh Mesh to be processed
|
||||||
* @param out Receives output UV coordinates
|
* @param out Receives output UV coordinates
|
||||||
*/
|
*/
|
||||||
void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
|
void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// temporary structure to describe a mapping
|
// temporary structure to describe a mapping
|
||||||
struct MappingInfo
|
struct MappingInfo
|
||||||
{
|
{
|
||||||
MappingInfo(aiTextureMapping _type)
|
MappingInfo(aiTextureMapping _type)
|
||||||
: type (_type)
|
: type (_type)
|
||||||
, axis (0.f,1.f,0.f)
|
, axis (0.f,1.f,0.f)
|
||||||
, uv (0u)
|
, uv (0u)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
aiTextureMapping type;
|
aiTextureMapping type;
|
||||||
aiVector3D axis;
|
aiVector3D axis;
|
||||||
unsigned int uv;
|
unsigned int uv;
|
||||||
|
|
||||||
bool operator== (const MappingInfo& other)
|
bool operator== (const MappingInfo& other)
|
||||||
{
|
{
|
||||||
return type == other.type && axis == other.axis;
|
return type == other.type && axis == other.axis;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -74,59 +74,59 @@ MakeLeftHandedProcess::~MakeLeftHandedProcess() {
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
|
bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
return 0 != (pFlags & aiProcess_MakeLeftHanded);
|
return 0 != (pFlags & aiProcess_MakeLeftHanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void MakeLeftHandedProcess::Execute( aiScene* pScene)
|
void MakeLeftHandedProcess::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
// Check for an existent root node to proceed
|
// Check for an existent root node to proceed
|
||||||
ai_assert(pScene->mRootNode != NULL);
|
ai_assert(pScene->mRootNode != NULL);
|
||||||
DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
|
DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
|
||||||
|
|
||||||
// recursively convert all the nodes
|
// recursively convert all the nodes
|
||||||
ProcessNode( pScene->mRootNode, aiMatrix4x4());
|
ProcessNode( pScene->mRootNode, aiMatrix4x4());
|
||||||
|
|
||||||
// process the meshes accordingly
|
// process the meshes accordingly
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
||||||
ProcessMesh( pScene->mMeshes[a]);
|
ProcessMesh( pScene->mMeshes[a]);
|
||||||
|
|
||||||
// process the materials accordingly
|
// process the materials accordingly
|
||||||
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
|
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
|
||||||
ProcessMaterial( pScene->mMaterials[a]);
|
ProcessMaterial( pScene->mMaterials[a]);
|
||||||
|
|
||||||
// transform all animation channels as well
|
// transform all animation channels as well
|
||||||
for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
|
for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
|
||||||
{
|
{
|
||||||
aiAnimation* anim = pScene->mAnimations[a];
|
aiAnimation* anim = pScene->mAnimations[a];
|
||||||
for( unsigned int b = 0; b < anim->mNumChannels; b++)
|
for( unsigned int b = 0; b < anim->mNumChannels; b++)
|
||||||
{
|
{
|
||||||
aiNodeAnim* nodeAnim = anim->mChannels[b];
|
aiNodeAnim* nodeAnim = anim->mChannels[b];
|
||||||
ProcessAnimation( nodeAnim);
|
ProcessAnimation( nodeAnim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
|
DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Recursively converts a node, all of its children and all of its meshes
|
// Recursively converts a node, all of its children and all of its meshes
|
||||||
void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
|
void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
|
||||||
{
|
{
|
||||||
// mirror all base vectors at the local Z axis
|
// mirror all base vectors at the local Z axis
|
||||||
pNode->mTransformation.c1 = -pNode->mTransformation.c1;
|
pNode->mTransformation.c1 = -pNode->mTransformation.c1;
|
||||||
pNode->mTransformation.c2 = -pNode->mTransformation.c2;
|
pNode->mTransformation.c2 = -pNode->mTransformation.c2;
|
||||||
pNode->mTransformation.c3 = -pNode->mTransformation.c3;
|
pNode->mTransformation.c3 = -pNode->mTransformation.c3;
|
||||||
pNode->mTransformation.c4 = -pNode->mTransformation.c4;
|
pNode->mTransformation.c4 = -pNode->mTransformation.c4;
|
||||||
|
|
||||||
// now invert the Z axis again to keep the matrix determinant positive.
|
// now invert the Z axis again to keep the matrix determinant positive.
|
||||||
// The local meshes will be inverted accordingly so that the result should look just fine again.
|
// The local meshes will be inverted accordingly so that the result should look just fine again.
|
||||||
pNode->mTransformation.a3 = -pNode->mTransformation.a3;
|
pNode->mTransformation.a3 = -pNode->mTransformation.a3;
|
||||||
pNode->mTransformation.b3 = -pNode->mTransformation.b3;
|
pNode->mTransformation.b3 = -pNode->mTransformation.b3;
|
||||||
pNode->mTransformation.c3 = -pNode->mTransformation.c3;
|
pNode->mTransformation.c3 = -pNode->mTransformation.c3;
|
||||||
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
|
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
|
||||||
|
|
||||||
// continue for all children
|
// continue for all children
|
||||||
for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
|
for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
|
||||||
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
|
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
|
||||||
}
|
}
|
||||||
|
@ -136,78 +136,78 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare
|
||||||
// Converts a single mesh to left handed coordinates.
|
// Converts a single mesh to left handed coordinates.
|
||||||
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
|
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
// mirror positions, normals and stuff along the Z axis
|
// mirror positions, normals and stuff along the Z axis
|
||||||
for( size_t a = 0; a < pMesh->mNumVertices; ++a)
|
for( size_t a = 0; a < pMesh->mNumVertices; ++a)
|
||||||
{
|
{
|
||||||
pMesh->mVertices[a].z *= -1.0f;
|
pMesh->mVertices[a].z *= -1.0f;
|
||||||
if( pMesh->HasNormals())
|
if( pMesh->HasNormals())
|
||||||
pMesh->mNormals[a].z *= -1.0f;
|
pMesh->mNormals[a].z *= -1.0f;
|
||||||
if( pMesh->HasTangentsAndBitangents())
|
if( pMesh->HasTangentsAndBitangents())
|
||||||
{
|
{
|
||||||
pMesh->mTangents[a].z *= -1.0f;
|
pMesh->mTangents[a].z *= -1.0f;
|
||||||
pMesh->mBitangents[a].z *= -1.0f;
|
pMesh->mBitangents[a].z *= -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mirror offset matrices of all bones
|
// mirror offset matrices of all bones
|
||||||
for( size_t a = 0; a < pMesh->mNumBones; ++a)
|
for( size_t a = 0; a < pMesh->mNumBones; ++a)
|
||||||
{
|
{
|
||||||
aiBone* bone = pMesh->mBones[a];
|
aiBone* bone = pMesh->mBones[a];
|
||||||
bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
|
bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
|
||||||
bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
|
bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
|
||||||
bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
|
bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
|
||||||
bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
|
bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
|
||||||
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
|
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
|
||||||
bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
|
bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mirror bitangents as well as they're derived from the texture coords
|
// mirror bitangents as well as they're derived from the texture coords
|
||||||
if( pMesh->HasTangentsAndBitangents())
|
if( pMesh->HasTangentsAndBitangents())
|
||||||
{
|
{
|
||||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
|
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
|
||||||
pMesh->mBitangents[a] *= -1.0f;
|
pMesh->mBitangents[a] *= -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts a single material to left handed coordinates.
|
// Converts a single material to left handed coordinates.
|
||||||
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
|
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
|
||||||
{
|
{
|
||||||
aiMaterial* mat = (aiMaterial*)_mat;
|
aiMaterial* mat = (aiMaterial*)_mat;
|
||||||
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
||||||
aiMaterialProperty* prop = mat->mProperties[a];
|
aiMaterialProperty* prop = mat->mProperties[a];
|
||||||
|
|
||||||
// Mapping axis for UV mappings?
|
// Mapping axis for UV mappings?
|
||||||
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
|
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
|
||||||
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
|
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
|
||||||
aiVector3D* pff = (aiVector3D*)prop->mData;
|
aiVector3D* pff = (aiVector3D*)prop->mData;
|
||||||
|
|
||||||
pff->z *= -1.f;
|
pff->z *= -1.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts the given animation to LH coordinates.
|
// Converts the given animation to LH coordinates.
|
||||||
void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
|
void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
|
||||||
{
|
{
|
||||||
// position keys
|
// position keys
|
||||||
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
|
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
|
||||||
pAnim->mPositionKeys[a].mValue.z *= -1.0f;
|
pAnim->mPositionKeys[a].mValue.z *= -1.0f;
|
||||||
|
|
||||||
// rotation keys
|
// rotation keys
|
||||||
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
|
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
|
||||||
{
|
{
|
||||||
/* That's the safe version, but the float errors add up. So we try the short version instead
|
/* That's the safe version, but the float errors add up. So we try the short version instead
|
||||||
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
|
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
|
||||||
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
|
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
|
||||||
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
|
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
|
||||||
aiQuaternion rotquat( rotmat);
|
aiQuaternion rotquat( rotmat);
|
||||||
pAnim->mRotationKeys[a].mValue = rotquat;
|
pAnim->mRotationKeys[a].mValue = rotquat;
|
||||||
*/
|
*/
|
||||||
pAnim->mRotationKeys[a].mValue.x *= -1.0f;
|
pAnim->mRotationKeys[a].mValue.x *= -1.0f;
|
||||||
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
|
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
|
||||||
|
@ -228,52 +228,52 @@ FlipUVsProcess::~FlipUVsProcess()
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FlipUVsProcess::IsActive( unsigned int pFlags) const
|
bool FlipUVsProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
return 0 != (pFlags & aiProcess_FlipUVs);
|
return 0 != (pFlags & aiProcess_FlipUVs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void FlipUVsProcess::Execute( aiScene* pScene)
|
void FlipUVsProcess::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("FlipUVsProcess begin");
|
DefaultLogger::get()->debug("FlipUVsProcess begin");
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
ProcessMesh(pScene->mMeshes[i]);
|
ProcessMesh(pScene->mMeshes[i]);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
|
||||||
ProcessMaterial(pScene->mMaterials[i]);
|
ProcessMaterial(pScene->mMaterials[i]);
|
||||||
DefaultLogger::get()->debug("FlipUVsProcess finished");
|
DefaultLogger::get()->debug("FlipUVsProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts a single material
|
// Converts a single material
|
||||||
void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
|
void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
|
||||||
{
|
{
|
||||||
aiMaterial* mat = (aiMaterial*)_mat;
|
aiMaterial* mat = (aiMaterial*)_mat;
|
||||||
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
||||||
aiMaterialProperty* prop = mat->mProperties[a];
|
aiMaterialProperty* prop = mat->mProperties[a];
|
||||||
if( !prop ) {
|
if( !prop ) {
|
||||||
DefaultLogger::get()->debug( "Property is null" );
|
DefaultLogger::get()->debug( "Property is null" );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UV transformation key?
|
// UV transformation key?
|
||||||
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
|
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
|
||||||
ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
|
ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
|
||||||
aiUVTransform* uv = (aiUVTransform*)prop->mData;
|
aiUVTransform* uv = (aiUVTransform*)prop->mData;
|
||||||
|
|
||||||
// just flip it, that's everything
|
// just flip it, that's everything
|
||||||
uv->mTranslation.y *= -1.f;
|
uv->mTranslation.y *= -1.f;
|
||||||
uv->mRotation *= -1.f;
|
uv->mRotation *= -1.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts a single mesh
|
// Converts a single mesh
|
||||||
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
|
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
// mirror texture y coordinate
|
// mirror texture y coordinate
|
||||||
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
|
||||||
if( !pMesh->HasTextureCoords( a ) ) {
|
if( !pMesh->HasTextureCoords( a ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +281,7 @@ void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
|
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
|
||||||
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
|
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
|
||||||
|
@ -302,30 +302,30 @@ FlipWindingOrderProcess::~FlipWindingOrderProcess()
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
|
bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
return 0 != (pFlags & aiProcess_FlipWindingOrder);
|
return 0 != (pFlags & aiProcess_FlipWindingOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void FlipWindingOrderProcess::Execute( aiScene* pScene)
|
void FlipWindingOrderProcess::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
|
DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
|
||||||
ProcessMesh(pScene->mMeshes[i]);
|
ProcessMesh(pScene->mMeshes[i]);
|
||||||
DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
|
DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Converts a single mesh
|
// Converts a single mesh
|
||||||
void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
|
void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
// invert the order of all faces in this mesh
|
// invert the order of all faces in this mesh
|
||||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||||
{
|
{
|
||||||
aiFace& face = pMesh->mFaces[a];
|
aiFace& face = pMesh->mFaces[a];
|
||||||
for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
|
for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
|
||||||
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
|
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
|
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -57,7 +57,7 @@ struct aiNodeAnim;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMaterial;
|
struct aiMaterial;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
|
/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
|
||||||
|
@ -74,43 +74,43 @@ class MakeLeftHandedProcess : public BaseProcess
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MakeLeftHandedProcess();
|
MakeLeftHandedProcess();
|
||||||
~MakeLeftHandedProcess();
|
~MakeLeftHandedProcess();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Recursively converts a node and all of its children
|
/** Recursively converts a node and all of its children
|
||||||
*/
|
*/
|
||||||
void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
|
void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Converts a single mesh to left handed coordinates.
|
/** Converts a single mesh to left handed coordinates.
|
||||||
* This means that positions, normals and tangents are mirrored at
|
* This means that positions, normals and tangents are mirrored at
|
||||||
* the local Z axis and the order of all faces are inverted.
|
* the local Z axis and the order of all faces are inverted.
|
||||||
* @param pMesh The mesh to convert.
|
* @param pMesh The mesh to convert.
|
||||||
*/
|
*/
|
||||||
void ProcessMesh( aiMesh* pMesh);
|
void ProcessMesh( aiMesh* pMesh);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Converts a single material to left-handed coordinates
|
/** Converts a single material to left-handed coordinates
|
||||||
* @param pMat Material to convert
|
* @param pMat Material to convert
|
||||||
*/
|
*/
|
||||||
void ProcessMaterial( aiMaterial* pMat);
|
void ProcessMaterial( aiMaterial* pMat);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Converts the given animation to LH coordinates.
|
/** Converts the given animation to LH coordinates.
|
||||||
* The rotation and translation keys are transformed, the scale keys
|
* The rotation and translation keys are transformed, the scale keys
|
||||||
* work in local space and can therefore be left untouched.
|
* work in local space and can therefore be left untouched.
|
||||||
* @param pAnim The bone animation to transform
|
* @param pAnim The bone animation to transform
|
||||||
*/
|
*/
|
||||||
void ProcessAnimation( aiNodeAnim* pAnim);
|
void ProcessAnimation( aiNodeAnim* pAnim);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,23 +119,23 @@ protected:
|
||||||
*/
|
*/
|
||||||
class FlipWindingOrderProcess : public BaseProcess
|
class FlipWindingOrderProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor to be privately used by Importer */
|
/** Constructor to be privately used by Importer */
|
||||||
FlipWindingOrderProcess();
|
FlipWindingOrderProcess();
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
~FlipWindingOrderProcess();
|
~FlipWindingOrderProcess();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMesh( aiMesh* pMesh);
|
void ProcessMesh( aiMesh* pMesh);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -143,24 +143,24 @@ protected:
|
||||||
*/
|
*/
|
||||||
class FlipUVsProcess : public BaseProcess
|
class FlipUVsProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
friend class Importer;
|
friend class Importer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Constructor to be privately used by Importer */
|
/** Constructor to be privately used by Importer */
|
||||||
FlipUVsProcess();
|
FlipUVsProcess();
|
||||||
|
|
||||||
/** Destructor, private as well */
|
/** Destructor, private as well */
|
||||||
~FlipUVsProcess();
|
~FlipUVsProcess();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ProcessMesh( aiMesh* pMesh);
|
void ProcessMesh( aiMesh* pMesh);
|
||||||
void ProcessMaterial( aiMaterial* mat);
|
void ProcessMaterial( aiMaterial* mat);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
212
code/DXFHelper.h
212
code/DXFHelper.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/assimp/DefaultLogger.hpp"
|
#include "../include/assimp/DefaultLogger.hpp"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace DXF {
|
namespace DXF {
|
||||||
|
|
||||||
|
|
||||||
// read pairs of lines, parse group code and value and provide utilities
|
// read pairs of lines, parse group code and value and provide utilities
|
||||||
|
@ -63,113 +63,113 @@ class LineReader
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LineReader(StreamReaderLE& reader)
|
LineReader(StreamReaderLE& reader)
|
||||||
// do NOT skip empty lines. In DXF files, they count as valid data.
|
// do NOT skip empty lines. In DXF files, they count as valid data.
|
||||||
: splitter(reader,false,true)
|
: splitter(reader,false,true)
|
||||||
, end()
|
, end()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
bool Is(int gc, const char* what) const {
|
bool Is(int gc, const char* what) const {
|
||||||
return groupcode == gc && !strcmp(what,value.c_str());
|
return groupcode == gc && !strcmp(what,value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
bool Is(int gc) const {
|
bool Is(int gc) const {
|
||||||
return groupcode == gc;
|
return groupcode == gc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int GroupCode() const {
|
int GroupCode() const {
|
||||||
return groupcode;
|
return groupcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
const std::string& Value() const {
|
const std::string& Value() const {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
bool End() const {
|
bool End() const {
|
||||||
return !((bool)*this);
|
return !((bool)*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
unsigned int ValueAsUnsignedInt() const {
|
unsigned int ValueAsUnsignedInt() const {
|
||||||
return strtoul10(value.c_str());
|
return strtoul10(value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
int ValueAsSignedInt() const {
|
int ValueAsSignedInt() const {
|
||||||
return strtol10(value.c_str());
|
return strtol10(value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
float ValueAsFloat() const {
|
float ValueAsFloat() const {
|
||||||
return fast_atof(value.c_str());
|
return fast_atof(value.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
/** pseudo-iterator increment to advance to the next (groupcode/value) pair */
|
/** pseudo-iterator increment to advance to the next (groupcode/value) pair */
|
||||||
LineReader& operator++() {
|
LineReader& operator++() {
|
||||||
if (end) {
|
if (end) {
|
||||||
if (end == 1) {
|
if (end == 1) {
|
||||||
++end;
|
++end;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
groupcode = strtol10(splitter->c_str());
|
groupcode = strtol10(splitter->c_str());
|
||||||
splitter++;
|
splitter++;
|
||||||
|
|
||||||
value = *splitter;
|
value = *splitter;
|
||||||
splitter++;
|
splitter++;
|
||||||
|
|
||||||
// automatically skip over {} meta blocks (these are for application use
|
// automatically skip over {} meta blocks (these are for application use
|
||||||
// and currently not relevant for Assimp).
|
// and currently not relevant for Assimp).
|
||||||
if (value.length() && value[0] == '{') {
|
if (value.length() && value[0] == '{') {
|
||||||
|
|
||||||
size_t cnt = 0;
|
size_t cnt = 0;
|
||||||
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
|
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
|
||||||
|
|
||||||
splitter++;
|
splitter++;
|
||||||
DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
|
DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
|
||||||
}
|
}
|
||||||
} catch(std::logic_error&) {
|
} catch(std::logic_error&) {
|
||||||
ai_assert(!splitter);
|
ai_assert(!splitter);
|
||||||
}
|
}
|
||||||
if (!splitter) {
|
if (!splitter) {
|
||||||
end = 1;
|
end = 1;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
LineReader& operator++(int) {
|
LineReader& operator++(int) {
|
||||||
return ++(*this);
|
return ++(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
operator bool() const {
|
operator bool() const {
|
||||||
return end <= 1;
|
return end <= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
LineSplitter splitter;
|
LineSplitter splitter;
|
||||||
int groupcode;
|
int groupcode;
|
||||||
std::string value;
|
std::string value;
|
||||||
int end;
|
int end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -177,52 +177,52 @@ private:
|
||||||
// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
|
// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
|
||||||
struct PolyLine
|
struct PolyLine
|
||||||
{
|
{
|
||||||
PolyLine()
|
PolyLine()
|
||||||
: flags()
|
: flags()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::vector<aiVector3D> positions;
|
std::vector<aiVector3D> positions;
|
||||||
std::vector<aiColor4D> colors;
|
std::vector<aiColor4D> colors;
|
||||||
std::vector<unsigned int> indices;
|
std::vector<unsigned int> indices;
|
||||||
std::vector<unsigned int> counts;
|
std::vector<unsigned int> counts;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
std::string layer;
|
std::string layer;
|
||||||
std::string desc;
|
std::string desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// reference to a BLOCK. Specifies its own coordinate system.
|
// reference to a BLOCK. Specifies its own coordinate system.
|
||||||
struct InsertBlock
|
struct InsertBlock
|
||||||
{
|
{
|
||||||
InsertBlock()
|
InsertBlock()
|
||||||
: scale(1.f,1.f,1.f)
|
: scale(1.f,1.f,1.f)
|
||||||
, angle()
|
, angle()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
aiVector3D pos;
|
aiVector3D pos;
|
||||||
aiVector3D scale;
|
aiVector3D scale;
|
||||||
float angle;
|
float angle;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// keeps track of all geometry in a single BLOCK.
|
// keeps track of all geometry in a single BLOCK.
|
||||||
struct Block
|
struct Block
|
||||||
{
|
{
|
||||||
std::vector< boost::shared_ptr<PolyLine> > lines;
|
std::vector< boost::shared_ptr<PolyLine> > lines;
|
||||||
std::vector<InsertBlock> insertions;
|
std::vector<InsertBlock> insertions;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
aiVector3D base;
|
aiVector3D base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FileData
|
struct FileData
|
||||||
{
|
{
|
||||||
// note: the LAST block always contains the stuff from ENTITIES.
|
// note: the LAST block always contains the stuff from ENTITIES.
|
||||||
std::vector<Block> blocks;
|
std::vector<Block> blocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
1220
code/DXFLoader.cpp
1220
code/DXFLoader.cpp
File diff suppressed because it is too large
Load Diff
130
code/DXFLoader.h
130
code/DXFLoader.h
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,17 +46,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace DXF {
|
namespace DXF {
|
||||||
|
|
||||||
class LineReader;
|
class LineReader;
|
||||||
struct FileData;
|
struct FileData;
|
||||||
struct PolyLine;
|
struct PolyLine;
|
||||||
struct Block;
|
struct Block;
|
||||||
struct InsertBlock;
|
struct InsertBlock;
|
||||||
|
|
||||||
typedef std::map<std::string, const DXF::Block*> BlockMap;
|
typedef std::map<std::string, const DXF::Block*> BlockMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -66,85 +66,85 @@ namespace Assimp {
|
||||||
class DXFImporter : public BaseImporter
|
class DXFImporter : public BaseImporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DXFImporter();
|
DXFImporter();
|
||||||
~DXFImporter();
|
~DXFImporter();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the class can handle the format of the given file.
|
/** Returns whether the class can handle the format of the given file.
|
||||||
* See BaseImporter::CanRead() for details. */
|
* See BaseImporter::CanRead() for details. */
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
bool checkSig) const;
|
bool checkSig) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Return importer meta information.
|
/** Return importer meta information.
|
||||||
* See #BaseImporter::GetInfo for the details*/
|
* See #BaseImporter::GetInfo for the details*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Imports the given file into the given scene structure.
|
/** Imports the given file into the given scene structure.
|
||||||
* See BaseImporter::InternReadFile() for details */
|
* See BaseImporter::InternReadFile() for details */
|
||||||
void InternReadFile( const std::string& pFile,
|
void InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene,
|
aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void SkipSection(DXF::LineReader& reader);
|
void SkipSection(DXF::LineReader& reader);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParseHeader(DXF::LineReader& reader,
|
void ParseHeader(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParseEntities(DXF::LineReader& reader,
|
void ParseEntities(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParseBlocks(DXF::LineReader& reader,
|
void ParseBlocks(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParseBlock(DXF::LineReader& reader,
|
void ParseBlock(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParseInsertion(DXF::LineReader& reader,
|
void ParseInsertion(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParsePolyLine(DXF::LineReader& reader,
|
void ParsePolyLine(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ParsePolyLineVertex(DXF::LineReader& reader,
|
void ParsePolyLineVertex(DXF::LineReader& reader,
|
||||||
DXF::PolyLine& line);
|
DXF::PolyLine& line);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void Parse3DFace(DXF::LineReader& reader,
|
void Parse3DFace(DXF::LineReader& reader,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ConvertMeshes(aiScene* pScene,
|
void ConvertMeshes(aiScene* pScene,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void GenerateHierarchy(aiScene* pScene,
|
void GenerateHierarchy(aiScene* pScene,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void GenerateMaterials(aiScene* pScene,
|
void GenerateMaterials(aiScene* pScene,
|
||||||
DXF::FileData& output);
|
DXF::FileData& output);
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
void ExpandBlockReferences(DXF::Block& bl,
|
void ExpandBlockReferences(DXF::Block& bl,
|
||||||
const DXF::BlockMap& blocks_by_name);
|
const DXF::BlockMap& blocks_by_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -55,411 +55,411 @@ using namespace Assimp;
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
DeboneProcess::DeboneProcess()
|
DeboneProcess::DeboneProcess()
|
||||||
{
|
{
|
||||||
mNumBones = 0;
|
mNumBones = 0;
|
||||||
mNumBonesCanDoWithout = 0;
|
mNumBonesCanDoWithout = 0;
|
||||||
|
|
||||||
mThreshold = AI_DEBONE_THRESHOLD;
|
mThreshold = AI_DEBONE_THRESHOLD;
|
||||||
mAllOrNone = false;
|
mAllOrNone = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
DeboneProcess::~DeboneProcess()
|
DeboneProcess::~DeboneProcess()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool DeboneProcess::IsActive( unsigned int pFlags) const
|
bool DeboneProcess::IsActive( unsigned int pFlags) const
|
||||||
{
|
{
|
||||||
return (pFlags & aiProcess_Debone) != 0;
|
return (pFlags & aiProcess_Debone) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void DeboneProcess::SetupProperties(const Importer* pImp)
|
void DeboneProcess::SetupProperties(const Importer* pImp)
|
||||||
{
|
{
|
||||||
// get the current value of the property
|
// get the current value of the property
|
||||||
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
|
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
|
||||||
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
|
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Executes the post processing step on the given imported data.
|
// Executes the post processing step on the given imported data.
|
||||||
void DeboneProcess::Execute( aiScene* pScene)
|
void DeboneProcess::Execute( aiScene* pScene)
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->debug("DeboneProcess begin");
|
DefaultLogger::get()->debug("DeboneProcess begin");
|
||||||
|
|
||||||
if(!pScene->mNumMeshes) {
|
if(!pScene->mNumMeshes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<bool> splitList(pScene->mNumMeshes);
|
std::vector<bool> splitList(pScene->mNumMeshes);
|
||||||
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
||||||
splitList[a] = ConsiderMesh( pScene->mMeshes[a] );
|
splitList[a] = ConsiderMesh( pScene->mMeshes[a] );
|
||||||
}
|
}
|
||||||
|
|
||||||
int numSplits = 0;
|
int numSplits = 0;
|
||||||
|
|
||||||
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
|
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
|
||||||
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
|
||||||
if(splitList[a]) {
|
if(splitList[a]) {
|
||||||
numSplits++;
|
numSplits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(numSplits) {
|
if(numSplits) {
|
||||||
// we need to do something. Let's go.
|
// we need to do something. Let's go.
|
||||||
//mSubMeshIndices.clear(); // really needed?
|
//mSubMeshIndices.clear(); // really needed?
|
||||||
mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
|
mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
|
||||||
|
|
||||||
// build a new array of meshes for the scene
|
// build a new array of meshes for the scene
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
|
|
||||||
for(unsigned int a=0;a<pScene->mNumMeshes;a++)
|
for(unsigned int a=0;a<pScene->mNumMeshes;a++)
|
||||||
{
|
{
|
||||||
aiMesh* srcMesh = pScene->mMeshes[a];
|
aiMesh* srcMesh = pScene->mMeshes[a];
|
||||||
|
|
||||||
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
|
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
|
||||||
|
|
||||||
if(splitList[a]) {
|
if(splitList[a]) {
|
||||||
SplitMesh(srcMesh,newMeshes);
|
SplitMesh(srcMesh,newMeshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mesh was split
|
// mesh was split
|
||||||
if(!newMeshes.empty()) {
|
if(!newMeshes.empty()) {
|
||||||
unsigned int out = 0, in = srcMesh->mNumBones;
|
unsigned int out = 0, in = srcMesh->mNumBones;
|
||||||
|
|
||||||
// store new meshes and indices of the new meshes
|
// store new meshes and indices of the new meshes
|
||||||
for(unsigned int b=0;b<newMeshes.size();b++) {
|
for(unsigned int b=0;b<newMeshes.size();b++) {
|
||||||
const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0;
|
const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0;
|
||||||
|
|
||||||
aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0;
|
aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0;
|
||||||
std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode);
|
std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode);
|
||||||
|
|
||||||
mSubMeshIndices[a].push_back(push_pair);
|
mSubMeshIndices[a].push_back(push_pair);
|
||||||
meshes.push_back(newMeshes[b].first);
|
meshes.push_back(newMeshes[b].first);
|
||||||
|
|
||||||
out+=newMeshes[b].first->mNumBones;
|
out+=newMeshes[b].first->mNumBones;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!DefaultLogger::isNullLogger()) {
|
if(!DefaultLogger::isNullLogger()) {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
|
::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
|
||||||
DefaultLogger::get()->info(buffer);
|
DefaultLogger::get()->info(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and destroy the source mesh. It should be completely contained inside the new submeshes
|
// and destroy the source mesh. It should be completely contained inside the new submeshes
|
||||||
delete srcMesh;
|
delete srcMesh;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Mesh is kept unchanged - store it's new place in the mesh array
|
// Mesh is kept unchanged - store it's new place in the mesh array
|
||||||
mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0));
|
mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0));
|
||||||
meshes.push_back(srcMesh);
|
meshes.push_back(srcMesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rebuild the scene's mesh array
|
// rebuild the scene's mesh array
|
||||||
pScene->mNumMeshes = meshes.size();
|
pScene->mNumMeshes = meshes.size();
|
||||||
delete [] pScene->mMeshes;
|
delete [] pScene->mMeshes;
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
|
std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
|
||||||
|
|
||||||
// recurse through all nodes and translate the node's mesh indices to fit the new mesh array
|
// recurse through all nodes and translate the node's mesh indices to fit the new mesh array
|
||||||
UpdateNode( pScene->mRootNode);
|
UpdateNode( pScene->mRootNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->debug("DeboneProcess end");
|
DefaultLogger::get()->debug("DeboneProcess end");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Counts bones total/removable in a given mesh.
|
// Counts bones total/removable in a given mesh.
|
||||||
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
|
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
if(!pMesh->HasBones()) {
|
if(!pMesh->HasBones()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool split = false;
|
bool split = false;
|
||||||
|
|
||||||
//interstitial faces not permitted
|
//interstitial faces not permitted
|
||||||
bool isInterstitialRequired = false;
|
bool isInterstitialRequired = false;
|
||||||
|
|
||||||
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
|
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
|
||||||
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
|
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
|
||||||
|
|
||||||
const unsigned int cUnowned = UINT_MAX;
|
const unsigned int cUnowned = UINT_MAX;
|
||||||
const unsigned int cCoowned = UINT_MAX-1;
|
const unsigned int cCoowned = UINT_MAX-1;
|
||||||
|
|
||||||
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
||||||
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
|
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
|
||||||
float w = pMesh->mBones[i]->mWeights[j].mWeight;
|
float w = pMesh->mBones[i]->mWeights[j].mWeight;
|
||||||
|
|
||||||
if(w==0.0f) {
|
if(w==0.0f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
|
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
|
||||||
if(w>=mThreshold) {
|
if(w>=mThreshold) {
|
||||||
|
|
||||||
if(vertexBones[vid]!=cUnowned) {
|
if(vertexBones[vid]!=cUnowned) {
|
||||||
if(vertexBones[vid]==i) //double entry
|
if(vertexBones[vid]==i) //double entry
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->warn("Encountered double entry in bone weights");
|
DefaultLogger::get()->warn("Encountered double entry in bone weights");
|
||||||
}
|
}
|
||||||
else //TODO: track attraction in order to break tie
|
else //TODO: track attraction in order to break tie
|
||||||
{
|
{
|
||||||
vertexBones[vid] = cCoowned;
|
vertexBones[vid] = cCoowned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else vertexBones[vid] = i;
|
else vertexBones[vid] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isBoneNecessary[i]) {
|
if(!isBoneNecessary[i]) {
|
||||||
isBoneNecessary[i] = w<mThreshold;
|
isBoneNecessary[i] = w<mThreshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isBoneNecessary[i]) {
|
if(!isBoneNecessary[i]) {
|
||||||
isInterstitialRequired = true;
|
isInterstitialRequired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isInterstitialRequired) {
|
if(isInterstitialRequired) {
|
||||||
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
||||||
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
|
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
|
||||||
|
|
||||||
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
|
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
|
||||||
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
|
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
|
||||||
|
|
||||||
if(v!=w) {
|
if(v!=w) {
|
||||||
if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
|
if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
|
||||||
if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
|
if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
||||||
if(!isBoneNecessary[i]) {
|
if(!isBoneNecessary[i]) {
|
||||||
mNumBonesCanDoWithout++;
|
mNumBonesCanDoWithout++;
|
||||||
split = true;
|
split = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mNumBones++;
|
mNumBones++;
|
||||||
}
|
}
|
||||||
return split;
|
return split;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Splits the given mesh by bone count.
|
// Splits the given mesh by bone count.
|
||||||
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
|
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
|
||||||
{
|
{
|
||||||
// same deal here as ConsiderMesh basically
|
// same deal here as ConsiderMesh basically
|
||||||
|
|
||||||
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
|
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
|
||||||
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
|
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
|
||||||
|
|
||||||
const unsigned int cUnowned = UINT_MAX;
|
const unsigned int cUnowned = UINT_MAX;
|
||||||
const unsigned int cCoowned = UINT_MAX-1;
|
const unsigned int cCoowned = UINT_MAX-1;
|
||||||
|
|
||||||
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
||||||
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
|
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
|
||||||
float w = pMesh->mBones[i]->mWeights[j].mWeight;
|
float w = pMesh->mBones[i]->mWeights[j].mWeight;
|
||||||
|
|
||||||
if(w==0.0f) {
|
if(w==0.0f) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
|
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
|
||||||
|
|
||||||
if(w>=mThreshold) {
|
if(w>=mThreshold) {
|
||||||
if(vertexBones[vid]!=cUnowned) {
|
if(vertexBones[vid]!=cUnowned) {
|
||||||
if(vertexBones[vid]==i) //double entry
|
if(vertexBones[vid]==i) //double entry
|
||||||
{
|
{
|
||||||
//DefaultLogger::get()->warn("Encountered double entry in bone weights");
|
//DefaultLogger::get()->warn("Encountered double entry in bone weights");
|
||||||
}
|
}
|
||||||
else //TODO: track attraction in order to break tie
|
else //TODO: track attraction in order to break tie
|
||||||
{
|
{
|
||||||
vertexBones[vid] = cCoowned;
|
vertexBones[vid] = cCoowned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else vertexBones[vid] = i;
|
else vertexBones[vid] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isBoneNecessary[i]) {
|
if(!isBoneNecessary[i]) {
|
||||||
isBoneNecessary[i] = w<mThreshold;
|
isBoneNecessary[i] = w<mThreshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int nFacesUnowned = 0;
|
unsigned int nFacesUnowned = 0;
|
||||||
|
|
||||||
std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX);
|
std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX);
|
||||||
std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0);
|
std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0);
|
||||||
|
|
||||||
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
||||||
unsigned int nInterstitial = 1;
|
unsigned int nInterstitial = 1;
|
||||||
|
|
||||||
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
|
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
|
||||||
|
|
||||||
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
|
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
|
||||||
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
|
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
|
||||||
|
|
||||||
if(v!=w) {
|
if(v!=w) {
|
||||||
if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
|
if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
|
||||||
if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
|
if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
|
||||||
}
|
}
|
||||||
else nInterstitial++;
|
else nInterstitial++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) {
|
if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) {
|
||||||
faceBones[i] = v; //primitive belongs to bone #v
|
faceBones[i] = v; //primitive belongs to bone #v
|
||||||
facesPerBone[v]++;
|
facesPerBone[v]++;
|
||||||
}
|
}
|
||||||
else nFacesUnowned++;
|
else nFacesUnowned++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalidate any "cojoined" faces
|
// invalidate any "cojoined" faces
|
||||||
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
||||||
if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]])
|
if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]])
|
||||||
{
|
{
|
||||||
ai_assert(facesPerBone[faceBones[i]]>0);
|
ai_assert(facesPerBone[faceBones[i]]>0);
|
||||||
facesPerBone[faceBones[i]]--;
|
facesPerBone[faceBones[i]]--;
|
||||||
|
|
||||||
nFacesUnowned++;
|
nFacesUnowned++;
|
||||||
faceBones[i] = cUnowned;
|
faceBones[i] = cUnowned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nFacesUnowned) {
|
if(nFacesUnowned) {
|
||||||
std::vector<unsigned int> subFaces;
|
std::vector<unsigned int> subFaces;
|
||||||
|
|
||||||
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
|
||||||
if(faceBones[i]==cUnowned) {
|
if(faceBones[i]==cUnowned) {
|
||||||
subFaces.push_back(i);
|
subFaces.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0);
|
aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0);
|
||||||
std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0);
|
std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0);
|
||||||
|
|
||||||
poNewMeshes.push_back(push_pair);
|
poNewMeshes.push_back(push_pair);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
for(unsigned int i=0;i<pMesh->mNumBones;i++) {
|
||||||
|
|
||||||
if(!isBoneNecessary[i]&&facesPerBone[i]>0) {
|
if(!isBoneNecessary[i]&&facesPerBone[i]>0) {
|
||||||
std::vector<unsigned int> subFaces;
|
std::vector<unsigned int> subFaces;
|
||||||
|
|
||||||
for(unsigned int j=0;j<pMesh->mNumFaces;j++) {
|
for(unsigned int j=0;j<pMesh->mNumFaces;j++) {
|
||||||
if(faceBones[j]==i) {
|
if(faceBones[j]==i) {
|
||||||
subFaces.push_back(j);
|
subFaces.push_back(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES;
|
unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES;
|
||||||
aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f);
|
aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f);
|
||||||
|
|
||||||
//Lifted from PretransformVertices.cpp
|
//Lifted from PretransformVertices.cpp
|
||||||
ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix);
|
ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix);
|
||||||
std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]);
|
std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]);
|
||||||
|
|
||||||
poNewMeshes.push_back(push_pair);
|
poNewMeshes.push_back(push_pair);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Recursively updates the node's mesh list to account for the changed mesh list
|
// Recursively updates the node's mesh list to account for the changed mesh list
|
||||||
void DeboneProcess::UpdateNode(aiNode* pNode) const
|
void DeboneProcess::UpdateNode(aiNode* pNode) const
|
||||||
{
|
{
|
||||||
// rebuild the node's mesh index list
|
// rebuild the node's mesh index list
|
||||||
|
|
||||||
std::vector<unsigned int> newMeshList;
|
std::vector<unsigned int> newMeshList;
|
||||||
|
|
||||||
// this will require two passes
|
// this will require two passes
|
||||||
|
|
||||||
unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size();
|
unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size();
|
||||||
|
|
||||||
// first pass, look for meshes which have not moved
|
// first pass, look for meshes which have not moved
|
||||||
|
|
||||||
for(unsigned int a=0;a<m;a++) {
|
for(unsigned int a=0;a<m;a++) {
|
||||||
|
|
||||||
unsigned int srcIndex = pNode->mMeshes[a];
|
unsigned int srcIndex = pNode->mMeshes[a];
|
||||||
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
|
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
|
||||||
unsigned int nSubmeshes = subMeshes.size();
|
unsigned int nSubmeshes = subMeshes.size();
|
||||||
|
|
||||||
for(unsigned int b=0;b<nSubmeshes;b++) {
|
for(unsigned int b=0;b<nSubmeshes;b++) {
|
||||||
if(!subMeshes[b].second) {
|
if(!subMeshes[b].second) {
|
||||||
newMeshList.push_back(subMeshes[b].first);
|
newMeshList.push_back(subMeshes[b].first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// second pass, collect deboned meshes
|
// second pass, collect deboned meshes
|
||||||
|
|
||||||
for(unsigned int a=0;a<n;a++)
|
for(unsigned int a=0;a<n;a++)
|
||||||
{
|
{
|
||||||
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
|
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
|
||||||
unsigned int nSubmeshes = subMeshes.size();
|
unsigned int nSubmeshes = subMeshes.size();
|
||||||
|
|
||||||
for(unsigned int b=0;b<nSubmeshes;b++) {
|
for(unsigned int b=0;b<nSubmeshes;b++) {
|
||||||
if(subMeshes[b].second == pNode) {
|
if(subMeshes[b].second == pNode) {
|
||||||
newMeshList.push_back(subMeshes[b].first);
|
newMeshList.push_back(subMeshes[b].first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pNode->mNumMeshes > 0 ) {
|
if( pNode->mNumMeshes > 0 ) {
|
||||||
delete [] pNode->mMeshes; pNode->mMeshes = NULL;
|
delete [] pNode->mMeshes; pNode->mMeshes = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pNode->mNumMeshes = newMeshList.size();
|
pNode->mNumMeshes = newMeshList.size();
|
||||||
|
|
||||||
if(pNode->mNumMeshes) {
|
if(pNode->mNumMeshes) {
|
||||||
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
|
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
|
||||||
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
|
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do that also recursively for all children
|
// do that also recursively for all children
|
||||||
for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
|
for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
|
||||||
UpdateNode( pNode->mChildren[a]);
|
UpdateNode( pNode->mChildren[a]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Apply the node transformation to a mesh
|
// Apply the node transformation to a mesh
|
||||||
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
|
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
|
||||||
{
|
{
|
||||||
// Check whether we need to transform the coordinates at all
|
// Check whether we need to transform the coordinates at all
|
||||||
if (!mat.IsIdentity()) {
|
if (!mat.IsIdentity()) {
|
||||||
|
|
||||||
if (mesh->HasPositions()) {
|
if (mesh->HasPositions()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
mesh->mVertices[i] = mat * mesh->mVertices[i];
|
mesh->mVertices[i] = mat * mesh->mVertices[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
|
if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
|
||||||
aiMatrix4x4 mWorldIT = mat;
|
aiMatrix4x4 mWorldIT = mat;
|
||||||
mWorldIT.Inverse().Transpose();
|
mWorldIT.Inverse().Transpose();
|
||||||
|
|
||||||
// TODO: implement Inverse() for aiMatrix3x3
|
// TODO: implement Inverse() for aiMatrix3x3
|
||||||
aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
|
aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
|
||||||
|
|
||||||
if (mesh->HasNormals()) {
|
if (mesh->HasNormals()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
|
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mesh->HasTangentsAndBitangents()) {
|
if (mesh->HasTangentsAndBitangents()) {
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
|
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
|
||||||
mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
|
mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -55,7 +55,7 @@ namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (!defined AI_DEBONE_THRESHOLD)
|
#if (!defined AI_DEBONE_THRESHOLD)
|
||||||
# define AI_DEBONE_THRESHOLD 1.0f
|
# define AI_DEBONE_THRESHOLD 1.0f
|
||||||
#endif // !! AI_DEBONE_THRESHOLD
|
#endif // !! AI_DEBONE_THRESHOLD
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -68,63 +68,63 @@ class DeboneProcess : public BaseProcess
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DeboneProcess();
|
DeboneProcess();
|
||||||
~DeboneProcess();
|
~DeboneProcess();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns whether the processing step is present in the given flag.
|
/** Returns whether the processing step is present in the given flag.
|
||||||
* @param pFlags The processing flags the importer was called with.
|
* @param pFlags The processing flags the importer was called with.
|
||||||
* A bitwise combination of #aiPostProcessSteps.
|
* A bitwise combination of #aiPostProcessSteps.
|
||||||
* @return true if the process is present in this flag fields,
|
* @return true if the process is present in this flag fields,
|
||||||
* false if not.
|
* false if not.
|
||||||
*/
|
*/
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called prior to ExecuteOnScene().
|
/** Called prior to ExecuteOnScene().
|
||||||
* The function is a request to the process to update its configuration
|
* The function is a request to the process to update its configuration
|
||||||
* basing on the Importer's configuration property list.
|
* basing on the Importer's configuration property list.
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Executes the post processing step on the given imported data.
|
/** Executes the post processing step on the given imported data.
|
||||||
* At the moment a process is not supposed to fail.
|
* At the moment a process is not supposed to fail.
|
||||||
* @param pScene The imported data to work at.
|
* @param pScene The imported data to work at.
|
||||||
*/
|
*/
|
||||||
void Execute( aiScene* pScene);
|
void Execute( aiScene* pScene);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Counts bones total/removable in a given mesh.
|
/** Counts bones total/removable in a given mesh.
|
||||||
* @param pMesh The mesh to process.
|
* @param pMesh The mesh to process.
|
||||||
*/
|
*/
|
||||||
bool ConsiderMesh( const aiMesh* pMesh);
|
bool ConsiderMesh( const aiMesh* pMesh);
|
||||||
|
|
||||||
/// Splits the given mesh by bone count.
|
/// Splits the given mesh by bone count.
|
||||||
/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
|
/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
|
||||||
/// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
|
/// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
|
||||||
void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const;
|
void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const;
|
||||||
|
|
||||||
/// Recursively updates the node's mesh list to account for the changed mesh list
|
/// Recursively updates the node's mesh list to account for the changed mesh list
|
||||||
void UpdateNode(aiNode* pNode) const;
|
void UpdateNode(aiNode* pNode) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Apply transformation to a mesh
|
// Apply transformation to a mesh
|
||||||
void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const;
|
void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Number of bones present in the scene. */
|
/** Number of bones present in the scene. */
|
||||||
unsigned int mNumBones;
|
unsigned int mNumBones;
|
||||||
unsigned int mNumBonesCanDoWithout;
|
unsigned int mNumBonesCanDoWithout;
|
||||||
|
|
||||||
float mThreshold;
|
float mThreshold;
|
||||||
bool mAllOrNone;
|
bool mAllOrNone;
|
||||||
|
|
||||||
/// Per mesh index: Array of indices of the new submeshes.
|
/// Per mesh index: Array of indices of the new submeshes.
|
||||||
std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices;
|
std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -54,62 +54,62 @@ using namespace Assimp;
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
DefaultIOStream::~DefaultIOStream()
|
DefaultIOStream::~DefaultIOStream()
|
||||||
{
|
{
|
||||||
if (mFile) {
|
if (mFile) {
|
||||||
::fclose(mFile);
|
::fclose(mFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
size_t DefaultIOStream::Read(void* pvBuffer,
|
size_t DefaultIOStream::Read(void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount)
|
size_t pCount)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
|
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
|
||||||
return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
|
return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
size_t DefaultIOStream::Write(const void* pvBuffer,
|
size_t DefaultIOStream::Write(const void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount)
|
size_t pCount)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
|
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
|
||||||
return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
|
return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
aiReturn DefaultIOStream::Seek(size_t pOffset,
|
aiReturn DefaultIOStream::Seek(size_t pOffset,
|
||||||
aiOrigin pOrigin)
|
aiOrigin pOrigin)
|
||||||
{
|
{
|
||||||
if (!mFile) {
|
if (!mFile) {
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just to check whether our enum maps one to one with the CRT constants
|
// Just to check whether our enum maps one to one with the CRT constants
|
||||||
BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR &&
|
BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR &&
|
||||||
aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET);
|
aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET);
|
||||||
|
|
||||||
// do the seek
|
// do the seek
|
||||||
return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
|
return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
size_t DefaultIOStream::Tell() const
|
size_t DefaultIOStream::Tell() const
|
||||||
{
|
{
|
||||||
if (!mFile) {
|
if (!mFile) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ::ftell(mFile);
|
return ::ftell(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
size_t DefaultIOStream::FileSize() const
|
size_t DefaultIOStream::FileSize() const
|
||||||
{
|
{
|
||||||
if (! mFile || mFilename.empty()) {
|
if (! mFile || mFilename.empty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SIZE_MAX == cachedSize) {
|
if (SIZE_MAX == cachedSize) {
|
||||||
|
|
||||||
// Although fseek/ftell would allow us to reuse the exising file handle here,
|
// Although fseek/ftell would allow us to reuse the exising file handle here,
|
||||||
// it is generally unsafe because:
|
// it is generally unsafe because:
|
||||||
|
@ -120,28 +120,28 @@ size_t DefaultIOStream::FileSize() const
|
||||||
// See here for details:
|
// See here for details:
|
||||||
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
|
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
|
||||||
#if defined _WIN32 && !defined __GNUC__
|
#if defined _WIN32 && !defined __GNUC__
|
||||||
struct __stat64 fileStat;
|
struct __stat64 fileStat;
|
||||||
int err = _stat64( mFilename.c_str(), &fileStat );
|
int err = _stat64( mFilename.c_str(), &fileStat );
|
||||||
if (0 != err)
|
if (0 != err)
|
||||||
return 0;
|
return 0;
|
||||||
cachedSize = (size_t) (fileStat.st_size);
|
cachedSize = (size_t) (fileStat.st_size);
|
||||||
#else
|
#else
|
||||||
struct stat fileStat;
|
struct stat fileStat;
|
||||||
int err = stat(mFilename.c_str(), &fileStat );
|
int err = stat(mFilename.c_str(), &fileStat );
|
||||||
if (0 != err)
|
if (0 != err)
|
||||||
return 0;
|
return 0;
|
||||||
cachedSize = (size_t) (fileStat.st_size);
|
cachedSize = (size_t) (fileStat.st_size);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return cachedSize;
|
return cachedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
void DefaultIOStream::Flush()
|
void DefaultIOStream::Flush()
|
||||||
{
|
{
|
||||||
if (mFile) {
|
if (mFile) {
|
||||||
::fflush(mFile);
|
::fflush(mFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -47,17 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "../include/assimp/importerdesc.h"
|
#include "../include/assimp/importerdesc.h"
|
||||||
#include "Defines.h"
|
#include "Defines.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
//! @class DefaultIOStream
|
//! @class DefaultIOStream
|
||||||
//! @brief Default IO implementation, use standard IO operations
|
//! @brief Default IO implementation, use standard IO operations
|
||||||
//! @note An instance of this class can exist without a valid file handle
|
//! @note An instance of this class can exist without a valid file handle
|
||||||
//! attached to it. All calls fail, but the instance can nevertheless be
|
//! attached to it. All calls fail, but the instance can nevertheless be
|
||||||
//! used with no restrictions.
|
//! used with no restrictions.
|
||||||
class DefaultIOStream : public IOStream
|
class DefaultIOStream : public IOStream
|
||||||
{
|
{
|
||||||
friend class DefaultIOSystem;
|
friend class DefaultIOSystem;
|
||||||
#if __ANDROID__
|
#if __ANDROID__
|
||||||
#if __ANDROID_API__ > 9
|
#if __ANDROID_API__ > 9
|
||||||
#if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
#if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||||
|
@ -67,72 +67,72 @@ class DefaultIOStream : public IOStream
|
||||||
#endif // __ANDROID__
|
#endif // __ANDROID__
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DefaultIOStream();
|
DefaultIOStream();
|
||||||
DefaultIOStream(FILE* pFile, const std::string &strFilename);
|
DefaultIOStream(FILE* pFile, const std::string &strFilename);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** Destructor public to allow simple deletion to close the file. */
|
/** Destructor public to allow simple deletion to close the file. */
|
||||||
~DefaultIOStream ();
|
~DefaultIOStream ();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Read from stream
|
/// Read from stream
|
||||||
size_t Read(void* pvBuffer,
|
size_t Read(void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount);
|
size_t pCount);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Write to stream
|
/// Write to stream
|
||||||
size_t Write(const void* pvBuffer,
|
size_t Write(const void* pvBuffer,
|
||||||
size_t pSize,
|
size_t pSize,
|
||||||
size_t pCount);
|
size_t pCount);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Seek specific position
|
/// Seek specific position
|
||||||
aiReturn Seek(size_t pOffset,
|
aiReturn Seek(size_t pOffset,
|
||||||
aiOrigin pOrigin);
|
aiOrigin pOrigin);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Get current seek position
|
/// Get current seek position
|
||||||
size_t Tell() const;
|
size_t Tell() const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Get size of file
|
/// Get size of file
|
||||||
size_t FileSize() const;
|
size_t FileSize() const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/// Flush file contents
|
/// Flush file contents
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// File datastructure, using clib
|
// File datastructure, using clib
|
||||||
FILE* mFile;
|
FILE* mFile;
|
||||||
// Filename
|
// Filename
|
||||||
std::string mFilename;
|
std::string mFilename;
|
||||||
|
|
||||||
// Cached file size
|
// Cached file size
|
||||||
mutable size_t cachedSize;
|
mutable size_t cachedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream () :
|
inline DefaultIOStream::DefaultIOStream () :
|
||||||
mFile (NULL),
|
mFile (NULL),
|
||||||
mFilename (""),
|
mFilename (""),
|
||||||
cachedSize (SIZE_MAX)
|
cachedSize (SIZE_MAX)
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
||||||
const std::string &strFilename) :
|
const std::string &strFilename) :
|
||||||
mFile(pFile),
|
mFile(pFile),
|
||||||
mFilename(strFilename),
|
mFilename(strFilename),
|
||||||
cachedSize (SIZE_MAX)
|
cachedSize (SIZE_MAX)
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -60,47 +60,47 @@ using namespace Assimp;
|
||||||
// Constructor.
|
// Constructor.
|
||||||
DefaultIOSystem::DefaultIOSystem()
|
DefaultIOSystem::DefaultIOSystem()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor.
|
// Destructor.
|
||||||
DefaultIOSystem::~DefaultIOSystem()
|
DefaultIOSystem::~DefaultIOSystem()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Tests for the existence of a file at the given path.
|
// Tests for the existence of a file at the given path.
|
||||||
bool DefaultIOSystem::Exists( const char* pFile) const
|
bool DefaultIOSystem::Exists( const char* pFile) const
|
||||||
{
|
{
|
||||||
FILE* file = ::fopen( pFile, "rb");
|
FILE* file = ::fopen( pFile, "rb");
|
||||||
if( !file)
|
if( !file)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
::fclose( file);
|
::fclose( file);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Open a new file with a given path.
|
// Open a new file with a given path.
|
||||||
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != strFile);
|
ai_assert(NULL != strFile);
|
||||||
ai_assert(NULL != strMode);
|
ai_assert(NULL != strMode);
|
||||||
|
|
||||||
FILE* file = ::fopen( strFile, strMode);
|
FILE* file = ::fopen( strFile, strMode);
|
||||||
if( NULL == file)
|
if( NULL == file)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return new DefaultIOStream(file, (std::string) strFile);
|
return new DefaultIOStream(file, (std::string) strFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Closes the given file and releases all resources associated with it.
|
// Closes the given file and releases all resources associated with it.
|
||||||
void DefaultIOSystem::Close( IOStream* pFile)
|
void DefaultIOSystem::Close( IOStream* pFile)
|
||||||
{
|
{
|
||||||
delete pFile;
|
delete pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -108,9 +108,9 @@ void DefaultIOSystem::Close( IOStream* pFile)
|
||||||
char DefaultIOSystem::getOsSeparator() const
|
char DefaultIOSystem::getOsSeparator() const
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
return '/';
|
return '/';
|
||||||
#else
|
#else
|
||||||
return '\\';
|
return '\\';
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,80 +118,80 @@ char DefaultIOSystem::getOsSeparator() const
|
||||||
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
|
// IOSystem default implementation (ComparePaths isn't a pure virtual function)
|
||||||
bool IOSystem::ComparePaths (const char* one, const char* second) const
|
bool IOSystem::ComparePaths (const char* one, const char* second) const
|
||||||
{
|
{
|
||||||
return !ASSIMP_stricmp(one,second);
|
return !ASSIMP_stricmp(one,second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// maximum path length
|
// maximum path length
|
||||||
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||||
#ifdef PATH_MAX
|
#ifdef PATH_MAX
|
||||||
# define PATHLIMIT PATH_MAX
|
# define PATHLIMIT PATH_MAX
|
||||||
#else
|
#else
|
||||||
# define PATHLIMIT 4096
|
# define PATHLIMIT 4096
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Convert a relative path into an absolute path
|
// Convert a relative path into an absolute path
|
||||||
inline void MakeAbsolutePath (const char* in, char* _out)
|
inline void MakeAbsolutePath (const char* in, char* _out)
|
||||||
{
|
{
|
||||||
ai_assert(in && _out);
|
ai_assert(in && _out);
|
||||||
char* ret;
|
char* ret;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ret = ::_fullpath(_out, in,PATHLIMIT);
|
ret = ::_fullpath(_out, in,PATHLIMIT);
|
||||||
#else
|
#else
|
||||||
// use realpath
|
// use realpath
|
||||||
ret = realpath(in, _out);
|
ret = realpath(in, _out);
|
||||||
#endif
|
#endif
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
// preserve the input path, maybe someone else is able to fix
|
// preserve the input path, maybe someone else is able to fix
|
||||||
// the path before it is accessed (e.g. our file system filter)
|
// the path before it is accessed (e.g. our file system filter)
|
||||||
DefaultLogger::get()->warn("Invalid path: "+std::string(in));
|
DefaultLogger::get()->warn("Invalid path: "+std::string(in));
|
||||||
strcpy(_out,in);
|
strcpy(_out,in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// DefaultIOSystem's more specialized implementation
|
// DefaultIOSystem's more specialized implementation
|
||||||
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
|
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
|
||||||
{
|
{
|
||||||
// chances are quite good both paths are formatted identically,
|
// chances are quite good both paths are formatted identically,
|
||||||
// so we can hopefully return here already
|
// so we can hopefully return here already
|
||||||
if( !ASSIMP_stricmp(one,second) )
|
if( !ASSIMP_stricmp(one,second) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
char temp1[PATHLIMIT];
|
char temp1[PATHLIMIT];
|
||||||
char temp2[PATHLIMIT];
|
char temp2[PATHLIMIT];
|
||||||
|
|
||||||
MakeAbsolutePath (one, temp1);
|
MakeAbsolutePath (one, temp1);
|
||||||
MakeAbsolutePath (second, temp2);
|
MakeAbsolutePath (second, temp2);
|
||||||
|
|
||||||
return !ASSIMP_stricmp(temp1,temp2);
|
return !ASSIMP_stricmp(temp1,temp2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string DefaultIOSystem::fileName(std::string path)
|
std::string DefaultIOSystem::fileName(std::string path)
|
||||||
{
|
{
|
||||||
std::string ret = path;
|
std::string ret = path;
|
||||||
std::size_t last = ret.find_last_of("\\/");
|
std::size_t last = ret.find_last_of("\\/");
|
||||||
if (last != std::string::npos) ret = ret.substr(last + 1);
|
if (last != std::string::npos) ret = ret.substr(last + 1);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string DefaultIOSystem::completeBaseName(std::string path)
|
std::string DefaultIOSystem::completeBaseName(std::string path)
|
||||||
{
|
{
|
||||||
std::string ret = fileName(path);
|
std::string ret = fileName(path);
|
||||||
std::size_t pos = ret.find_last_of('.');
|
std::size_t pos = ret.find_last_of('.');
|
||||||
if(pos != ret.npos) ret = ret.substr(0, pos);
|
if(pos != ret.npos) ret = ret.substr(0, pos);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string DefaultIOSystem::absolutePath(std::string path)
|
std::string DefaultIOSystem::absolutePath(std::string path)
|
||||||
{
|
{
|
||||||
std::string ret = path;
|
std::string ret = path;
|
||||||
std::size_t last = ret.find_last_of("\\/");
|
std::size_t last = ret.find_last_of("\\/");
|
||||||
if (last != std::string::npos) ret = ret.substr(0, last);
|
if (last != std::string::npos) ret = ret.substr(0, last);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef PATHLIMIT
|
#undef PATHLIMIT
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -44,53 +44,53 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "../include/assimp/IOSystem.hpp"
|
#include "../include/assimp/IOSystem.hpp"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Default implementation of IOSystem using the standard C file functions */
|
/** Default implementation of IOSystem using the standard C file functions */
|
||||||
class DefaultIOSystem : public IOSystem
|
class DefaultIOSystem : public IOSystem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constructor. */
|
/** Constructor. */
|
||||||
DefaultIOSystem();
|
DefaultIOSystem();
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
~DefaultIOSystem();
|
~DefaultIOSystem();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Tests for the existence of a file at the given path. */
|
/** Tests for the existence of a file at the given path. */
|
||||||
bool Exists( const char* pFile) const;
|
bool Exists( const char* pFile) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the directory separator. */
|
/** Returns the directory separator. */
|
||||||
char getOsSeparator() const;
|
char getOsSeparator() const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Open a new file with a given path. */
|
/** Open a new file with a given path. */
|
||||||
IOStream* Open( const char* pFile, const char* pMode = "rb");
|
IOStream* Open( const char* pFile, const char* pMode = "rb");
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Closes the given file and releases all resources associated with it. */
|
/** Closes the given file and releases all resources associated with it. */
|
||||||
void Close( IOStream* pFile);
|
void Close( IOStream* pFile);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Compare two paths */
|
/** Compare two paths */
|
||||||
bool ComparePaths (const char* one, const char* second) const;
|
bool ComparePaths (const char* one, const char* second) const;
|
||||||
|
|
||||||
/** @brief get the file name of a full filepath
|
/** @brief get the file name of a full filepath
|
||||||
* example: /tmp/archive.tar.gz -> archive.tar.gz
|
* example: /tmp/archive.tar.gz -> archive.tar.gz
|
||||||
*/
|
*/
|
||||||
static std::string fileName(std::string path);
|
static std::string fileName(std::string path);
|
||||||
|
|
||||||
/** @brief get the complete base name of a full filepath
|
/** @brief get the complete base name of a full filepath
|
||||||
* example: /tmp/archive.tar.gz -> archive.tar
|
* example: /tmp/archive.tar.gz -> archive.tar
|
||||||
*/
|
*/
|
||||||
static std::string completeBaseName(std::string path);
|
static std::string completeBaseName(std::string path);
|
||||||
|
|
||||||
/** @brief get the path of a full filepath
|
/** @brief get the path of a full filepath
|
||||||
* example: /tmp/archive.tar.gz -> /tmp/
|
* example: /tmp/archive.tar.gz -> /tmp/
|
||||||
*/
|
*/
|
||||||
static std::string absolutePath(std::string path);
|
static std::string absolutePath(std::string path);
|
||||||
};
|
};
|
||||||
|
|
||||||
} //!ns Assimp
|
} //!ns Assimp
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -56,13 +56,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
# include <boost/thread/thread.hpp>
|
# include <boost/thread/thread.hpp>
|
||||||
# include <boost/thread/mutex.hpp>
|
# include <boost/thread/mutex.hpp>
|
||||||
|
|
||||||
boost::mutex loggerMutex;
|
boost::mutex loggerMutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
NullLogger DefaultLogger::s_pNullLogger;
|
NullLogger DefaultLogger::s_pNullLogger;
|
||||||
|
@ -74,351 +74,347 @@ static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::War
|
||||||
// Represents a log-stream + its error severity
|
// Represents a log-stream + its error severity
|
||||||
struct LogStreamInfo
|
struct LogStreamInfo
|
||||||
{
|
{
|
||||||
unsigned int m_uiErrorSeverity;
|
unsigned int m_uiErrorSeverity;
|
||||||
LogStream *m_pStream;
|
LogStream *m_pStream;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
|
LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
|
||||||
m_uiErrorSeverity( uiErrorSev ),
|
m_uiErrorSeverity( uiErrorSev ),
|
||||||
m_pStream( pStream )
|
m_pStream( pStream )
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~LogStreamInfo()
|
~LogStreamInfo()
|
||||||
{
|
{
|
||||||
delete m_pStream;
|
delete m_pStream;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Construct a default log stream
|
// Construct a default log stream
|
||||||
LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
|
LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
|
||||||
const char* name /*= "AssimpLog.txt"*/,
|
const char* name /*= "AssimpLog.txt"*/,
|
||||||
IOSystem* io /*= NULL*/)
|
IOSystem* io /*= NULL*/)
|
||||||
{
|
{
|
||||||
switch (streams)
|
switch (streams)
|
||||||
{
|
{
|
||||||
// This is a platform-specific feature
|
// This is a platform-specific feature
|
||||||
case aiDefaultLogStream_DEBUGGER:
|
case aiDefaultLogStream_DEBUGGER:
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
return new Win32DebugLogStream();
|
return new Win32DebugLogStream();
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Platform-independent default streams
|
// Platform-independent default streams
|
||||||
case aiDefaultLogStream_STDERR:
|
case aiDefaultLogStream_STDERR:
|
||||||
return new StdOStreamLogStream(std::cerr);
|
return new StdOStreamLogStream(std::cerr);
|
||||||
case aiDefaultLogStream_STDOUT:
|
case aiDefaultLogStream_STDOUT:
|
||||||
return new StdOStreamLogStream(std::cout);
|
return new StdOStreamLogStream(std::cout);
|
||||||
case aiDefaultLogStream_FILE:
|
case aiDefaultLogStream_FILE:
|
||||||
return (name && *name ? new FileLogStream(name,io) : NULL);
|
return (name && *name ? new FileLogStream(name,io) : NULL);
|
||||||
default:
|
default:
|
||||||
// We don't know this default log stream, so raise an assertion
|
// We don't know this default log stream, so raise an assertion
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// For compilers without dead code path detection
|
// For compilers without dead code path detection
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Creates the only singleton instance
|
// Creates the only singleton instance
|
||||||
Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
|
Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
|
||||||
LogSeverity severity /*= NORMAL*/,
|
LogSeverity severity /*= NORMAL*/,
|
||||||
unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
|
unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
|
||||||
IOSystem* io /*= NULL*/)
|
IOSystem* io /*= NULL*/)
|
||||||
{
|
{
|
||||||
// enter the mutex here to avoid concurrency problems
|
// enter the mutex here to avoid concurrency problems
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(loggerMutex);
|
boost::mutex::scoped_lock lock(loggerMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_pLogger && !isNullLogger() )
|
if (m_pLogger && !isNullLogger() )
|
||||||
delete m_pLogger;
|
delete m_pLogger;
|
||||||
|
|
||||||
m_pLogger = new DefaultLogger( severity );
|
m_pLogger = new DefaultLogger( severity );
|
||||||
|
|
||||||
// Attach default log streams
|
// Attach default log streams
|
||||||
// Stream the log to the MSVC debugger?
|
// Stream the log to the MSVC debugger?
|
||||||
if (defStreams & aiDefaultLogStream_DEBUGGER)
|
if (defStreams & aiDefaultLogStream_DEBUGGER)
|
||||||
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
|
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
|
||||||
|
|
||||||
// Stream the log to COUT?
|
// Stream the log to COUT?
|
||||||
if (defStreams & aiDefaultLogStream_STDOUT)
|
if (defStreams & aiDefaultLogStream_STDOUT)
|
||||||
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
|
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
|
||||||
|
|
||||||
// Stream the log to CERR?
|
// Stream the log to CERR?
|
||||||
if (defStreams & aiDefaultLogStream_STDERR)
|
if (defStreams & aiDefaultLogStream_STDERR)
|
||||||
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
|
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
|
||||||
|
|
||||||
// Stream the log to a file
|
// Stream the log to a file
|
||||||
if (defStreams & aiDefaultLogStream_FILE && name && *name)
|
if (defStreams & aiDefaultLogStream_FILE && name && *name)
|
||||||
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
|
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
|
||||||
|
|
||||||
return m_pLogger;
|
return m_pLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
void Logger::debug(const char* message) {
|
void Logger::debug(const char* message) {
|
||||||
|
|
||||||
// SECURITY FIX: otherwise it's easy to produce overruns since
|
// SECURITY FIX: otherwise it's easy to produce overruns since
|
||||||
// sometimes importers will include data from the input file
|
// sometimes importers will include data from the input file
|
||||||
// (i.e. node names) in their messages.
|
// (i.e. node names) in their messages.
|
||||||
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
||||||
ai_assert(false);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
return OnDebug(message);
|
||||||
return OnDebug(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
void Logger::info(const char* message) {
|
void Logger::info(const char* message) {
|
||||||
|
|
||||||
// SECURITY FIX: see above
|
// SECURITY FIX: see above
|
||||||
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
||||||
ai_assert(false);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
return OnInfo(message);
|
||||||
return OnInfo(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
void Logger::warn(const char* message) {
|
void Logger::warn(const char* message) {
|
||||||
|
|
||||||
// SECURITY FIX: see above
|
// SECURITY FIX: see above
|
||||||
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
||||||
ai_assert(false);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
return OnWarn(message);
|
||||||
return OnWarn(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
void Logger::error(const char* message) {
|
void Logger::error(const char* message) {
|
||||||
|
|
||||||
// SECURITY FIX: see above
|
// SECURITY FIX: see above
|
||||||
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
|
||||||
ai_assert(false);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
return OnError(message);
|
||||||
return OnError(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
void DefaultLogger::set( Logger *logger )
|
void DefaultLogger::set( Logger *logger )
|
||||||
{
|
{
|
||||||
// enter the mutex here to avoid concurrency problems
|
// enter the mutex here to avoid concurrency problems
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(loggerMutex);
|
boost::mutex::scoped_lock lock(loggerMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!logger)logger = &s_pNullLogger;
|
if (!logger)logger = &s_pNullLogger;
|
||||||
if (m_pLogger && !isNullLogger() )
|
if (m_pLogger && !isNullLogger() )
|
||||||
delete m_pLogger;
|
delete m_pLogger;
|
||||||
|
|
||||||
DefaultLogger::m_pLogger = logger;
|
DefaultLogger::m_pLogger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
bool DefaultLogger::isNullLogger()
|
bool DefaultLogger::isNullLogger()
|
||||||
{
|
{
|
||||||
return m_pLogger == &s_pNullLogger;
|
return m_pLogger == &s_pNullLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Singleton getter
|
// Singleton getter
|
||||||
Logger *DefaultLogger::get()
|
Logger *DefaultLogger::get()
|
||||||
{
|
{
|
||||||
return m_pLogger;
|
return m_pLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Kills the only instance
|
// Kills the only instance
|
||||||
void DefaultLogger::kill()
|
void DefaultLogger::kill()
|
||||||
{
|
{
|
||||||
// enter the mutex here to avoid concurrency problems
|
// enter the mutex here to avoid concurrency problems
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(loggerMutex);
|
boost::mutex::scoped_lock lock(loggerMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_pLogger == &s_pNullLogger)return;
|
if (m_pLogger == &s_pNullLogger)return;
|
||||||
delete m_pLogger;
|
delete m_pLogger;
|
||||||
m_pLogger = &s_pNullLogger;
|
m_pLogger = &s_pNullLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Debug message
|
// Debug message
|
||||||
void DefaultLogger::OnDebug( const char* message )
|
void DefaultLogger::OnDebug( const char* message )
|
||||||
{
|
{
|
||||||
if ( m_Severity == Logger::NORMAL )
|
if ( m_Severity == Logger::NORMAL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
||||||
::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message );
|
::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message );
|
||||||
|
|
||||||
WriteToStreams( msg, Logger::Debugging );
|
WriteToStreams( msg, Logger::Debugging );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Logs an info
|
// Logs an info
|
||||||
void DefaultLogger::OnInfo( const char* message )
|
void DefaultLogger::OnInfo( const char* message )
|
||||||
{
|
{
|
||||||
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
||||||
::sprintf(msg,"Info, T%u: %s", GetThreadID(), message );
|
::sprintf(msg,"Info, T%u: %s", GetThreadID(), message );
|
||||||
|
|
||||||
WriteToStreams( msg , Logger::Info );
|
WriteToStreams( msg , Logger::Info );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Logs a warning
|
// Logs a warning
|
||||||
void DefaultLogger::OnWarn( const char* message )
|
void DefaultLogger::OnWarn( const char* message )
|
||||||
{
|
{
|
||||||
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
||||||
::sprintf(msg,"Warn, T%u: %s", GetThreadID(), message );
|
::sprintf(msg,"Warn, T%u: %s", GetThreadID(), message );
|
||||||
|
|
||||||
WriteToStreams( msg, Logger::Warn );
|
WriteToStreams( msg, Logger::Warn );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Logs an error
|
// Logs an error
|
||||||
void DefaultLogger::OnError( const char* message )
|
void DefaultLogger::OnError( const char* message )
|
||||||
{
|
{
|
||||||
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
char msg[MAX_LOG_MESSAGE_LENGTH + 16];
|
||||||
::sprintf(msg,"Error, T%u: %s", GetThreadID(), message );
|
::sprintf(msg,"Error, T%u: %s", GetThreadID(), message );
|
||||||
|
|
||||||
WriteToStreams( msg, Logger::Err );
|
WriteToStreams( msg, Logger::Err );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Will attach a new stream
|
// Will attach a new stream
|
||||||
bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
|
bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
|
||||||
{
|
{
|
||||||
if (!pStream)
|
if (!pStream)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (0 == severity) {
|
if (0 == severity) {
|
||||||
severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
|
severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( StreamIt it = m_StreamArray.begin();
|
for ( StreamIt it = m_StreamArray.begin();
|
||||||
it != m_StreamArray.end();
|
it != m_StreamArray.end();
|
||||||
++it )
|
++it )
|
||||||
{
|
{
|
||||||
if ( (*it)->m_pStream == pStream )
|
if ( (*it)->m_pStream == pStream )
|
||||||
{
|
{
|
||||||
(*it)->m_uiErrorSeverity |= severity;
|
(*it)->m_uiErrorSeverity |= severity;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
|
LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
|
||||||
m_StreamArray.push_back( pInfo );
|
m_StreamArray.push_back( pInfo );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Detatch a stream
|
// Detatch a stream
|
||||||
bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
|
bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
|
||||||
{
|
{
|
||||||
if (!pStream)
|
if (!pStream)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (0 == severity) {
|
if (0 == severity) {
|
||||||
severity = SeverityAll;
|
severity = SeverityAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( StreamIt it = m_StreamArray.begin();
|
for ( StreamIt it = m_StreamArray.begin();
|
||||||
it != m_StreamArray.end();
|
it != m_StreamArray.end();
|
||||||
++it )
|
++it )
|
||||||
{
|
{
|
||||||
if ( (*it)->m_pStream == pStream )
|
if ( (*it)->m_pStream == pStream )
|
||||||
{
|
{
|
||||||
(*it)->m_uiErrorSeverity &= ~severity;
|
(*it)->m_uiErrorSeverity &= ~severity;
|
||||||
if ( (*it)->m_uiErrorSeverity == 0 )
|
if ( (*it)->m_uiErrorSeverity == 0 )
|
||||||
{
|
{
|
||||||
// don't delete the underlying stream 'cause the caller gains ownership again
|
// don't delete the underlying stream 'cause the caller gains ownership again
|
||||||
(**it).m_pStream = NULL;
|
(**it).m_pStream = NULL;
|
||||||
delete *it;
|
delete *it;
|
||||||
m_StreamArray.erase( it );
|
m_StreamArray.erase( it );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Constructor
|
// Constructor
|
||||||
DefaultLogger::DefaultLogger(LogSeverity severity)
|
DefaultLogger::DefaultLogger(LogSeverity severity)
|
||||||
|
|
||||||
: Logger ( severity )
|
: Logger ( severity )
|
||||||
, noRepeatMsg (false)
|
, noRepeatMsg (false)
|
||||||
, lastLen( 0 )
|
, lastLen( 0 )
|
||||||
{
|
{
|
||||||
lastMsg[0] = '\0';
|
lastMsg[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Destructor
|
// Destructor
|
||||||
DefaultLogger::~DefaultLogger()
|
DefaultLogger::~DefaultLogger()
|
||||||
{
|
{
|
||||||
for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
|
for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
|
||||||
// also frees the underlying stream, we are its owner.
|
// also frees the underlying stream, we are its owner.
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Writes message to stream
|
// Writes message to stream
|
||||||
void DefaultLogger::WriteToStreams(const char *message,
|
void DefaultLogger::WriteToStreams(const char *message,
|
||||||
ErrorSeverity ErrorSev )
|
ErrorSeverity ErrorSev )
|
||||||
{
|
{
|
||||||
ai_assert(NULL != message);
|
ai_assert(NULL != message);
|
||||||
|
|
||||||
// Check whether this is a repeated message
|
// Check whether this is a repeated message
|
||||||
if (! ::strncmp( message,lastMsg, lastLen-1))
|
if (! ::strncmp( message,lastMsg, lastLen-1))
|
||||||
{
|
{
|
||||||
if (!noRepeatMsg)
|
if (!noRepeatMsg)
|
||||||
{
|
{
|
||||||
noRepeatMsg = true;
|
noRepeatMsg = true;
|
||||||
message = "Skipping one or more lines with the same contents\n";
|
message = "Skipping one or more lines with the same contents\n";
|
||||||
}
|
}
|
||||||
else return;
|
else return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// append a new-line character to the message to be printed
|
// append a new-line character to the message to be printed
|
||||||
lastLen = ::strlen(message);
|
lastLen = ::strlen(message);
|
||||||
::memcpy(lastMsg,message,lastLen+1);
|
::memcpy(lastMsg,message,lastLen+1);
|
||||||
::strcat(lastMsg+lastLen,"\n");
|
::strcat(lastMsg+lastLen,"\n");
|
||||||
|
|
||||||
message = lastMsg;
|
message = lastMsg;
|
||||||
noRepeatMsg = false;
|
noRepeatMsg = false;
|
||||||
++lastLen;
|
++lastLen;
|
||||||
}
|
}
|
||||||
for ( ConstStreamIt it = m_StreamArray.begin();
|
for ( ConstStreamIt it = m_StreamArray.begin();
|
||||||
it != m_StreamArray.end();
|
it != m_StreamArray.end();
|
||||||
++it)
|
++it)
|
||||||
{
|
{
|
||||||
if ( ErrorSev & (*it)->m_uiErrorSeverity )
|
if ( ErrorSev & (*it)->m_uiErrorSeverity )
|
||||||
(*it)->m_pStream->write( message);
|
(*it)->m_pStream->write( message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
// Returns thread id, if not supported only a zero will be returned.
|
// Returns thread id, if not supported only a zero will be returned.
|
||||||
unsigned int DefaultLogger::GetThreadID()
|
unsigned int DefaultLogger::GetThreadID()
|
||||||
{
|
{
|
||||||
// fixme: we can get this value via boost::threads
|
// fixme: we can get this value via boost::threads
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
return (unsigned int)::GetCurrentThreadId();
|
return (unsigned int)::GetCurrentThreadId();
|
||||||
#else
|
#else
|
||||||
return 0; // not supported
|
return 0; // not supported
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -45,17 +45,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
|
#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
|
||||||
|
|
||||||
#include "../include/assimp/ProgressHandler.hpp"
|
#include "../include/assimp/ProgressHandler.hpp"
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
/** @brief Internal default implementation of the #ProgressHandler interface. */
|
/** @brief Internal default implementation of the #ProgressHandler interface. */
|
||||||
class DefaultProgressHandler
|
class DefaultProgressHandler
|
||||||
: public ProgressHandler {
|
: public ProgressHandler {
|
||||||
|
|
||||||
|
|
||||||
virtual bool Update(float /*percentage*/) {
|
virtual bool Update(float /*percentage*/) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}; // !class DefaultProgressHandler
|
}; // !class DefaultProgressHandler
|
||||||
|
|
|
@ -40,10 +40,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// We need those constants, workaround for any platforms where nobody defined them yet
|
// We need those constants, workaround for any platforms where nobody defined them yet
|
||||||
#if (!defined SIZE_MAX)
|
#if (!defined SIZE_MAX)
|
||||||
# define SIZE_MAX (~((size_t)0))
|
# define SIZE_MAX (~((size_t)0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined UINT_MAX)
|
#if (!defined UINT_MAX)
|
||||||
# define UINT_MAX (~((unsigned int)0))
|
# define UINT_MAX (~((unsigned int)0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(disable : 4275)
|
# pragma warning(disable : 4275)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -54,14 +54,14 @@ using std::runtime_error;
|
||||||
* unrecoverable error occurs while importing. Loading APIs return
|
* unrecoverable error occurs while importing. Loading APIs return
|
||||||
* NULL instead of a valid aiScene then. */
|
* NULL instead of a valid aiScene then. */
|
||||||
class DeadlyImportError
|
class DeadlyImportError
|
||||||
: public runtime_error
|
: public runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constructor with arguments */
|
/** Constructor with arguments */
|
||||||
explicit DeadlyImportError( const std::string& pErrorText)
|
explicit DeadlyImportError( const std::string& pErrorText)
|
||||||
: runtime_error(pErrorText)
|
: runtime_error(pErrorText)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
@ -69,57 +69,57 @@ private:
|
||||||
typedef DeadlyImportError DeadlyExportError;
|
typedef DeadlyImportError DeadlyExportError;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(default : 4275)
|
# pragma warning(default : 4275)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ExceptionSwallower {
|
struct ExceptionSwallower {
|
||||||
T operator ()() const {
|
T operator ()() const {
|
||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ExceptionSwallower<T*> {
|
struct ExceptionSwallower<T*> {
|
||||||
T* operator ()() const {
|
T* operator ()() const {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
struct ExceptionSwallower<aiReturn> {
|
struct ExceptionSwallower<aiReturn> {
|
||||||
aiReturn operator ()() const {
|
aiReturn operator ()() const {
|
||||||
try {
|
try {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
catch (std::bad_alloc&) {
|
catch (std::bad_alloc&) {
|
||||||
return aiReturn_OUTOFMEMORY;
|
return aiReturn_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
return aiReturn_FAILURE;
|
return aiReturn_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
template <>
|
template <>
|
||||||
struct ExceptionSwallower<void> {
|
struct ExceptionSwallower<void> {
|
||||||
void operator ()() const {
|
void operator ()() const {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ASSIMP_BEGIN_EXCEPTION_REGION()\
|
#define ASSIMP_BEGIN_EXCEPTION_REGION()\
|
||||||
{\
|
{\
|
||||||
try {
|
try {
|
||||||
|
|
||||||
#define ASSIMP_END_EXCEPTION_REGION(type)\
|
#define ASSIMP_END_EXCEPTION_REGION(type)\
|
||||||
} catch(...) {\
|
} catch(...) {\
|
||||||
return ExceptionSwallower<type>()();\
|
return ExceptionSwallower<type>()();\
|
||||||
}\
|
}\
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // INCLUDED_EXCEPTIONAL_H
|
#endif // INCLUDED_EXCEPTIONAL_H
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -95,52 +95,52 @@ void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportPrope
|
||||||
Exporter::ExportFormatEntry gExporters[] =
|
Exporter::ExportFormatEntry gExporters[] =
|
||||||
{
|
{
|
||||||
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
|
Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_XFILE_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
|
||||||
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
|
aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0),
|
Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
||||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
|
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
Exporter::ExportFormatEntry( "stl", "Stereolithography", "stl" , &ExportSceneSTL,
|
||||||
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
||||||
),
|
),
|
||||||
Exporter::ExportFormatEntry( "stlb", "Stereolithography (binary)", "stl" , &ExportSceneSTLBinary,
|
Exporter::ExportFormatEntry( "stlb", "Stereolithography (binary)", "stl" , &ExportSceneSTLBinary,
|
||||||
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_PreTransformVertices
|
||||||
),
|
),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly,
|
Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly,
|
||||||
aiProcess_PreTransformVertices
|
aiProcess_PreTransformVertices
|
||||||
),
|
),
|
||||||
Exporter::ExportFormatEntry( "plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary,
|
Exporter::ExportFormatEntry( "plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary,
|
||||||
aiProcess_PreTransformVertices
|
aiProcess_PreTransformVertices
|
||||||
),
|
),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
|
Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
|
||||||
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices),
|
aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0),
|
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||||
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0),
|
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0),
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -150,42 +150,42 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||||
class ExporterPimpl {
|
class ExporterPimpl {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ExporterPimpl()
|
ExporterPimpl()
|
||||||
: blob()
|
: blob()
|
||||||
, mIOSystem(new Assimp::DefaultIOSystem())
|
, mIOSystem(new Assimp::DefaultIOSystem())
|
||||||
, mIsDefaultIOHandler(true)
|
, mIsDefaultIOHandler(true)
|
||||||
{
|
{
|
||||||
GetPostProcessingStepInstanceList(mPostProcessingSteps);
|
GetPostProcessingStepInstanceList(mPostProcessingSteps);
|
||||||
|
|
||||||
// grab all builtin exporters
|
// grab all builtin exporters
|
||||||
mExporters.resize(ASSIMP_NUM_EXPORTERS);
|
mExporters.resize(ASSIMP_NUM_EXPORTERS);
|
||||||
std::copy(gExporters,gExporters+ASSIMP_NUM_EXPORTERS,mExporters.begin());
|
std::copy(gExporters,gExporters+ASSIMP_NUM_EXPORTERS,mExporters.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
~ExporterPimpl()
|
~ExporterPimpl()
|
||||||
{
|
{
|
||||||
delete blob;
|
delete blob;
|
||||||
|
|
||||||
// Delete all post-processing plug-ins
|
// Delete all post-processing plug-ins
|
||||||
for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
|
for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
|
||||||
delete mPostProcessingSteps[a];
|
delete mPostProcessingSteps[a];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
aiExportDataBlob* blob;
|
aiExportDataBlob* blob;
|
||||||
boost::shared_ptr< Assimp::IOSystem > mIOSystem;
|
boost::shared_ptr< Assimp::IOSystem > mIOSystem;
|
||||||
bool mIsDefaultIOHandler;
|
bool mIsDefaultIOHandler;
|
||||||
|
|
||||||
/** Post processing steps we can apply at the imported data. */
|
/** Post processing steps we can apply at the imported data. */
|
||||||
std::vector< BaseProcess* > mPostProcessingSteps;
|
std::vector< BaseProcess* > mPostProcessingSteps;
|
||||||
|
|
||||||
/** Last fatal export error */
|
/** Last fatal export error */
|
||||||
std::string mError;
|
std::string mError;
|
||||||
|
|
||||||
/** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
|
/** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
|
||||||
std::vector<Exporter::ExportFormatEntry> mExporters;
|
std::vector<Exporter::ExportFormatEntry> mExporters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,306 +208,306 @@ Exporter :: Exporter()
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Exporter :: ~Exporter()
|
Exporter :: ~Exporter()
|
||||||
{
|
{
|
||||||
FreeBlob();
|
FreeBlob();
|
||||||
|
|
||||||
delete pimpl;
|
delete pimpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter :: SetIOHandler( IOSystem* pIOHandler)
|
void Exporter :: SetIOHandler( IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
pimpl->mIsDefaultIOHandler = !pIOHandler;
|
pimpl->mIsDefaultIOHandler = !pIOHandler;
|
||||||
pimpl->mIOSystem.reset(pIOHandler);
|
pimpl->mIOSystem.reset(pIOHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
IOSystem* Exporter :: GetIOHandler() const
|
IOSystem* Exporter :: GetIOHandler() const
|
||||||
{
|
{
|
||||||
return pimpl->mIOSystem.get();
|
return pimpl->mIOSystem.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool Exporter :: IsDefaultIOHandler() const
|
bool Exporter :: IsDefaultIOHandler() const
|
||||||
{
|
{
|
||||||
return pimpl->mIsDefaultIOHandler;
|
return pimpl->mIsDefaultIOHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int, const ExportProperties* pProperties)
|
const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const char* pFormatId, unsigned int, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
if (pimpl->blob) {
|
if (pimpl->blob) {
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
pimpl->blob = NULL;
|
pimpl->blob = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boost::shared_ptr<IOSystem> old = pimpl->mIOSystem;
|
boost::shared_ptr<IOSystem> old = pimpl->mIOSystem;
|
||||||
|
|
||||||
BlobIOSystem* blobio = new BlobIOSystem();
|
BlobIOSystem* blobio = new BlobIOSystem();
|
||||||
pimpl->mIOSystem = boost::shared_ptr<IOSystem>( blobio );
|
pimpl->mIOSystem = boost::shared_ptr<IOSystem>( blobio );
|
||||||
|
|
||||||
if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
|
if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
|
||||||
pimpl->mIOSystem = old;
|
pimpl->mIOSystem = old;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pimpl->blob = blobio->GetBlobChain();
|
pimpl->blob = blobio->GetBlobChain();
|
||||||
pimpl->mIOSystem = old;
|
pimpl->mIOSystem = old;
|
||||||
|
|
||||||
return pimpl->blob;
|
return pimpl->blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool IsVerboseFormat(const aiMesh* mesh)
|
bool IsVerboseFormat(const aiMesh* mesh)
|
||||||
{
|
{
|
||||||
// avoid slow vector<bool> specialization
|
// avoid slow vector<bool> specialization
|
||||||
std::vector<unsigned int> seen(mesh->mNumVertices,0);
|
std::vector<unsigned int> seen(mesh->mNumVertices,0);
|
||||||
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
||||||
const aiFace& f = mesh->mFaces[i];
|
const aiFace& f = mesh->mFaces[i];
|
||||||
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
|
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
|
||||||
if(++seen[f.mIndices[j]] == 2) {
|
if(++seen[f.mIndices[j]] == 2) {
|
||||||
// found a duplicate index
|
// found a duplicate index
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool IsVerboseFormat(const aiScene* pScene)
|
bool IsVerboseFormat(const aiScene* pScene)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
if(!IsVerboseFormat(pScene->mMeshes[i])) {
|
if(!IsVerboseFormat(pScene->mMeshes[i])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
|
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
// when they create scenes from scratch, users will likely create them not in verbose
|
// when they create scenes from scratch, users will likely create them not in verbose
|
||||||
// format. They will likely not be aware that there is a flag in the scene to indicate
|
// format. They will likely not be aware that there is a flag in the scene to indicate
|
||||||
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
||||||
// meshes upfront.
|
// meshes upfront.
|
||||||
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
||||||
|
|
||||||
pimpl->mError = "";
|
pimpl->mError = "";
|
||||||
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
||||||
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
|
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
|
||||||
if (!strcmp(exp.mDescription.id,pFormatId)) {
|
if (!strcmp(exp.mDescription.id,pFormatId)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Always create a full copy of the scene. We might optimize this one day,
|
// Always create a full copy of the scene. We might optimize this one day,
|
||||||
// but for now it is the most pragmatic way.
|
// but for now it is the most pragmatic way.
|
||||||
aiScene* scenecopy_tmp;
|
aiScene* scenecopy_tmp;
|
||||||
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
||||||
|
|
||||||
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
|
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
|
||||||
const ScenePrivateData* const priv = ScenePriv(pScene);
|
const ScenePrivateData* const priv = ScenePriv(pScene);
|
||||||
|
|
||||||
// steps that are not idempotent, i.e. we might need to run them again, usually to get back to the
|
// steps that are not idempotent, i.e. we might need to run them again, usually to get back to the
|
||||||
// original state before the step was applied first. When checking which steps we don't need
|
// original state before the step was applied first. When checking which steps we don't need
|
||||||
// to run, those are excluded.
|
// to run, those are excluded.
|
||||||
const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
|
const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
|
||||||
|
|
||||||
// Erase all pp steps that were already applied to this scene
|
// Erase all pp steps that were already applied to this scene
|
||||||
const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy
|
const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy
|
||||||
? (priv->mPPStepsApplied & ~nonIdempotentSteps)
|
? (priv->mPPStepsApplied & ~nonIdempotentSteps)
|
||||||
: 0u);
|
: 0u);
|
||||||
|
|
||||||
// If no extra postprocessing was specified, and we obtained this scene from an
|
// If no extra postprocessing was specified, and we obtained this scene from an
|
||||||
// Assimp importer, apply the reverse steps automatically.
|
// Assimp importer, apply the reverse steps automatically.
|
||||||
// TODO: either drop this, or document it. Otherwise it is just a bad surprise.
|
// TODO: either drop this, or document it. Otherwise it is just a bad surprise.
|
||||||
//if (!pPreprocessing && priv) {
|
//if (!pPreprocessing && priv) {
|
||||||
// pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
// pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
||||||
// we need to run the MakeVerboseFormat step first.
|
// we need to run the MakeVerboseFormat step first.
|
||||||
bool must_join_again = false;
|
bool must_join_again = false;
|
||||||
if (!is_verbose_format) {
|
if (!is_verbose_format) {
|
||||||
|
|
||||||
bool verbosify = false;
|
bool verbosify = false;
|
||||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||||
BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
||||||
|
|
||||||
if (p->IsActive(pp) && p->RequireVerboseFormat()) {
|
if (p->IsActive(pp) && p->RequireVerboseFormat()) {
|
||||||
verbosify = true;
|
verbosify = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
||||||
DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
|
DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
|
||||||
|
|
||||||
MakeVerboseFormatProcess proc;
|
MakeVerboseFormatProcess proc;
|
||||||
proc.Execute(scenecopy.get());
|
proc.Execute(scenecopy.get());
|
||||||
|
|
||||||
if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
|
||||||
must_join_again = true;
|
must_join_again = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pp) {
|
if (pp) {
|
||||||
// the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
|
// the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
|
||||||
{
|
{
|
||||||
FlipWindingOrderProcess step;
|
FlipWindingOrderProcess step;
|
||||||
if (step.IsActive(pp)) {
|
if (step.IsActive(pp)) {
|
||||||
step.Execute(scenecopy.get());
|
step.Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
FlipUVsProcess step;
|
FlipUVsProcess step;
|
||||||
if (step.IsActive(pp)) {
|
if (step.IsActive(pp)) {
|
||||||
step.Execute(scenecopy.get());
|
step.Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
MakeLeftHandedProcess step;
|
MakeLeftHandedProcess step;
|
||||||
if (step.IsActive(pp)) {
|
if (step.IsActive(pp)) {
|
||||||
step.Execute(scenecopy.get());
|
step.Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dispatch other processes
|
// dispatch other processes
|
||||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||||
BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
||||||
|
|
||||||
if (p->IsActive(pp)
|
if (p->IsActive(pp)
|
||||||
&& !dynamic_cast<FlipUVsProcess*>(p)
|
&& !dynamic_cast<FlipUVsProcess*>(p)
|
||||||
&& !dynamic_cast<FlipWindingOrderProcess*>(p)
|
&& !dynamic_cast<FlipWindingOrderProcess*>(p)
|
||||||
&& !dynamic_cast<MakeLeftHandedProcess*>(p)) {
|
&& !dynamic_cast<MakeLeftHandedProcess*>(p)) {
|
||||||
|
|
||||||
p->Execute(scenecopy.get());
|
p->Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
|
ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
|
||||||
ai_assert(privOut);
|
ai_assert(privOut);
|
||||||
|
|
||||||
privOut->mPPStepsApplied |= pp;
|
privOut->mPPStepsApplied |= pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(must_join_again) {
|
if(must_join_again) {
|
||||||
JoinVerticesProcess proc;
|
JoinVerticesProcess proc;
|
||||||
proc.Execute(scenecopy.get());
|
proc.Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
|
ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
|
||||||
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
|
exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
|
||||||
}
|
}
|
||||||
catch (DeadlyExportError& err) {
|
catch (DeadlyExportError& err) {
|
||||||
pimpl->mError = err.what();
|
pimpl->mError = err.what();
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
|
pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
|
||||||
ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
ASSIMP_END_EXCEPTION_REGION(aiReturn);
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const char* Exporter :: GetErrorString() const
|
const char* Exporter :: GetErrorString() const
|
||||||
{
|
{
|
||||||
return pimpl->mError.c_str();
|
return pimpl->mError.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter :: FreeBlob( )
|
void Exporter :: FreeBlob( )
|
||||||
{
|
{
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
pimpl->blob = NULL;
|
pimpl->blob = NULL;
|
||||||
|
|
||||||
pimpl->mError = "";
|
pimpl->mError = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter :: GetBlob() const
|
const aiExportDataBlob* Exporter :: GetBlob() const
|
||||||
{
|
{
|
||||||
return pimpl->blob;
|
return pimpl->blob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportDataBlob* Exporter :: GetOrphanedBlob() const
|
const aiExportDataBlob* Exporter :: GetOrphanedBlob() const
|
||||||
{
|
{
|
||||||
const aiExportDataBlob* tmp = pimpl->blob;
|
const aiExportDataBlob* tmp = pimpl->blob;
|
||||||
pimpl->blob = NULL;
|
pimpl->blob = NULL;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
size_t Exporter :: GetExportFormatCount() const
|
size_t Exporter :: GetExportFormatCount() const
|
||||||
{
|
{
|
||||||
return pimpl->mExporters.size();
|
return pimpl->mExporters.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const aiExportFormatDesc* Exporter :: GetExportFormatDescription( size_t pIndex ) const
|
const aiExportFormatDesc* Exporter :: GetExportFormatDescription( size_t pIndex ) const
|
||||||
{
|
{
|
||||||
if (pIndex >= GetExportFormatCount()) {
|
if (pIndex >= GetExportFormatCount()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return from static storage if the requested index is built-in.
|
// Return from static storage if the requested index is built-in.
|
||||||
if (pIndex < sizeof(gExporters) / sizeof(gExporters[0])) {
|
if (pIndex < sizeof(gExporters) / sizeof(gExporters[0])) {
|
||||||
return &gExporters[pIndex].mDescription;
|
return &gExporters[pIndex].mDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &pimpl->mExporters[pIndex].mDescription;
|
return &pimpl->mExporters[pIndex].mDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiReturn Exporter :: RegisterExporter(const ExportFormatEntry& desc)
|
aiReturn Exporter :: RegisterExporter(const ExportFormatEntry& desc)
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(const ExportFormatEntry& e, pimpl->mExporters) {
|
BOOST_FOREACH(const ExportFormatEntry& e, pimpl->mExporters) {
|
||||||
if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
|
if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
|
||||||
return aiReturn_FAILURE;
|
return aiReturn_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pimpl->mExporters.push_back(desc);
|
pimpl->mExporters.push_back(desc);
|
||||||
return aiReturn_SUCCESS;
|
return aiReturn_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter :: UnregisterExporter(const char* id)
|
void Exporter :: UnregisterExporter(const char* id)
|
||||||
{
|
{
|
||||||
for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
|
for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
|
||||||
if (!strcmp((*it).mDescription.id,id)) {
|
if (!strcmp((*it).mDescription.id,id)) {
|
||||||
pimpl->mExporters.erase(it);
|
pimpl->mExporters.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportProperties :: ExportProperties() {}
|
ExportProperties :: ExportProperties() {}
|
||||||
|
|
||||||
ExportProperties::ExportProperties(const ExportProperties &other)
|
ExportProperties::ExportProperties(const ExportProperties &other)
|
||||||
: mIntProperties(other.mIntProperties),
|
: mIntProperties(other.mIntProperties),
|
||||||
mFloatProperties(other.mFloatProperties),
|
mFloatProperties(other.mFloatProperties),
|
||||||
mStringProperties(other.mStringProperties),
|
mStringProperties(other.mStringProperties),
|
||||||
mMatrixProperties(other.mMatrixProperties)
|
mMatrixProperties(other.mMatrixProperties)
|
||||||
|
@ -520,95 +520,95 @@ ExportProperties::ExportProperties(const ExportProperties &other)
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool ExportProperties :: SetPropertyInteger(const char* szName, int iValue)
|
bool ExportProperties :: SetPropertyInteger(const char* szName, int iValue)
|
||||||
{
|
{
|
||||||
return SetGenericProperty<int>(mIntProperties, szName,iValue);
|
return SetGenericProperty<int>(mIntProperties, szName,iValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool ExportProperties :: SetPropertyFloat(const char* szName, float iValue)
|
bool ExportProperties :: SetPropertyFloat(const char* szName, float iValue)
|
||||||
{
|
{
|
||||||
return SetGenericProperty<float>(mFloatProperties, szName,iValue);
|
return SetGenericProperty<float>(mFloatProperties, szName,iValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value)
|
bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value)
|
||||||
{
|
{
|
||||||
return SetGenericProperty<std::string>(mStringProperties, szName,value);
|
return SetGenericProperty<std::string>(mStringProperties, szName,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Set a configuration property
|
// Set a configuration property
|
||||||
bool ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
|
bool ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
|
||||||
{
|
{
|
||||||
return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value);
|
return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a configuration property
|
// Get a configuration property
|
||||||
int ExportProperties :: GetPropertyInteger(const char* szName,
|
int ExportProperties :: GetPropertyInteger(const char* szName,
|
||||||
int iErrorReturn /*= 0xffffffff*/) const
|
int iErrorReturn /*= 0xffffffff*/) const
|
||||||
{
|
{
|
||||||
return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
|
return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a configuration property
|
// Get a configuration property
|
||||||
float ExportProperties :: GetPropertyFloat(const char* szName,
|
float ExportProperties :: GetPropertyFloat(const char* szName,
|
||||||
float iErrorReturn /*= 10e10*/) const
|
float iErrorReturn /*= 10e10*/) const
|
||||||
{
|
{
|
||||||
return GetGenericProperty<float>(mFloatProperties,szName,iErrorReturn);
|
return GetGenericProperty<float>(mFloatProperties,szName,iErrorReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Get a configuration property
|
// Get a configuration property
|
||||||
const std::string ExportProperties :: GetPropertyString(const char* szName,
|
const std::string ExportProperties :: GetPropertyString(const char* szName,
|
||||||
const std::string& iErrorReturn /*= ""*/) const
|
const std::string& iErrorReturn /*= ""*/) const
|
||||||
{
|
{
|
||||||
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
|
return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Has a configuration property
|
// Has a configuration property
|
||||||
const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName,
|
const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName,
|
||||||
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
|
const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
|
||||||
{
|
{
|
||||||
return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
|
return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Has a configuration property
|
// Has a configuration property
|
||||||
bool ExportProperties :: HasPropertyInteger(const char* szName) const
|
bool ExportProperties :: HasPropertyInteger(const char* szName) const
|
||||||
{
|
{
|
||||||
return HasGenericProperty<int>(mIntProperties, szName);
|
return HasGenericProperty<int>(mIntProperties, szName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Has a configuration property
|
// Has a configuration property
|
||||||
bool ExportProperties :: HasPropertyBool(const char* szName) const
|
bool ExportProperties :: HasPropertyBool(const char* szName) const
|
||||||
{
|
{
|
||||||
return HasGenericProperty<int>(mIntProperties, szName);
|
return HasGenericProperty<int>(mIntProperties, szName);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Has a configuration property
|
// Has a configuration property
|
||||||
bool ExportProperties :: HasPropertyFloat(const char* szName) const
|
bool ExportProperties :: HasPropertyFloat(const char* szName) const
|
||||||
{
|
{
|
||||||
return HasGenericProperty<float>(mFloatProperties, szName);
|
return HasGenericProperty<float>(mFloatProperties, szName);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Has a configuration property
|
// Has a configuration property
|
||||||
bool ExportProperties :: HasPropertyString(const char* szName) const
|
bool ExportProperties :: HasPropertyString(const char* szName) const
|
||||||
{
|
{
|
||||||
return HasGenericProperty<std::string>(mStringProperties, szName);
|
return HasGenericProperty<std::string>(mStringProperties, szName);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Has a configuration property
|
// Has a configuration property
|
||||||
bool ExportProperties :: HasPropertyMatrix(const char* szName) const
|
bool ExportProperties :: HasPropertyMatrix(const char* szName) const
|
||||||
{
|
{
|
||||||
return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
|
return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -56,37 +56,37 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
using namespace Util;
|
using namespace Util;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
|
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
{
|
{
|
||||||
const Scope& sc = GetRequiredScope(element);
|
const Scope& sc = GetRequiredScope(element);
|
||||||
const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
|
const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
|
||||||
const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
|
const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
|
||||||
|
|
||||||
ParseVectorDataArray(keys, KeyTime);
|
ParseVectorDataArray(keys, KeyTime);
|
||||||
ParseVectorDataArray(values, KeyValueFloat);
|
ParseVectorDataArray(values, KeyValueFloat);
|
||||||
|
|
||||||
if(keys.size() != values.size()) {
|
if(keys.size() != values.size()) {
|
||||||
DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
|
DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the key times are well-ordered
|
// check if the key times are well-ordered
|
||||||
if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
|
if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
|
||||||
DOMError("the keyframes are not in ascending order",&KeyTime);
|
DOMError("the keyframes are not in ascending order",&KeyTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
|
const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
|
||||||
if(KeyAttrDataFloat) {
|
if(KeyAttrDataFloat) {
|
||||||
ParseVectorDataArray(attributes, *KeyAttrDataFloat);
|
ParseVectorDataArray(attributes, *KeyAttrDataFloat);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Element* KeyAttrFlags = sc["KeyAttrFlags"];
|
const Element* KeyAttrFlags = sc["KeyAttrFlags"];
|
||||||
if(KeyAttrFlags) {
|
if(KeyAttrFlags) {
|
||||||
ParseVectorDataArray(flags, *KeyAttrFlags);
|
ParseVectorDataArray(flags, *KeyAttrFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,61 +99,61 @@ AnimationCurve::~AnimationCurve()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||||
const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
|
const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
, target()
|
, target()
|
||||||
, doc(doc)
|
, doc(doc)
|
||||||
{
|
{
|
||||||
const Scope& sc = GetRequiredScope(element);
|
const Scope& sc = GetRequiredScope(element);
|
||||||
|
|
||||||
// find target node
|
// find target node
|
||||||
const char* whitelist[] = {"Model","NodeAttribute"};
|
const char* whitelist[] = {"Model","NodeAttribute"};
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
|
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
|
||||||
|
|
||||||
BOOST_FOREACH(const Connection* con, conns) {
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
// link should go for a property
|
// link should go for a property
|
||||||
if (!con->PropertyName().length()) {
|
if (!con->PropertyName().length()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target_prop_whitelist) {
|
if(target_prop_whitelist) {
|
||||||
const char* const s = con->PropertyName().c_str();
|
const char* const s = con->PropertyName().c_str();
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
for (size_t i = 0; i < whitelist_size; ++i) {
|
for (size_t i = 0; i < whitelist_size; ++i) {
|
||||||
if (!strcmp(s, target_prop_whitelist[i])) {
|
if (!strcmp(s, target_prop_whitelist[i])) {
|
||||||
ok = true;
|
ok = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throw std::range_error("AnimationCurveNode target property is not in whitelist");
|
throw std::range_error("AnimationCurveNode target property is not in whitelist");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Object* const ob = con->DestinationObject();
|
const Object* const ob = con->DestinationObject();
|
||||||
if(!ob) {
|
if(!ob) {
|
||||||
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
|
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX support constraints as DOM class
|
// XXX support constraints as DOM class
|
||||||
//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
|
//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
|
||||||
target = ob;
|
target = ob;
|
||||||
if(!target) {
|
if(!target) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
prop = con->PropertyName();
|
prop = con->PropertyName();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!target) {
|
if(!target) {
|
||||||
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
|
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
|
||||||
}
|
}
|
||||||
|
|
||||||
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,34 +167,34 @@ AnimationCurveNode::~AnimationCurveNode()
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
const AnimationCurveMap& AnimationCurveNode::Curves() const
|
||||||
{
|
{
|
||||||
if(curves.empty()) {
|
if(curves.empty()) {
|
||||||
// resolve attached animation curves
|
// resolve attached animation curves
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
|
||||||
|
|
||||||
BOOST_FOREACH(const Connection* con, conns) {
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
// link should go for a property
|
// link should go for a property
|
||||||
if (!con->PropertyName().length()) {
|
if (!con->PropertyName().length()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Object* const ob = con->SourceObject();
|
const Object* const ob = con->SourceObject();
|
||||||
if(!ob) {
|
if(!ob) {
|
||||||
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
|
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
|
const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
|
||||||
if(!anim) {
|
if(!anim) {
|
||||||
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
|
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
curves[con->PropertyName()] = anim;
|
curves[con->PropertyName()] = anim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return curves;
|
return curves;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,10 +203,10 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::s
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
, doc(doc)
|
, doc(doc)
|
||||||
{
|
{
|
||||||
const Scope& sc = GetRequiredScope(element);
|
const Scope& sc = GetRequiredScope(element);
|
||||||
|
|
||||||
// note: the props table here bears little importance and is usually absent
|
// note: the props table here bears little importance and is usually absent
|
||||||
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
|
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -219,85 +219,85 @@ AnimationLayer::~AnimationLayer()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
|
||||||
size_t whitelist_size /*= 0*/) const
|
size_t whitelist_size /*= 0*/) const
|
||||||
{
|
{
|
||||||
AnimationCurveNodeList nodes;
|
AnimationCurveNodeList nodes;
|
||||||
|
|
||||||
// resolve attached animation nodes
|
// resolve attached animation nodes
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
|
||||||
nodes.reserve(conns.size());
|
nodes.reserve(conns.size());
|
||||||
|
|
||||||
BOOST_FOREACH(const Connection* con, conns) {
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
// link should not go to a property
|
// link should not go to a property
|
||||||
if (con->PropertyName().length()) {
|
if (con->PropertyName().length()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Object* const ob = con->SourceObject();
|
const Object* const ob = con->SourceObject();
|
||||||
if(!ob) {
|
if(!ob) {
|
||||||
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
|
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
|
const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
|
||||||
if(!anim) {
|
if(!anim) {
|
||||||
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
|
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(target_prop_whitelist) {
|
if(target_prop_whitelist) {
|
||||||
const char* s = anim->TargetProperty().c_str();
|
const char* s = anim->TargetProperty().c_str();
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
for (size_t i = 0; i < whitelist_size; ++i) {
|
for (size_t i = 0; i < whitelist_size; ++i) {
|
||||||
if (!strcmp(s, target_prop_whitelist[i])) {
|
if (!strcmp(s, target_prop_whitelist[i])) {
|
||||||
ok = true;
|
ok = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!ok) {
|
if(!ok) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nodes.push_back(anim);
|
nodes.push_back(anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes; // pray for NRVO
|
return nodes; // pray for NRVO
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||||
: Object(id, element, name)
|
: Object(id, element, name)
|
||||||
{
|
{
|
||||||
const Scope& sc = GetRequiredScope(element);
|
const Scope& sc = GetRequiredScope(element);
|
||||||
|
|
||||||
// note: we don't currently use any of these properties so we shouldn't bother if it is missing
|
// note: we don't currently use any of these properties so we shouldn't bother if it is missing
|
||||||
props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
|
props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
|
||||||
|
|
||||||
// resolve attached animation layers
|
// resolve attached animation layers
|
||||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
|
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
|
||||||
layers.reserve(conns.size());
|
layers.reserve(conns.size());
|
||||||
|
|
||||||
BOOST_FOREACH(const Connection* con, conns) {
|
BOOST_FOREACH(const Connection* con, conns) {
|
||||||
|
|
||||||
// link should not go to a property
|
// link should not go to a property
|
||||||
if (con->PropertyName().length()) {
|
if (con->PropertyName().length()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Object* const ob = con->SourceObject();
|
const Object* const ob = con->SourceObject();
|
||||||
if(!ob) {
|
if(!ob) {
|
||||||
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
|
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
|
const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
|
||||||
if(!anim) {
|
if(!anim) {
|
||||||
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
|
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
layers.push_back(anim);
|
layers.push_back(anim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2015, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -58,22 +58,22 @@ namespace FBX {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
|
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
|
||||||
:
|
:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
contents(sbegin, static_cast<size_t>(send-sbegin)),
|
contents(sbegin, static_cast<size_t>(send-sbegin)),
|
||||||
#endif
|
#endif
|
||||||
sbegin(sbegin)
|
sbegin(sbegin)
|
||||||
, send(send)
|
, send(send)
|
||||||
, type(type)
|
, type(type)
|
||||||
, line(offset)
|
, line(offset)
|
||||||
, column(BINARY_MARKER)
|
, column(BINARY_MARKER)
|
||||||
{
|
{
|
||||||
ai_assert(sbegin);
|
ai_assert(sbegin);
|
||||||
ai_assert(send);
|
ai_assert(send);
|
||||||
|
|
||||||
// binary tokens may have zero length because they are sometimes dummies
|
// binary tokens may have zero length because they are sometimes dummies
|
||||||
// inserted by TokenizeBinary()
|
// inserted by TokenizeBinary()
|
||||||
ai_assert(send >= sbegin);
|
ai_assert(send >= sbegin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -84,85 +84,85 @@ namespace {
|
||||||
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX;
|
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX;
|
||||||
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset)
|
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
|
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
uint32_t Offset(const char* begin, const char* cursor)
|
uint32_t Offset(const char* begin, const char* cursor)
|
||||||
{
|
{
|
||||||
ai_assert(begin <= cursor);
|
ai_assert(begin <= cursor);
|
||||||
return static_cast<unsigned int>(cursor - begin);
|
return static_cast<unsigned int>(cursor - begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TokenizeError(const std::string& message, const char* begin, const char* cursor)
|
void TokenizeError(const std::string& message, const char* begin, const char* cursor)
|
||||||
{
|
{
|
||||||
TokenizeError(message, Offset(begin, cursor));
|
TokenizeError(message, Offset(begin, cursor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
|
uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
|
||||||
{
|
{
|
||||||
if(Offset(cursor, end) < 4) {
|
if(Offset(cursor, end) < 4) {
|
||||||
TokenizeError("cannot ReadWord, out of bounds",input, cursor);
|
TokenizeError("cannot ReadWord, out of bounds",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
|
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
|
||||||
AI_SWAP4(word);
|
AI_SWAP4(word);
|
||||||
|
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
|
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
|
uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
|
||||||
{
|
{
|
||||||
if(Offset(cursor, end) < 1) {
|
if(Offset(cursor, end) < 1) {
|
||||||
TokenizeError("cannot ReadByte, out of bounds",input, cursor);
|
TokenizeError("cannot ReadByte, out of bounds",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
|
uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
|
||||||
++cursor;
|
++cursor;
|
||||||
|
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end,
|
unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end,
|
||||||
bool long_length = false,
|
bool long_length = false,
|
||||||
bool allow_null = false)
|
bool allow_null = false)
|
||||||
{
|
{
|
||||||
const uint32_t len_len = long_length ? 4 : 1;
|
const uint32_t len_len = long_length ? 4 : 1;
|
||||||
if(Offset(cursor, end) < len_len) {
|
if(Offset(cursor, end) < len_len) {
|
||||||
TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
|
TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end);
|
const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end);
|
||||||
|
|
||||||
if (Offset(cursor, end) < length) {
|
if (Offset(cursor, end) < length) {
|
||||||
TokenizeError("cannot ReadString, length is out of bounds",input, cursor);
|
TokenizeError("cannot ReadString, length is out of bounds",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
sbegin_out = cursor;
|
sbegin_out = cursor;
|
||||||
cursor += length;
|
cursor += length;
|
||||||
|
|
||||||
send_out = cursor;
|
send_out = cursor;
|
||||||
|
|
||||||
if(!allow_null) {
|
if(!allow_null) {
|
||||||
for (unsigned int i = 0; i < length; ++i) {
|
for (unsigned int i = 0; i < length; ++i) {
|
||||||
if(sbegin_out[i] == '\0') {
|
if(sbegin_out[i] == '\0') {
|
||||||
TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor);
|
TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,203 +170,203 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
|
void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
|
||||||
{
|
{
|
||||||
if(Offset(cursor, end) < 1) {
|
if(Offset(cursor, end) < 1) {
|
||||||
TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
|
TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char type = *cursor;
|
const char type = *cursor;
|
||||||
sbegin_out = cursor++;
|
sbegin_out = cursor++;
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
// 16 bit int
|
// 16 bit int
|
||||||
case 'Y':
|
case 'Y':
|
||||||
cursor += 2;
|
cursor += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 1 bit bool flag (yes/no)
|
// 1 bit bool flag (yes/no)
|
||||||
case 'C':
|
case 'C':
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 32 bit int
|
// 32 bit int
|
||||||
case 'I':
|
case 'I':
|
||||||
// <- fall thru
|
// <- fall thru
|
||||||
|
|
||||||
// float
|
// float
|
||||||
case 'F':
|
case 'F':
|
||||||
cursor += 4;
|
cursor += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// double
|
// double
|
||||||
case 'D':
|
case 'D':
|
||||||
cursor += 8;
|
cursor += 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 64 bit int
|
// 64 bit int
|
||||||
case 'L':
|
case 'L':
|
||||||
cursor += 8;
|
cursor += 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// note: do not write cursor += ReadWord(...cursor) as this would be UB
|
// note: do not write cursor += ReadWord(...cursor) as this would be UB
|
||||||
|
|
||||||
// raw binary data
|
// raw binary data
|
||||||
case 'R':
|
case 'R':
|
||||||
{
|
{
|
||||||
const uint32_t length = ReadWord(input, cursor, end);
|
const uint32_t length = ReadWord(input, cursor, end);
|
||||||
cursor += length;
|
cursor += length;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
// TODO: what is the 'b' type code? Right now we just skip over it /
|
// TODO: what is the 'b' type code? Right now we just skip over it /
|
||||||
// take the full range we could get
|
// take the full range we could get
|
||||||
cursor = end;
|
cursor = end;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// array of *
|
// array of *
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'l':
|
case 'l':
|
||||||
case 'i': {
|
case 'i': {
|
||||||
|
|
||||||
const uint32_t length = ReadWord(input, cursor, end);
|
const uint32_t length = ReadWord(input, cursor, end);
|
||||||
const uint32_t encoding = ReadWord(input, cursor, end);
|
const uint32_t encoding = ReadWord(input, cursor, end);
|
||||||
|
|
||||||
const uint32_t comp_len = ReadWord(input, cursor, end);
|
const uint32_t comp_len = ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// compute length based on type and check against the stored value
|
// compute length based on type and check against the stored value
|
||||||
if(encoding == 0) {
|
if(encoding == 0) {
|
||||||
uint32_t stride = 0;
|
uint32_t stride = 0;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'i':
|
case 'i':
|
||||||
stride = 4;
|
stride = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'l':
|
case 'l':
|
||||||
stride = 8;
|
stride = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
};
|
};
|
||||||
ai_assert(stride > 0);
|
ai_assert(stride > 0);
|
||||||
if(length * stride != comp_len) {
|
if(length * stride != comp_len) {
|
||||||
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
|
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// zip/deflate algorithm (encoding==1)? take given length. anything else? die
|
// zip/deflate algorithm (encoding==1)? take given length. anything else? die
|
||||||
else if (encoding != 1) {
|
else if (encoding != 1) {
|
||||||
TokenizeError("cannot ReadData, unknown encoding",input, cursor);
|
TokenizeError("cannot ReadData, unknown encoding",input, cursor);
|
||||||
}
|
}
|
||||||
cursor += comp_len;
|
cursor += comp_len;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// string
|
// string
|
||||||
case 'S': {
|
case 'S': {
|
||||||
const char* sb, *se;
|
const char* sb, *se;
|
||||||
// 0 characters can legally happen in such strings
|
// 0 characters can legally happen in such strings
|
||||||
ReadString(sb, se, input, cursor, end, true, true);
|
ReadString(sb, se, input, cursor, end, true, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor);
|
TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cursor > end) {
|
if(cursor > end) {
|
||||||
TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor);
|
TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the type code is contained in the returned range
|
// the type code is contained in the returned range
|
||||||
send_out = cursor;
|
send_out = cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end)
|
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end)
|
||||||
{
|
{
|
||||||
// the first word contains the offset at which this block ends
|
// the first word contains the offset at which this block ends
|
||||||
const uint32_t end_offset = ReadWord(input, cursor, end);
|
const uint32_t end_offset = ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// we may get 0 if reading reached the end of the file -
|
// we may get 0 if reading reached the end of the file -
|
||||||
// fbx files have a mysterious extra footer which I don't know
|
// fbx files have a mysterious extra footer which I don't know
|
||||||
// how to extract any information from, but at least it always
|
// how to extract any information from, but at least it always
|
||||||
// starts with a 0.
|
// starts with a 0.
|
||||||
if(!end_offset) {
|
if(!end_offset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(end_offset > Offset(input, end)) {
|
if(end_offset > Offset(input, end)) {
|
||||||
TokenizeError("block offset is out of range",input, cursor);
|
TokenizeError("block offset is out of range",input, cursor);
|
||||||
}
|
}
|
||||||
else if(end_offset < Offset(input, cursor)) {
|
else if(end_offset < Offset(input, cursor)) {
|
||||||
TokenizeError("block offset is negative out of range",input, cursor);
|
TokenizeError("block offset is negative out of range",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// the second data word contains the number of properties in the scope
|
// the second data word contains the number of properties in the scope
|
||||||
const uint32_t prop_count = ReadWord(input, cursor, end);
|
const uint32_t prop_count = ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// the third data word contains the length of the property list
|
// the third data word contains the length of the property list
|
||||||
const uint32_t prop_length = ReadWord(input, cursor, end);
|
const uint32_t prop_length = ReadWord(input, cursor, end);
|
||||||
|
|
||||||
// now comes the name of the scope/key
|
// now comes the name of the scope/key
|
||||||
const char* sbeg, *send;
|
const char* sbeg, *send;
|
||||||
ReadString(sbeg, send, input, cursor, end);
|
ReadString(sbeg, send, input, cursor, end);
|
||||||
|
|
||||||
output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) ));
|
||||||
|
|
||||||
// now come the individual properties
|
// now come the individual properties
|
||||||
const char* begin_cursor = cursor;
|
const char* begin_cursor = cursor;
|
||||||
for (unsigned int i = 0; i < prop_count; ++i) {
|
for (unsigned int i = 0; i < prop_count; ++i) {
|
||||||
ReadData(sbeg, send, input, cursor, begin_cursor + prop_length);
|
ReadData(sbeg, send, input, cursor, begin_cursor + prop_length);
|
||||||
|
|
||||||
output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) ));
|
||||||
|
|
||||||
if(i != prop_count-1) {
|
if(i != prop_count-1) {
|
||||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Offset(begin_cursor, cursor) != prop_length) {
|
if (Offset(begin_cursor, cursor) != prop_length) {
|
||||||
TokenizeError("property length not reached, something is wrong",input, cursor);
|
TokenizeError("property length not reached, something is wrong",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// at the end of each nested block, there is a NUL record to indicate
|
// at the end of each nested block, there is a NUL record to indicate
|
||||||
// that the sub-scope exists (i.e. to distinguish between P: and P : {})
|
// that the sub-scope exists (i.e. to distinguish between P: and P : {})
|
||||||
// this NUL record is 13 bytes long.
|
// this NUL record is 13 bytes long.
|
||||||
#define BLOCK_SENTINEL_LENGTH 13
|
#define BLOCK_SENTINEL_LENGTH 13
|
||||||
|
|
||||||
if (Offset(input, cursor) < end_offset) {
|
if (Offset(input, cursor) < end_offset) {
|
||||||
|
|
||||||
if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) {
|
if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) {
|
||||||
TokenizeError("insufficient padding bytes at block end",input, cursor);
|
TokenizeError("insufficient padding bytes at block end",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) ));
|
||||||
|
|
||||||
// XXX this is vulnerable to stack overflowing ..
|
// XXX this is vulnerable to stack overflowing ..
|
||||||
while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) {
|
while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) {
|
||||||
ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH);
|
ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH);
|
||||||
}
|
}
|
||||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
||||||
|
|
||||||
for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) {
|
for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) {
|
||||||
if(cursor[i] != '\0') {
|
if(cursor[i] != '\0') {
|
||||||
TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
|
TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor += BLOCK_SENTINEL_LENGTH;
|
cursor += BLOCK_SENTINEL_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Offset(input, cursor) != end_offset) {
|
if (Offset(input, cursor) != end_offset) {
|
||||||
TokenizeError("scope length not reached, something is wrong",input, cursor);
|
TokenizeError("scope length not reached, something is wrong",input, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,26 +375,26 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
|
void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
|
||||||
{
|
{
|
||||||
ai_assert(input);
|
ai_assert(input);
|
||||||
|
|
||||||
if(length < 0x1b) {
|
if(length < 0x1b) {
|
||||||
TokenizeError("file is too short",0);
|
TokenizeError("file is too short",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(input,"Kaydara FBX Binary",18)) {
|
if (strncmp(input,"Kaydara FBX Binary",18)) {
|
||||||
TokenizeError("magic bytes not found",0);
|
TokenizeError("magic bytes not found",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//uint32_t offset = 0x1b;
|
//uint32_t offset = 0x1b;
|
||||||
|
|
||||||
const char* cursor = input + 0x1b;
|
const char* cursor = input + 0x1b;
|
||||||
|
|
||||||
while (cursor < input + length) {
|
while (cursor < input + length) {
|
||||||
if(!ReadScope(output_tokens, input, cursor, input + length)) {
|
if(!ReadScope(output_tokens, input, cursor, input + length)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // !FBX
|
} // !FBX
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue