- Merge in latest from assimp/assimp on GitHub (5c00aef7cd)

- Added at least some of the new files to my Xcode 6 project, as
well.
    - Built and tested with the DAE importer, seems to work fine.
pull/615/head
Wil Shipley 2015-07-26 19:16:01 -07:00
commit 8b7fa48d27
648 changed files with 199798 additions and 210225 deletions

22
.editorconfig 100644
View File

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

8
.gitattributes vendored 100644
View File

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

8
.gitignore vendored
View File

@ -1,3 +1,4 @@
.idea
build build
.project .project
*.kdev4* *.kdev4*
@ -10,7 +11,7 @@ build
# Output # Output
bin/ bin/
lib/ lib/
contrib/
# Generated # Generated
assimp.pc assimp.pc
@ -54,3 +55,8 @@ tools/assimp_view/assimp_viewer.vcxproj.user
# Unix editor backups # Unix editor backups
*~ *~
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
test/gtest/src/gtest-stamp/gtest-gitclone-lastrun.txt
Assimp.opensdf
contrib/zlib/CTestTestfile.cmake
ipch/assimp_viewer-44bbbcd1/assimp_viewerd-ccc45335.ipch

16
.travis.sh 100755
View File

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

View File

@ -1,16 +1,22 @@
before_install: before_install:
- sudo apt-get update -qq
- sudo apt-get install cmake python3 - sudo apt-get install cmake python3
- if [ $LINUX ]; then sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; fi
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
branches:
only:
- master
env: env:
matrix: global:
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
matrix:
- LINUX=1 TRAVIS_NO_EXPORT=YES - LINUX=1 TRAVIS_NO_EXPORT=YES
- LINUX=1 TRAVIS_NO_EXPORT=NO - LINUX=1 TRAVIS_NO_EXPORT=NO
- LINUX=1 TRAVIS_STATIC_BUILD=ON - LINUX=1 SHARED_BUILD=ON
- LINUX=1 TRAVIS_STATIC_BUILD=OFF - LINUX=1 SHARED_BUILD=OFF
- WINDOWS=1 TRAVIS_NO_EXPORT=YES - ANDROID=1
- WINDOWS=1 TRAVIS_NO_EXPORT=NO
- WINDOWS=1 TRAVIS_STATIC_BUILD=ON
- WINDOWS=1 TRAVIS_STATIC_BUILD=OFF
language: cpp language: cpp
@ -19,19 +25,7 @@ compiler:
- clang - clang
install: install:
- if [ $WINDOWS ]; then travis_retry sudo apt-get install -q -y gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64; 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:
- cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD - . ./.travis.sh
- make
- sudo make install
- sudo ldconfig
- cd test/unit
- ../../bin/unit
- cd ../regression
- chmod 755 run.py
- ./run.py
- echo "=========================================================="
- echo "REGRESSION TEST FAILS (results/run_regression_suite_failures.csv)"
- cat ../results/run_regression_suite_failures.csv

View File

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

View File

@ -1,6 +1,13 @@
set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
cmake_minimum_required( VERSION 2.8 ) cmake_minimum_required( VERSION 2.8 )
PROJECT( Assimp ) PROJECT( Assimp )
option(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
if(NOT BUILD_SHARED_LIBS)
#set(CMAKE_EXE_LINKER_FLAGS "-static")
set(LINK_SEARCH_START_STATIC TRUE)
endif(NOT BUILD_SHARED_LIBS)
# Define here the needed parameters # Define here the needed parameters
set (ASSIMP_VERSION_MAJOR 3) set (ASSIMP_VERSION_MAJOR 3)
set (ASSIMP_VERSION_MINOR 1) set (ASSIMP_VERSION_MINOR 1)
@ -11,29 +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 )
# 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_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_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})
@ -49,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)
add_definitions(-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
add_definitions( -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)
@ -71,54 +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")
# Allow the user to build a shared or static library
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
# 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
@ -126,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 )
@ -139,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.
@ -274,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()

View File

@ -151,3 +151,10 @@ Ogre Binary format support
- Filip Wasil, Tieto Poland Sp. z o.o. - Filip Wasil, Tieto Poland Sp. z o.o.
Android JNI asset extraction support Android JNI asset extraction support
- Richard Steffen
Contributed ExportProperties interface
Contributed X File exporter
Contributed Step (stp) exporter

12
CodeConventions.md 100644
View File

@ -0,0 +1,12 @@
Open Asset Import Library Coding Conventions
==
If you want to participate as a developer in the **Open Asset Import Library** please read and respect the following coding conventions. This will ensure consistency throughout the codebase and help all the Open Asset Import Library users.
Spacing
==
* Use UNIX-style line endings (LF)
* Remove any trailing whitespace
* Expand tabs to 4 spaces

View File

@ -1,14 +0,0 @@
===============================================
The Asset-Importer-Library Coding conventions
===============================================
If you want to participate to the Asset-Importer_Library please have a look
onto these coding conventions and try to follow them. They are more or less
some kind of guide line to help others coming into the code and help all
the Asset-Importer-Library users.
Tab width
===========
The tab width shall be 4 spaces.

View File

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

View File

@ -1,18 +1,31 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
======== ========
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a shared, in-memory format__. It supports more than __40 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _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. Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
This is the development trunk of assimp 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 of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp) APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
[open3mod](https://github.com/acgessler/open3mod) is an Open Source 3D model viewer based off Assimp's import and export abilities. 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.
The current build status is:
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.__
#### Supported file formats #### #### Supported file formats ####
The library provides importers for a lot of file formats, including: A full list [is here](http://assimp.sourceforge.net/main_features_formats.html).
__Importers__:
- 3DS - 3DS
- BLEND (Blender 3D) - BLEND (Blender)
- DAE/Collada - DAE/Collada
- FBX - FBX
- IFC-STEP - IFC-STEP
@ -28,7 +41,8 @@ The library provides importers for a lot of file formats, including:
- PLY - PLY
- STL - STL
- X - X
- OBJ - OBJ
- OpenGEX
- SMD - SMD
- LWO - LWO
- LXO - LXO
@ -46,13 +60,13 @@ The library provides importers for a lot of file formats, including:
- Ogre Binary - Ogre Binary
- Ogre XML - Ogre XML
- Q3D - Q3D
- ASSBIN (Assimp scene serialization) - ASSBIN (Assimp custom format)
Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries. Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
- C4D (https://github.com/acgessler/assimp-cinema4d) - C4D (https://github.com/acgessler/assimp-cinema4d)
Exporters include: __Exporters__:
- DAE (Collada) - DAE (Collada)
- STL - STL
@ -63,23 +77,21 @@ Exporters include:
- JSON (for WebGl, via https://github.com/acgessler/assimp2json) - JSON (for WebGl, via https://github.com/acgessler/assimp2json)
- ASSBIN - ASSBIN
See [the full list here](http://assimp.sourceforge.net/main_features_formats.html). ### Building ###
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
#### Repository structure #### #### Repository structure ####
Open Asset Import Library is implemented in C++ (but provides both a C and a Open Asset Import Library is implemented in C++. The directory structure is:
C++ish interface). The directory structure is:
/bin Folder for binaries, only used on Windows
/code Source code /code Source code
/contrib Third-party libraries /contrib Third-party libraries
/doc Documentation (doxysource and pre-compiled docs) /doc Documentation (doxysource and pre-compiled docs)
/include Public header C and C++ header files /include Public header C and C++ header files
/lib Static library location for Windows
/obj Object file location for Windows
/scripts Scripts used to generate the loading code for some formats /scripts Scripts used to generate the loading code for some formats
/port Ports to other languages and scripts to maintain those. /port Ports to other languages and scripts to maintain those.
/test Unit- and regression tests, test suite of models /test Unit- and regression tests, test suite of models
@ -90,24 +102,15 @@ C++ish interface). The directory structure is:
CMake has superseeded all legacy build options!) CMake has superseeded all legacy build options!)
### Building ###
Take a look into the `INSTALL` file. Our build system is CMake, if you already used CMake before there is a good chance you know what to do.
### Where to get help ### ### Where to get help ###
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format. For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
(CHMs for Windows are included in some release packages and should be located right here in the root folder). (CHMs for Windows are included in some release packages and should be located right here in the root folder).
If the documentation doesn't solve your problems, If the docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
[try our forums at SF.net](http://sourceforge.net/p/assimp/discussion/817654) or ask on
[StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
For development discussions, there is also a mailing list, _assimp-discussions_ For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions) [(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
### Contributing ### ### Contributing ###
@ -115,10 +118,9 @@ For development discussions, there is also a mailing list, _assimp-discussions_
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
a pull request with your changes against the main repository's `master` branch. a pull request with your changes against the main repository's `master` branch.
### License ### ### License ###
Our license is based on the modified, __3-clause BSD__-License, which is very liberal. Our license is based on the modified, __3-clause BSD__-License.
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp. and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.

24
appveyor.yml 100644
View File

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

View File

@ -2,63 +2,71 @@ 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")
ExternalProject_Add(gtest # try to find git - if found, setup gtest
GIT_REPOSITORY https://chromium.googlesource.com/external/googletest find_package(Git)
TIMEOUT 10 if(NOT GIT_FOUND)
PREFIX "${GTEST_PREFIX}" set(AddGTest_FOUND false CACHE BOOL "Was gtest setup correctly?")
CMAKE_ARGS "${GTEST_CMAKE_ARGS}" else(NOT GIT_FOUND)
LOG_DOWNLOAD ON set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?")
LOG_CONFIGURE ON
LOG_BUILD ON
# Disable install
INSTALL_COMMAND ""
)
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}") ExternalProject_Add(gtest
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
set(GTEST_LOCATION "${GTEST_PREFIX}/src/gtest-build") TIMEOUT 10
set(GTEST_DEBUG_LIBRARIES PREFIX "${GTEST_PREFIX}"
"${GTEST_LOCATION}/${DEBUG_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}" CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
"${CMAKE_THREAD_LIBS_INIT}") LOG_DOWNLOAD ON
SET(GTEST_RELEASE_LIBRARIES LOG_CONFIGURE ON
"${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}" LOG_BUILD ON
"${CMAKE_THREAD_LIBS_INIT}") # Disable install
INSTALL_COMMAND ""
)
if(MSVC_VERSION EQUAL 1700) set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
add_definitions(-D_VARIADIC_MAX=10) set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif() set(GTEST_LOCATION "${GTEST_PREFIX}/src/gtest-build")
set(GTEST_DEBUG_LIBRARIES
"${GTEST_LOCATION}/${DEBUG_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
"${CMAKE_THREAD_LIBS_INIT}")
SET(GTEST_RELEASE_LIBRARIES
"${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
"${CMAKE_THREAD_LIBS_INIT}")
ExternalProject_Get_Property(gtest source_dir) if(MSVC_VERSION EQUAL 1700)
include_directories(${source_dir}/include) add_definitions(-D_VARIADIC_MAX=10)
include_directories(${source_dir}/gtest/include) endif()
ExternalProject_Get_Property(gtest binary_dir) ExternalProject_Get_Property(gtest source_dir)
link_directories(${binary_dir}) include_directories(${source_dir}/include)
include_directories(${source_dir}/gtest/include)
ExternalProject_Get_Property(gtest binary_dir)
link_directories(${binary_dir})
endif(NOT GIT_FOUND)

View File

@ -1,347 +1,347 @@
## Debian Source Package Generator ## Debian Source Package Generator
# #
# Copyright (c) 2010 Daniel Pfeifer <daniel@pfeifer-mail.de> # Copyright (c) 2010 Daniel Pfeifer <daniel@pfeifer-mail.de>
# Many modifications by Rosen Diankov <rosen.diankov@gmail.com> # Many modifications by Rosen Diankov <rosen.diankov@gmail.com>
# #
# Creates source debian files and manages library dependencies # Creates source debian files and manages library dependencies
# #
# Features: # Features:
# #
# - Automatically generates symbols and run-time dependencies from the build dependencies # - Automatically generates symbols and run-time dependencies from the build dependencies
# - Custom copy of source directory via CPACK_DEBIAN_PACKAGE_SOURCE_COPY # - Custom copy of source directory via CPACK_DEBIAN_PACKAGE_SOURCE_COPY
# - Simultaneous output of multiple debian source packages for each distribution # - Simultaneous output of multiple debian source packages for each distribution
# - Can specificy distribution-specific dependencies by suffixing DEPENDS with _${DISTRO_NAME}, for example: CPACK_DEBIAN_PACKAGE_DEPENDS_LUCID, CPACK_COMPONENT_MYCOMP0_DEPENDS_LUCID # - Can specificy distribution-specific dependencies by suffixing DEPENDS with _${DISTRO_NAME}, for example: CPACK_DEBIAN_PACKAGE_DEPENDS_LUCID, CPACK_COMPONENT_MYCOMP0_DEPENDS_LUCID
# #
# Usage: # Usage:
# #
# set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake) # set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake)
# set(CPACK_DEBIAN_PACKAGE_PRIORITY optional) # set(CPACK_DEBIAN_PACKAGE_PRIORITY optional)
# set(CPACK_DEBIAN_PACKAGE_SECTION devel) # set(CPACK_DEBIAN_PACKAGE_SECTION devel)
# set(CPACK_DEBIAN_CMAKE_OPTIONS "-DMYOPTION=myvalue") # set(CPACK_DEBIAN_CMAKE_OPTIONS "-DMYOPTION=myvalue")
# set(CPACK_DEBIAN_PACKAGE_DEPENDS mycomp0 mycomp1 some_ubuntu_package) # set(CPACK_DEBIAN_PACKAGE_DEPENDS mycomp0 mycomp1 some_ubuntu_package)
# set(CPACK_DEBIAN_PACKAGE_DEPENDS_UBUNTU_LUCID mycomp0 mycomp1 lucid_specific_package) # set(CPACK_DEBIAN_PACKAGE_DEPENDS_UBUNTU_LUCID mycomp0 mycomp1 lucid_specific_package)
# set(CPACK_DEBIAN_PACKAGE_NAME mypackage) # set(CPACK_DEBIAN_PACKAGE_NAME mypackage)
# set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES unnecessary_file unnecessary_dir/file0) # set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES unnecessary_file unnecessary_dir/file0)
# set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force) # if using subversion # set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force) # if using subversion
# set(CPACK_DEBIAN_DISTRIBUTION_NAME ubuntu) # set(CPACK_DEBIAN_DISTRIBUTION_NAME ubuntu)
# set(CPACK_DEBIAN_DISTRIBUTION_RELEASES karmic lucid maverick natty) # set(CPACK_DEBIAN_DISTRIBUTION_RELEASES karmic lucid maverick natty)
# set(CPACK_DEBIAN_CHANGELOG " * Extra change log lines") # set(CPACK_DEBIAN_CHANGELOG " * Extra change log lines")
# set(CPACK_DEBIAN_PACKAGE_SUGGESTS "ipython") # set(CPACK_DEBIAN_PACKAGE_SUGGESTS "ipython")
# set(CPACK_COMPONENT_X_RECOMMENDS "recommended-package") # set(CPACK_COMPONENT_X_RECOMMENDS "recommended-package")
## ##
find_program(DEBUILD_EXECUTABLE debuild) find_program(DEBUILD_EXECUTABLE debuild)
find_program(DPUT_EXECUTABLE dput) find_program(DPUT_EXECUTABLE dput)
if(NOT DEBUILD_EXECUTABLE OR NOT DPUT_EXECUTABLE) if(NOT DEBUILD_EXECUTABLE OR NOT DPUT_EXECUTABLE)
return() return()
endif(NOT DEBUILD_EXECUTABLE OR NOT DPUT_EXECUTABLE) endif(NOT DEBUILD_EXECUTABLE OR NOT DPUT_EXECUTABLE)
# DEBIAN/control # DEBIAN/control
# debian policy enforce lower case for package name # debian policy enforce lower case for package name
# Package: (mandatory) # Package: (mandatory)
IF(NOT CPACK_DEBIAN_PACKAGE_NAME) IF(NOT CPACK_DEBIAN_PACKAGE_NAME)
STRING(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME) STRING(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME)
ENDIF(NOT CPACK_DEBIAN_PACKAGE_NAME) ENDIF(NOT CPACK_DEBIAN_PACKAGE_NAME)
# Section: (recommended) # Section: (recommended)
IF(NOT CPACK_DEBIAN_PACKAGE_SECTION) IF(NOT CPACK_DEBIAN_PACKAGE_SECTION)
SET(CPACK_DEBIAN_PACKAGE_SECTION "devel") SET(CPACK_DEBIAN_PACKAGE_SECTION "devel")
ENDIF(NOT CPACK_DEBIAN_PACKAGE_SECTION) ENDIF(NOT CPACK_DEBIAN_PACKAGE_SECTION)
# Priority: (recommended) # Priority: (recommended)
IF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY) IF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
ENDIF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY) ENDIF(NOT CPACK_DEBIAN_PACKAGE_PRIORITY)
file(STRINGS ${CPACK_PACKAGE_DESCRIPTION_FILE} DESC_LINES) file(STRINGS ${CPACK_PACKAGE_DESCRIPTION_FILE} DESC_LINES)
foreach(LINE ${DESC_LINES}) foreach(LINE ${DESC_LINES})
set(DEB_LONG_DESCRIPTION "${DEB_LONG_DESCRIPTION} ${LINE}\n") set(DEB_LONG_DESCRIPTION "${DEB_LONG_DESCRIPTION} ${LINE}\n")
endforeach(LINE ${DESC_LINES}) endforeach(LINE ${DESC_LINES})
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/Debian") file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/Debian")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Debian") file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/Debian")
set(DEBIAN_SOURCE_ORIG_DIR "${CMAKE_BINARY_DIR}/Debian/${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}") set(DEBIAN_SOURCE_ORIG_DIR "${CMAKE_BINARY_DIR}/Debian/${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
if( CPACK_DEBIAN_PACKAGE_SOURCE_COPY ) if( CPACK_DEBIAN_PACKAGE_SOURCE_COPY )
execute_process(COMMAND ${CPACK_DEBIAN_PACKAGE_SOURCE_COPY} "${CMAKE_SOURCE_DIR}" "${DEBIAN_SOURCE_ORIG_DIR}.orig") execute_process(COMMAND ${CPACK_DEBIAN_PACKAGE_SOURCE_COPY} "${CMAKE_SOURCE_DIR}" "${DEBIAN_SOURCE_ORIG_DIR}.orig")
else() else()
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR} "${DEBIAN_SOURCE_ORIG_DIR}.orig") execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR} "${DEBIAN_SOURCE_ORIG_DIR}.orig")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${DEBIAN_SOURCE_ORIG_DIR}.orig/.git") execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${DEBIAN_SOURCE_ORIG_DIR}.orig/.git")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${DEBIAN_SOURCE_ORIG_DIR}.orig/.svn") execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory "${DEBIAN_SOURCE_ORIG_DIR}.orig/.svn")
endif() endif()
# remove unnecessary folders # remove unnecessary folders
foreach(REMOVE_DIR ${CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES}) foreach(REMOVE_DIR ${CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES})
file(REMOVE_RECURSE ${DEBIAN_SOURCE_ORIG_DIR}.orig/${REMOVE_DIR}) file(REMOVE_RECURSE ${DEBIAN_SOURCE_ORIG_DIR}.orig/${REMOVE_DIR})
endforeach() endforeach()
# create the original source tar # create the original source tar
execute_process(COMMAND ${CMAKE_COMMAND} -E tar czf "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}.orig.tar.gz" "${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.orig" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debian) execute_process(COMMAND ${CMAKE_COMMAND} -E tar czf "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}.orig.tar.gz" "${CPACK_DEBIAN_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.orig" WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debian)
set(DEB_SOURCE_CHANGES) set(DEB_SOURCE_CHANGES)
foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES}) foreach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
set(DEBIAN_SOURCE_DIR "${DEBIAN_SOURCE_ORIG_DIR}-${CPACK_DEBIAN_DISTRIBUTION_NAME}1~${RELEASE}1") set(DEBIAN_SOURCE_DIR "${DEBIAN_SOURCE_ORIG_DIR}-${CPACK_DEBIAN_DISTRIBUTION_NAME}1~${RELEASE}1")
set(RELEASE_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_DISTRIBUTION_NAME}1~${RELEASE}1") set(RELEASE_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_DISTRIBUTION_NAME}1~${RELEASE}1")
string(TOUPPER ${RELEASE} RELEASE_UPPER) string(TOUPPER ${RELEASE} RELEASE_UPPER)
string(TOUPPER ${CPACK_DEBIAN_DISTRIBUTION_NAME} DISTRIBUTION_NAME_UPPER) string(TOUPPER ${CPACK_DEBIAN_DISTRIBUTION_NAME} DISTRIBUTION_NAME_UPPER)
file(MAKE_DIRECTORY ${DEBIAN_SOURCE_DIR}/debian) file(MAKE_DIRECTORY ${DEBIAN_SOURCE_DIR}/debian)
############################################################################## ##############################################################################
# debian/control # debian/control
set(DEBIAN_CONTROL ${DEBIAN_SOURCE_DIR}/debian/control) set(DEBIAN_CONTROL ${DEBIAN_SOURCE_DIR}/debian/control)
file(WRITE ${DEBIAN_CONTROL} file(WRITE ${DEBIAN_CONTROL}
"Source: ${CPACK_DEBIAN_PACKAGE_NAME}\n" "Source: ${CPACK_DEBIAN_PACKAGE_NAME}\n"
"Section: ${CPACK_DEBIAN_PACKAGE_SECTION}\n" "Section: ${CPACK_DEBIAN_PACKAGE_SECTION}\n"
"Priority: ${CPACK_DEBIAN_PACKAGE_PRIORITY}\n" "Priority: ${CPACK_DEBIAN_PACKAGE_PRIORITY}\n"
"DM-Upload-Allowed: yes\n" "DM-Upload-Allowed: yes\n"
"Maintainer: ${CPACK_PACKAGE_CONTACT}\n" "Maintainer: ${CPACK_PACKAGE_CONTACT}\n"
"Build-Depends: " "Build-Depends: "
) )
if( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS}) foreach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS}) endforeach(DEP ${CPACK_DEBIAN_BUILD_DEPENDS})
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_DEBIAN_BUILD_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
file(APPEND ${DEBIAN_CONTROL} "\n" file(APPEND ${DEBIAN_CONTROL} "\n"
"Standards-Version: 3.8.4\n" "Standards-Version: 3.8.4\n"
"Homepage: ${CPACK_PACKAGE_VENDOR}\n" "Homepage: ${CPACK_PACKAGE_VENDOR}\n"
"\n" "\n"
"Package: ${CPACK_DEBIAN_PACKAGE_NAME}\n" "Package: ${CPACK_DEBIAN_PACKAGE_NAME}\n"
"Architecture: any\n" "Architecture: any\n"
"Depends: " "Depends: "
) )
if( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_DEPENDS})
endif( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_DEBIAN_PACKAGE_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
file(APPEND ${DEBIAN_CONTROL} "\nRecommends: ") file(APPEND ${DEBIAN_CONTROL} "\nRecommends: ")
if( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_RECOMMENDS})
endif( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_DEBIAN_PACKAGE_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
file(APPEND ${DEBIAN_CONTROL} "\nSuggests: ") file(APPEND ${DEBIAN_CONTROL} "\nSuggests: ")
if( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS}) foreach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS})
file(APPEND ${DEBIAN_CONTROL} "${DEP}, ") file(APPEND ${DEBIAN_CONTROL} "${DEP}, ")
endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS}) endforeach(DEP ${CPACK_DEBIAN_PACKAGE_SUGGESTS})
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_DEBIAN_PACKAGE_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
file(APPEND ${DEBIAN_CONTROL} "\n" file(APPEND ${DEBIAN_CONTROL} "\n"
"Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n" "Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}\n"
"${DEB_LONG_DESCRIPTION}" "${DEB_LONG_DESCRIPTION}"
) )
foreach(COMPONENT ${CPACK_COMPONENTS_ALL}) foreach(COMPONENT ${CPACK_COMPONENTS_ALL})
string(TOUPPER ${COMPONENT} UPPER_COMPONENT) string(TOUPPER ${COMPONENT} UPPER_COMPONENT)
set(DEPENDS "\${shlibs:Depends}") set(DEPENDS "\${shlibs:Depends}")
if( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
set(DEPENDS "${DEPENDS}, ${DEP}") set(DEPENDS "${DEPENDS}, ${DEP}")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
set(DEPENDS "${DEPENDS}, ${DEP}") set(DEPENDS "${DEPENDS}, ${DEP}")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS})
set(DEPENDS "${DEPENDS}, ${DEP}") set(DEPENDS "${DEPENDS}, ${DEP}")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS})
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_COMPONENT_${UPPER_COMPONENT}_DEPENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
set(RECOMMENDS) set(RECOMMENDS)
if( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
set(RECOMMENDS "${RECOMMENDS} ${DEP}, ") set(RECOMMENDS "${RECOMMENDS} ${DEP}, ")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
set(RECOMMENDS "${RECOMMENDS} ${DEP}, ") set(RECOMMENDS "${RECOMMENDS} ${DEP}, ")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS})
set(RECOMMENDS "${RECOMMENDS} ${DEP}, ") set(RECOMMENDS "${RECOMMENDS} ${DEP}, ")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS})
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_COMPONENT_${UPPER_COMPONENT}_RECOMMENDS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
set(SUGGESTS) set(SUGGESTS)
if( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) if( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
set(SUGGESTS "${SUGGESTS} ${DEP}, ") set(SUGGESTS "${SUGGESTS} ${DEP}, ")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER}})
else( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) else( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
if( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} ) if( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
set(SUGGESTS "${SUGGESTS} ${DEP}, ") set(SUGGESTS "${SUGGESTS} ${DEP}, ")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}})
else( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} ) else( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS}) foreach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS})
set(SUGGESTS "${SUGGESTS} ${DEP}, ") set(SUGGESTS "${SUGGESTS} ${DEP}, ")
endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS}) endforeach(DEP ${CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS})
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} ) endif( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER} )
endif( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} ) endif( CPACK_COMPONENT_${UPPER_COMPONENT}_SUGGESTS_${DISTRIBUTION_NAME_UPPER}_${RELEASE_UPPER} )
file(APPEND ${DEBIAN_CONTROL} "\n" file(APPEND ${DEBIAN_CONTROL} "\n"
"Package: ${COMPONENT}\n" "Package: ${COMPONENT}\n"
"Architecture: any\n" "Architecture: any\n"
"Depends: ${DEPENDS}\n" "Depends: ${DEPENDS}\n"
"Recommends: ${RECOMMENDS}\n" "Recommends: ${RECOMMENDS}\n"
"Suggests: ${SUGGESTS}\n" "Suggests: ${SUGGESTS}\n"
"Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_COMPONENT_${UPPER_COMPONENT}_DISPLAY_NAME}\n" "Description: ${CPACK_PACKAGE_DISPLAY_NAME} ${CPACK_COMPONENT_${UPPER_COMPONENT}_DISPLAY_NAME}\n"
"${DEB_LONG_DESCRIPTION}" "${DEB_LONG_DESCRIPTION}"
" .\n" " .\n"
" ${CPACK_COMPONENT_${UPPER_COMPONENT}_DESCRIPTION}\n" " ${CPACK_COMPONENT_${UPPER_COMPONENT}_DESCRIPTION}\n"
) )
endforeach(COMPONENT ${CPACK_COMPONENTS_ALL}) endforeach(COMPONENT ${CPACK_COMPONENTS_ALL})
############################################################################## ##############################################################################
# debian/copyright # debian/copyright
set(DEBIAN_COPYRIGHT ${DEBIAN_SOURCE_DIR}/debian/copyright) set(DEBIAN_COPYRIGHT ${DEBIAN_SOURCE_DIR}/debian/copyright)
execute_process(COMMAND ${CMAKE_COMMAND} -E execute_process(COMMAND ${CMAKE_COMMAND} -E
copy ${CPACK_RESOURCE_FILE_LICENSE} ${DEBIAN_COPYRIGHT} copy ${CPACK_RESOURCE_FILE_LICENSE} ${DEBIAN_COPYRIGHT}
) )
############################################################################## ##############################################################################
# debian/rules # debian/rules
set(DEBIAN_RULES ${DEBIAN_SOURCE_DIR}/debian/rules) set(DEBIAN_RULES ${DEBIAN_SOURCE_DIR}/debian/rules)
file(WRITE ${DEBIAN_RULES} file(WRITE ${DEBIAN_RULES}
"#!/usr/bin/make -f\n" "#!/usr/bin/make -f\n"
"\n" "\n"
"BUILDDIR = build_dir\n" "BUILDDIR = build_dir\n"
"\n" "\n"
"build:\n" "build:\n"
" mkdir $(BUILDDIR)\n" " mkdir $(BUILDDIR)\n"
" cd $(BUILDDIR); cmake -DCMAKE_BUILD_TYPE=Release ${CPACK_DEBIAN_CMAKE_OPTIONS} -DCMAKE_INSTALL_PREFIX=/usr ..\n" " cd $(BUILDDIR); cmake -DCMAKE_BUILD_TYPE=Release ${CPACK_DEBIAN_CMAKE_OPTIONS} -DCMAKE_INSTALL_PREFIX=/usr ..\n"
" $(MAKE) -C $(BUILDDIR) preinstall\n" " $(MAKE) -C $(BUILDDIR) preinstall\n"
" touch build\n" " touch build\n"
"\n" "\n"
"binary: binary-indep binary-arch\n" "binary: binary-indep binary-arch\n"
"\n" "\n"
"binary-indep: build\n" "binary-indep: build\n"
"\n" "\n"
"binary-arch: build\n" "binary-arch: build\n"
" cd $(BUILDDIR); cmake -DCOMPONENT=Unspecified -DCMAKE_INSTALL_PREFIX=../debian/tmp/usr -P cmake_install.cmake\n" " cd $(BUILDDIR); cmake -DCOMPONENT=Unspecified -DCMAKE_INSTALL_PREFIX=../debian/tmp/usr -P cmake_install.cmake\n"
" mkdir -p debian/tmp/DEBIAN\n" " mkdir -p debian/tmp/DEBIAN\n"
" dpkg-gensymbols -p${CPACK_DEBIAN_PACKAGE_NAME}\n" " dpkg-gensymbols -p${CPACK_DEBIAN_PACKAGE_NAME}\n"
) )
foreach(COMPONENT ${CPACK_COMPONENTS_ALL}) foreach(COMPONENT ${CPACK_COMPONENTS_ALL})
set(PATH debian/${COMPONENT}) set(PATH debian/${COMPONENT})
file(APPEND ${DEBIAN_RULES} file(APPEND ${DEBIAN_RULES}
" cd $(BUILDDIR); cmake -DCOMPONENT=${COMPONENT} -DCMAKE_INSTALL_PREFIX=../${PATH}/usr -P cmake_install.cmake\n" " cd $(BUILDDIR); cmake -DCOMPONENT=${COMPONENT} -DCMAKE_INSTALL_PREFIX=../${PATH}/usr -P cmake_install.cmake\n"
" mkdir -p ${PATH}/DEBIAN\n" " mkdir -p ${PATH}/DEBIAN\n"
" dpkg-gensymbols -p${COMPONENT} -P${PATH}\n" " dpkg-gensymbols -p${COMPONENT} -P${PATH}\n"
) )
endforeach(COMPONENT ${CPACK_COMPONENTS_ALL}) endforeach(COMPONENT ${CPACK_COMPONENTS_ALL})
file(APPEND ${DEBIAN_RULES} file(APPEND ${DEBIAN_RULES}
" dh_shlibdeps\n" " dh_shlibdeps\n"
" dh_strip\n" # for reducing size " dh_strip\n" # for reducing size
" dpkg-gencontrol -p${CPACK_DEBIAN_PACKAGE_NAME}\n" " dpkg-gencontrol -p${CPACK_DEBIAN_PACKAGE_NAME}\n"
" dpkg --build debian/tmp ..\n" " dpkg --build debian/tmp ..\n"
) )
foreach(COMPONENT ${CPACK_COMPONENTS_ALL}) foreach(COMPONENT ${CPACK_COMPONENTS_ALL})
set(PATH debian/${COMPONENT}) set(PATH debian/${COMPONENT})
file(APPEND ${DEBIAN_RULES} file(APPEND ${DEBIAN_RULES}
" dpkg-gencontrol -p${COMPONENT} -P${PATH} -Tdebian/${COMPONENT}.substvars\n" " dpkg-gencontrol -p${COMPONENT} -P${PATH} -Tdebian/${COMPONENT}.substvars\n"
" dpkg --build ${PATH} ..\n" " dpkg --build ${PATH} ..\n"
) )
endforeach(COMPONENT ${CPACK_COMPONENTS_ALL}) endforeach(COMPONENT ${CPACK_COMPONENTS_ALL})
file(APPEND ${DEBIAN_RULES} file(APPEND ${DEBIAN_RULES}
"\n" "\n"
"clean:\n" "clean:\n"
" rm -f build\n" " rm -f build\n"
" rm -rf $(BUILDDIR)\n" " rm -rf $(BUILDDIR)\n"
"\n" "\n"
".PHONY: binary binary-arch binary-indep clean\n" ".PHONY: binary binary-arch binary-indep clean\n"
) )
execute_process(COMMAND chmod +x ${DEBIAN_RULES}) execute_process(COMMAND chmod +x ${DEBIAN_RULES})
############################################################################## ##############################################################################
# debian/compat # debian/compat
file(WRITE ${DEBIAN_SOURCE_DIR}/debian/compat "7") file(WRITE ${DEBIAN_SOURCE_DIR}/debian/compat "7")
############################################################################## ##############################################################################
# debian/source/format # debian/source/format
file(WRITE ${DEBIAN_SOURCE_DIR}/debian/source/format "3.0 (quilt)") file(WRITE ${DEBIAN_SOURCE_DIR}/debian/source/format "3.0 (quilt)")
############################################################################## ##############################################################################
# debian/changelog # debian/changelog
set(DEBIAN_CHANGELOG ${DEBIAN_SOURCE_DIR}/debian/changelog) set(DEBIAN_CHANGELOG ${DEBIAN_SOURCE_DIR}/debian/changelog)
execute_process(COMMAND date -R OUTPUT_VARIABLE DATE_TIME) execute_process(COMMAND date -R OUTPUT_VARIABLE DATE_TIME)
file(WRITE ${DEBIAN_CHANGELOG} file(WRITE ${DEBIAN_CHANGELOG}
"${CPACK_DEBIAN_PACKAGE_NAME} (${RELEASE_PACKAGE_VERSION}) ${RELEASE}; urgency=medium\n\n" "${CPACK_DEBIAN_PACKAGE_NAME} (${RELEASE_PACKAGE_VERSION}) ${RELEASE}; urgency=medium\n\n"
" * Package built with CMake\n\n" " * Package built with CMake\n\n"
"${CPACK_DEBIAN_CHANGELOG}" "${CPACK_DEBIAN_CHANGELOG}"
" -- ${CPACK_PACKAGE_CONTACT} ${DATE_TIME}" " -- ${CPACK_PACKAGE_CONTACT} ${DATE_TIME}"
) )
############################################################################## ##############################################################################
# debuild -S # debuild -S
if( DEB_SOURCE_CHANGES ) if( DEB_SOURCE_CHANGES )
set(DEBUILD_OPTIONS "-sd") set(DEBUILD_OPTIONS "-sd")
else() else()
set(DEBUILD_OPTIONS "-sa") set(DEBUILD_OPTIONS "-sa")
endif() endif()
set(SOURCE_CHANGES_FILE "${CPACK_DEBIAN_PACKAGE_NAME}_${RELEASE_PACKAGE_VERSION}_source.changes") set(SOURCE_CHANGES_FILE "${CPACK_DEBIAN_PACKAGE_NAME}_${RELEASE_PACKAGE_VERSION}_source.changes")
set(DEB_SOURCE_CHANGES ${DEB_SOURCE_CHANGES} "${SOURCE_CHANGES_FILE}") set(DEB_SOURCE_CHANGES ${DEB_SOURCE_CHANGES} "${SOURCE_CHANGES_FILE}")
add_custom_command(OUTPUT "${SOURCE_CHANGES_FILE}" COMMAND ${DEBUILD_EXECUTABLE} -S ${DEBUILD_OPTIONS} WORKING_DIRECTORY ${DEBIAN_SOURCE_DIR}) add_custom_command(OUTPUT "${SOURCE_CHANGES_FILE}" COMMAND ${DEBUILD_EXECUTABLE} -S ${DEBUILD_OPTIONS} WORKING_DIRECTORY ${DEBIAN_SOURCE_DIR})
endforeach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES}) endforeach(RELEASE ${CPACK_DEBIAN_DISTRIBUTION_RELEASES})
############################################################################## ##############################################################################
# dput ppa:your-lp-id/ppa <source.changes> # dput ppa:your-lp-id/ppa <source.changes>
add_custom_target(dput ${DPUT_EXECUTABLE} ${DPUT_HOST} ${DEB_SOURCE_CHANGES} DEPENDS ${DEB_SOURCE_CHANGES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debian) add_custom_target(dput ${DPUT_EXECUTABLE} ${DPUT_HOST} ${DEB_SOURCE_CHANGES} DEPENDS ${DEB_SOURCE_CHANGES} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Debian)

View File

@ -1,100 +1,100 @@
#------------------------------------------------------------------- #-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE # This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine) # (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/ # For the latest info, see http://www.ogre3d.org/
# #
# The contents of this file are placed in the public domain. Feel # The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like. # free to make use of it in any way you like.
#------------------------------------------------------------------- #-------------------------------------------------------------------
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Find DirectX SDK # Find DirectX SDK
# Define: # Define:
# DirectX_FOUND # DirectX_FOUND
# DirectX_INCLUDE_DIR # DirectX_INCLUDE_DIR
# DirectX_LIBRARY # DirectX_LIBRARY
# DirectX_ROOT_DIR # DirectX_ROOT_DIR
if(WIN32) # The only platform it makes sense to check for DirectX SDK if(WIN32) # The only platform it makes sense to check for DirectX SDK
include(FindPkgMacros) include(FindPkgMacros)
findpkg_begin(DirectX) findpkg_begin(DirectX)
# Get path, convert backslashes as ${ENV_DXSDK_DIR} # Get path, convert backslashes as ${ENV_DXSDK_DIR}
getenv_path(DXSDK_DIR) getenv_path(DXSDK_DIR)
getenv_path(DIRECTX_HOME) getenv_path(DIRECTX_HOME)
getenv_path(DIRECTX_ROOT) getenv_path(DIRECTX_ROOT)
getenv_path(DIRECTX_BASE) getenv_path(DIRECTX_BASE)
# construct search paths # construct search paths
set(DirectX_PREFIX_PATH set(DirectX_PREFIX_PATH
"${DXSDK_DIR}" "${ENV_DXSDK_DIR}" "${DXSDK_DIR}" "${ENV_DXSDK_DIR}"
"${DIRECTX_HOME}" "${ENV_DIRECTX_HOME}" "${DIRECTX_HOME}" "${ENV_DIRECTX_HOME}"
"${DIRECTX_ROOT}" "${ENV_DIRECTX_ROOT}" "${DIRECTX_ROOT}" "${ENV_DIRECTX_ROOT}"
"${DIRECTX_BASE}" "${ENV_DIRECTX_BASE}" "${DIRECTX_BASE}" "${ENV_DIRECTX_BASE}"
"C:/apps_x86/Microsoft DirectX SDK*" "C:/apps_x86/Microsoft 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})
# dlls are in DirectX_ROOT_DIR/Developer Runtime/x64|x86 # dlls are in DirectX_ROOT_DIR/Developer Runtime/x64|x86
# lib files are in DirectX_ROOT_DIR/Lib/x64|x86 # lib files are in DirectX_ROOT_DIR/Lib/x64|x86
if(CMAKE_CL_64) if(CMAKE_CL_64)
set(DirectX_LIBPATH_SUFFIX "x64") set(DirectX_LIBPATH_SUFFIX "x64")
else(CMAKE_CL_64) else(CMAKE_CL_64)
set(DirectX_LIBPATH_SUFFIX "x86") set(DirectX_LIBPATH_SUFFIX "x86")
endif(CMAKE_CL_64) endif(CMAKE_CL_64)
find_library(DirectX_LIBRARY NAMES d3d9 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX}) find_library(DirectX_LIBRARY NAMES d3d9 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
find_library(DirectX_D3DX9_LIBRARY NAMES d3dx9 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX}) find_library(DirectX_D3DX9_LIBRARY NAMES d3dx9 HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
find_library(DirectX_DXERR_LIBRARY NAMES DxErr HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX}) find_library(DirectX_DXERR_LIBRARY NAMES DxErr HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
find_library(DirectX_DXGUID_LIBRARY NAMES dxguid HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX}) find_library(DirectX_DXGUID_LIBRARY NAMES dxguid HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
# look for dxgi (needed by both 10 and 11) # look for dxgi (needed by both 10 and 11)
find_library(DirectX_DXGI_LIBRARY NAMES dxgi HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX}) find_library(DirectX_DXGI_LIBRARY NAMES dxgi HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
# look for d3dcompiler (needed by 11) # look for d3dcompiler (needed by 11)
find_library(DirectX_D3DCOMPILER_LIBRARY NAMES d3dcompiler HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX}) find_library(DirectX_D3DCOMPILER_LIBRARY NAMES d3dcompiler HINTS ${DirectX_LIB_SEARCH_PATH} PATH_SUFFIXES ${DirectX_LIBPATH_SUFFIX})
findpkg_finish(DirectX) findpkg_finish(DirectX)
set(DirectX_LIBRARIES ${DirectX_LIBRARIES} set(DirectX_LIBRARIES ${DirectX_LIBRARIES}
${DirectX_D3DX9_LIBRARY} ${DirectX_D3DX9_LIBRARY}
${DirectX_DXERR_LIBRARY} ${DirectX_DXERR_LIBRARY}
${DirectX_DXGUID_LIBRARY} ${DirectX_DXGUID_LIBRARY}
) )
mark_as_advanced(DirectX_D3DX9_LIBRARY DirectX_DXERR_LIBRARY DirectX_DXGUID_LIBRARY mark_as_advanced(DirectX_D3DX9_LIBRARY DirectX_DXERR_LIBRARY DirectX_DXGUID_LIBRARY
DirectX_DXGI_LIBRARY DirectX_D3DCOMPILER_LIBRARY) DirectX_DXGI_LIBRARY DirectX_D3DCOMPILER_LIBRARY)
# 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)

View File

@ -1,142 +1,142 @@
#------------------------------------------------------------------- #-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE # This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine) # (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/ # For the latest info, see http://www.ogre3d.org/
# #
# The contents of this file are placed in the public domain. Feel # The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like. # free to make use of it in any way you like.
#------------------------------------------------------------------- #-------------------------------------------------------------------
################################################################## ##################################################################
# Provides some common functionality for the FindPackage modules # Provides some common functionality for the FindPackage modules
################################################################## ##################################################################
# Begin processing of package # Begin processing of package
macro(findpkg_begin PREFIX) macro(findpkg_begin PREFIX)
if (NOT ${PREFIX}_FIND_QUIETLY) if (NOT ${PREFIX}_FIND_QUIETLY)
message(STATUS "Looking for ${PREFIX}...") message(STATUS "Looking for ${PREFIX}...")
endif () endif ()
endmacro(findpkg_begin) endmacro(findpkg_begin)
# Display a status message unless FIND_QUIETLY is set # Display a status message unless FIND_QUIETLY is set
macro(pkg_message PREFIX) macro(pkg_message PREFIX)
if (NOT ${PREFIX}_FIND_QUIETLY) if (NOT ${PREFIX}_FIND_QUIETLY)
message(STATUS ${ARGN}) message(STATUS ${ARGN})
endif () endif ()
endmacro(pkg_message) endmacro(pkg_message)
# Get environment variable, define it as ENV_$var and make sure backslashes are converted to forward slashes # Get environment variable, define it as ENV_$var and make sure backslashes are converted to forward slashes
macro(getenv_path VAR) macro(getenv_path VAR)
set(ENV_${VAR} $ENV{${VAR}}) set(ENV_${VAR} $ENV{${VAR}})
# replace won't work if var is blank # replace won't work if var is blank
if (ENV_${VAR}) if (ENV_${VAR})
string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} ) string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} )
endif () endif ()
endmacro(getenv_path) endmacro(getenv_path)
# Construct search paths for includes and libraries from a PREFIX_PATH # Construct search paths for includes and libraries from a PREFIX_PATH
macro(create_search_paths PREFIX) macro(create_search_paths PREFIX)
foreach(dir ${${PREFIX}_PREFIX_PATH}) foreach(dir ${${PREFIX}_PREFIX_PATH})
set(${PREFIX}_INC_SEARCH_PATH ${${PREFIX}_INC_SEARCH_PATH} set(${PREFIX}_INC_SEARCH_PATH ${${PREFIX}_INC_SEARCH_PATH}
${dir}/include ${dir}/include/${PREFIX} ${dir}/Headers) ${dir}/include ${dir}/include/${PREFIX} ${dir}/Headers)
set(${PREFIX}_LIB_SEARCH_PATH ${${PREFIX}_LIB_SEARCH_PATH} set(${PREFIX}_LIB_SEARCH_PATH ${${PREFIX}_LIB_SEARCH_PATH}
${dir}/lib ${dir}/lib/${PREFIX} ${dir}/Libs) ${dir}/lib ${dir}/lib/${PREFIX} ${dir}/Libs)
endforeach(dir) endforeach(dir)
set(${PREFIX}_FRAMEWORK_SEARCH_PATH ${${PREFIX}_PREFIX_PATH}) set(${PREFIX}_FRAMEWORK_SEARCH_PATH ${${PREFIX}_PREFIX_PATH})
endmacro(create_search_paths) endmacro(create_search_paths)
# clear cache variables if a certain variable changed # clear cache variables if a certain variable changed
macro(clear_if_changed TESTVAR) macro(clear_if_changed TESTVAR)
# test against internal check variable # test against internal check variable
if (NOT "${${TESTVAR}}" STREQUAL "${${TESTVAR}_INT_CHECK}") if (NOT "${${TESTVAR}}" STREQUAL "${${TESTVAR}_INT_CHECK}")
message(STATUS "${TESTVAR} changed.") message(STATUS "${TESTVAR} changed.")
foreach(var ${ARGN}) foreach(var ${ARGN})
set(${var} "NOTFOUND" CACHE STRING "x" FORCE) set(${var} "NOTFOUND" CACHE STRING "x" FORCE)
endforeach(var) endforeach(var)
endif () endif ()
set(${TESTVAR}_INT_CHECK ${${TESTVAR}} CACHE INTERNAL "x" FORCE) set(${TESTVAR}_INT_CHECK ${${TESTVAR}} CACHE INTERNAL "x" FORCE)
endmacro(clear_if_changed) endmacro(clear_if_changed)
# Try to get some hints from pkg-config, if available # Try to get some hints from pkg-config, if available
macro(use_pkgconfig PREFIX PKGNAME) macro(use_pkgconfig PREFIX PKGNAME)
find_package(PkgConfig) find_package(PkgConfig)
if (PKG_CONFIG_FOUND) if (PKG_CONFIG_FOUND)
pkg_check_modules(${PREFIX} ${PKGNAME}) pkg_check_modules(${PREFIX} ${PKGNAME})
endif () endif ()
endmacro (use_pkgconfig) endmacro (use_pkgconfig)
# Couple a set of release AND debug libraries (or frameworks) # Couple a set of release AND debug libraries (or frameworks)
macro(make_library_set PREFIX) macro(make_library_set PREFIX)
if (${PREFIX}_FWK) if (${PREFIX}_FWK)
set(${PREFIX} ${${PREFIX}_FWK}) set(${PREFIX} ${${PREFIX}_FWK})
elseif (${PREFIX}_REL AND ${PREFIX}_DBG) elseif (${PREFIX}_REL AND ${PREFIX}_DBG)
set(${PREFIX} optimized ${${PREFIX}_REL} debug ${${PREFIX}_DBG}) set(${PREFIX} optimized ${${PREFIX}_REL} debug ${${PREFIX}_DBG})
elseif (${PREFIX}_REL) elseif (${PREFIX}_REL)
set(${PREFIX} ${${PREFIX}_REL}) set(${PREFIX} ${${PREFIX}_REL})
elseif (${PREFIX}_DBG) elseif (${PREFIX}_DBG)
set(${PREFIX} ${${PREFIX}_DBG}) set(${PREFIX} ${${PREFIX}_DBG})
endif () endif ()
endmacro(make_library_set) endmacro(make_library_set)
# Generate debug names from given release names # Generate debug names from given release names
macro(get_debug_names PREFIX) macro(get_debug_names PREFIX)
foreach(i ${${PREFIX}}) foreach(i ${${PREFIX}})
set(${PREFIX}_DBG ${${PREFIX}_DBG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i}) set(${PREFIX}_DBG ${${PREFIX}_DBG} ${i}d ${i}D ${i}_d ${i}_D ${i}_debug ${i})
endforeach(i) endforeach(i)
endmacro(get_debug_names) endmacro(get_debug_names)
# Add the parent dir from DIR to VAR # Add the parent dir from DIR to VAR
macro(add_parent_dir VAR DIR) macro(add_parent_dir VAR DIR)
get_filename_component(${DIR}_TEMP "${${DIR}}/.." ABSOLUTE) get_filename_component(${DIR}_TEMP "${${DIR}}/.." ABSOLUTE)
set(${VAR} ${${VAR}} ${${DIR}_TEMP}) set(${VAR} ${${VAR}} ${${DIR}_TEMP})
endmacro(add_parent_dir) endmacro(add_parent_dir)
# Do the final processing for the package find. # Do the final processing for the package find.
macro(findpkg_finish PREFIX) macro(findpkg_finish PREFIX)
# skip if already processed during this run # skip if already processed during this run
if (NOT ${PREFIX}_FOUND) if (NOT ${PREFIX}_FOUND)
if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY) if (${PREFIX}_INCLUDE_DIR AND ${PREFIX}_LIBRARY)
set(${PREFIX}_FOUND TRUE) set(${PREFIX}_FOUND TRUE)
set(${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR}) set(${PREFIX}_INCLUDE_DIRS ${${PREFIX}_INCLUDE_DIR})
set(${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY}) set(${PREFIX}_LIBRARIES ${${PREFIX}_LIBRARY})
if (NOT ${PREFIX}_FIND_QUIETLY) if (NOT ${PREFIX}_FIND_QUIETLY)
message(STATUS "Found ${PREFIX}: ${${PREFIX}_LIBRARIES}") message(STATUS "Found ${PREFIX}: ${${PREFIX}_LIBRARIES}")
endif () endif ()
else () else ()
if (NOT ${PREFIX}_FIND_QUIETLY) if (NOT ${PREFIX}_FIND_QUIETLY)
message(STATUS "Could not locate ${PREFIX}") message(STATUS "Could not locate ${PREFIX}")
endif () endif ()
if (${PREFIX}_FIND_REQUIRED) if (${PREFIX}_FIND_REQUIRED)
message(FATAL_ERROR "Required library ${PREFIX} not found! Install the library (including dev packages) and try again. If the library is already installed, set the missing variables manually in cmake.") message(FATAL_ERROR "Required library ${PREFIX} not found! Install the library (including dev packages) and try again. If the library is already installed, set the missing variables manually in cmake.")
endif () endif ()
endif () endif ()
mark_as_advanced(${PREFIX}_INCLUDE_DIR ${PREFIX}_LIBRARY ${PREFIX}_LIBRARY_REL ${PREFIX}_LIBRARY_DBG ${PREFIX}_LIBRARY_FWK) mark_as_advanced(${PREFIX}_INCLUDE_DIR ${PREFIX}_LIBRARY ${PREFIX}_LIBRARY_REL ${PREFIX}_LIBRARY_DBG ${PREFIX}_LIBRARY_FWK)
endif () endif ()
endmacro(findpkg_finish) endmacro(findpkg_finish)
# Slightly customised framework finder # Slightly customised framework finder
MACRO(findpkg_framework fwk) MACRO(findpkg_framework fwk)
IF(APPLE) IF(APPLE)
SET(${fwk}_FRAMEWORK_PATH SET(${fwk}_FRAMEWORK_PATH
${${fwk}_FRAMEWORK_SEARCH_PATH} ${${fwk}_FRAMEWORK_SEARCH_PATH}
${CMAKE_FRAMEWORK_PATH} ${CMAKE_FRAMEWORK_PATH}
~/Library/Frameworks ~/Library/Frameworks
/Library/Frameworks /Library/Frameworks
/System/Library/Frameworks /System/Library/Frameworks
/Network/Library/Frameworks /Network/Library/Frameworks
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/ /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/
) )
FOREACH(dir ${${fwk}_FRAMEWORK_PATH}) FOREACH(dir ${${fwk}_FRAMEWORK_PATH})
SET(fwkpath ${dir}/${fwk}.framework) SET(fwkpath ${dir}/${fwk}.framework)
IF(EXISTS ${fwkpath}) IF(EXISTS ${fwkpath})
SET(${fwk}_FRAMEWORK_INCLUDES ${${fwk}_FRAMEWORK_INCLUDES} SET(${fwk}_FRAMEWORK_INCLUDES ${${fwk}_FRAMEWORK_INCLUDES}
${fwkpath}/Headers ${fwkpath}/PrivateHeaders) ${fwkpath}/Headers ${fwkpath}/PrivateHeaders)
if (NOT ${fwk}_LIBRARY_FWK) if (NOT ${fwk}_LIBRARY_FWK)
SET(${fwk}_LIBRARY_FWK "-framework ${fwk}") SET(${fwk}_LIBRARY_FWK "-framework ${fwk}")
endif () endif ()
ENDIF(EXISTS ${fwkpath}) ENDIF(EXISTS ${fwkpath})
ENDFOREACH(dir) ENDFOREACH(dir)
ENDIF(APPLE) ENDIF(APPLE)
ENDMACRO(findpkg_framework) ENDMACRO(findpkg_framework)

View File

@ -1,48 +1,48 @@
#------------------------------------------------------------------- #-------------------------------------------------------------------
# This file is part of the CMake build system for OGRE # This file is part of the CMake build system for OGRE
# (Object-oriented Graphics Rendering Engine) # (Object-oriented Graphics Rendering Engine)
# For the latest info, see http://www.ogre3d.org/ # For the latest info, see http://www.ogre3d.org/
# #
# The contents of this file are placed in the public domain. Feel # The contents of this file are placed in the public domain. Feel
# free to make use of it in any way you like. # free to make use of it in any way you like.
#------------------------------------------------------------------- #-------------------------------------------------------------------
# - Try to find ZLIB # - Try to find ZLIB
# Once done, this will define # Once done, this will define
# #
# ZLIB_FOUND - system has ZLIB # ZLIB_FOUND - system has ZLIB
# ZLIB_INCLUDE_DIRS - the ZLIB include directories # ZLIB_INCLUDE_DIRS - the ZLIB include directories
# ZLIB_LIBRARIES - link these to use ZLIB # ZLIB_LIBRARIES - link these to use ZLIB
include(FindPkgMacros) include(FindPkgMacros)
findpkg_begin(ZLIB) findpkg_begin(ZLIB)
# Get path, convert backslashes as ${ENV_${var}} # Get path, convert backslashes as ${ENV_${var}}
getenv_path(ZLIB_HOME) getenv_path(ZLIB_HOME)
# construct search paths # construct search paths
set(ZLIB_PREFIX_PATH ${ZLIB_HOME} ${ENV_ZLIB_HOME}) set(ZLIB_PREFIX_PATH ${ZLIB_HOME} ${ENV_ZLIB_HOME})
create_search_paths(ZLIB) create_search_paths(ZLIB)
# redo search if prefix path changed # redo search if prefix path changed
clear_if_changed(ZLIB_PREFIX_PATH clear_if_changed(ZLIB_PREFIX_PATH
ZLIB_LIBRARY_FWK ZLIB_LIBRARY_FWK
ZLIB_LIBRARY_REL ZLIB_LIBRARY_REL
ZLIB_LIBRARY_DBG ZLIB_LIBRARY_DBG
ZLIB_INCLUDE_DIR ZLIB_INCLUDE_DIR
) )
set(ZLIB_LIBRARY_NAMES z zlib zdll) set(ZLIB_LIBRARY_NAMES z zlib zdll)
get_debug_names(ZLIB_LIBRARY_NAMES) get_debug_names(ZLIB_LIBRARY_NAMES)
use_pkgconfig(ZLIB_PKGC zzip-zlib-config) use_pkgconfig(ZLIB_PKGC zzip-zlib-config)
findpkg_framework(ZLIB) findpkg_framework(ZLIB)
find_path(ZLIB_INCLUDE_DIR NAMES zlib.h HINTS ${ZLIB_INC_SEARCH_PATH} ${ZLIB_PKGC_INCLUDE_DIRS}) find_path(ZLIB_INCLUDE_DIR NAMES zlib.h HINTS ${ZLIB_INC_SEARCH_PATH} ${ZLIB_PKGC_INCLUDE_DIRS})
find_library(ZLIB_LIBRARY_REL NAMES ${ZLIB_LIBRARY_NAMES} HINTS ${ZLIB_LIB_SEARCH_PATH} ${ZLIB_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel) find_library(ZLIB_LIBRARY_REL NAMES ${ZLIB_LIBRARY_NAMES} HINTS ${ZLIB_LIB_SEARCH_PATH} ${ZLIB_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" release relwithdebinfo minsizerel)
find_library(ZLIB_LIBRARY_DBG NAMES ${ZLIB_LIBRARY_NAMES_DBG} HINTS ${ZLIB_LIB_SEARCH_PATH} ${ZLIB_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug) find_library(ZLIB_LIBRARY_DBG NAMES ${ZLIB_LIBRARY_NAMES_DBG} HINTS ${ZLIB_LIB_SEARCH_PATH} ${ZLIB_PKGC_LIBRARY_DIRS} PATH_SUFFIXES "" debug)
make_library_set(ZLIB_LIBRARY) make_library_set(ZLIB_LIBRARY)
findpkg_finish(ZLIB) findpkg_finish(ZLIB)

View File

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

View File

@ -0,0 +1,16 @@
# this one sets internal to crosscompile (in theory)
SET(CMAKE_SYSTEM_NAME Windows)
# the minimalistic settings
SET(CMAKE_C_COMPILER "/usr/bin/x86_64-w64-mingw32-gcc")
SET(CMAKE_CXX_COMPILER "/usr/bin/x86_64-w64-mingw32-g++")
SET(CMAKE_RC_COMPILER "/usr/bin/x86_64-w64-mingw32-windres")
# where is the target (so called staging) environment
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
# search for programs in the build host directories (default BOTH)
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -5,21 +5,21 @@ 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
LIST(APPEND ${SourcesVar} ${PrecompiledSource}) LIST(APPEND ${SourcesVar} ${PrecompiledSource})
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER) ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)

View File

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

View File

@ -2,11 +2,11 @@
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,22 +23,21 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER #ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
@ -47,131 +46,136 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "3DSLoader.h" #include "3DSLoader.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "SplitLargeMeshes.h" #include "SplitLargeMeshes.h"
#include "StringComparison.h"
#include "../include/assimp/IOSystem.hpp"
#include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/Exporter.hpp"
#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) 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
@ -181,378 +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);
WriteMeshes(); WriteMaterials();
WriteMaterials(); 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:
ai_assert(false); shading_mode_out = Discreet3DS::Flat;
}; 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);
} }

View File

@ -2,11 +2,11 @@
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -45,13 +45,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_3DSEXPORTER_H_INC #define AI_3DSEXPORTER_H_INC
#include <map> #include <map>
#include <boost/shared_ptr.hpp>
#include "StreamWriter.h" #include "StreamWriter.h"
#include "./../include/assimp/material.h"
struct aiScene; struct aiScene;
struct aiNode; struct aiNode;
struct aiMaterial;
struct aiMesh;
namespace Assimp namespace Assimp
{ {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -60,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;
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,280 +1,282 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file 3DSLoader.h /** @file 3DSLoader.h
* @brief 3DS File format loader * @brief 3DS File format loader
*/ */
#ifndef AI_3DSIMPORTER_H_INC #ifndef AI_3DSIMPORTER_H_INC
#define AI_3DSIMPORTER_H_INC #define AI_3DSIMPORTER_H_INC
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
struct aiNode; #include "3DSHelper.h"
#include "3DSHelper.h" #include "StreamReader.h"
namespace Assimp { struct aiNode;
namespace Assimp {
using namespace D3DS;
// --------------------------------------------------------------------------------- using namespace D3DS;
/** Importer class for 3D Studio r3 and r4 3DS files
*/ // ---------------------------------------------------------------------------------
class Discreet3DSImporter : public BaseImporter /** Importer class for 3D Studio r3 and r4 3DS files
{ */
public: class Discreet3DSImporter : public BaseImporter
{
Discreet3DSImporter(); public:
~Discreet3DSImporter();
Discreet3DSImporter();
public: ~Discreet3DSImporter();
// ------------------------------------------------------------------- public:
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. // -------------------------------------------------------------------
*/ /** Returns whether the class can handle the format of the given file.
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, * See BaseImporter::CanRead() for details.
bool checkSig) const; */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
// ------------------------------------------------------------------- bool checkSig) const;
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration // -------------------------------------------------------------------
* basing on the Importer's configuration property list. /** Called prior to ReadFile().
*/ * The function is a request to the importer to update its configuration
void SetupProperties(const Importer* pImp); * basing on the Importer's configuration property list.
*/
protected: void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- protected:
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details // -------------------------------------------------------------------
*/ /** Return importer meta information.
const aiImporterDesc* GetInfo () const; * See #BaseImporter::GetInfo for the details
*/
// ------------------------------------------------------------------- const aiImporterDesc* GetInfo () const;
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details // -------------------------------------------------------------------
*/ /** Imports the given file into the given scene structure.
void InternReadFile( const std::string& pFile, aiScene* pScene, * See BaseImporter::InternReadFile() for details
IOSystem* pIOHandler); */
void InternReadFile( const std::string& pFile, aiScene* pScene,
// ------------------------------------------------------------------- IOSystem* pIOHandler);
/** Converts a temporary material to the outer representation
*/ // -------------------------------------------------------------------
void ConvertMaterial(D3DS::Material& p_cMat, /** Converts a temporary material to the outer representation
aiMaterial& p_pcOut); */
void ConvertMaterial(D3DS::Material& p_cMat,
// ------------------------------------------------------------------- aiMaterial& p_pcOut);
/** Read a chunk
* // -------------------------------------------------------------------
* @param pcOut Receives the current chunk /** Read a chunk
*/ *
void ReadChunk(Discreet3DS::Chunk* pcOut); * @param pcOut Receives the current chunk
*/
// ------------------------------------------------------------------- void ReadChunk(Discreet3DS::Chunk* pcOut);
/** Parse a percentage chunk. mCurrent will point to the next
* chunk behind afterwards. If no percentage chunk is found // -------------------------------------------------------------------
* QNAN is returned. /** Parse a percentage chunk. mCurrent will point to the next
*/ * chunk behind afterwards. If no percentage chunk is found
float ParsePercentageChunk(); * QNAN is returned.
*/
// ------------------------------------------------------------------- float ParsePercentageChunk();
/** Parse a color chunk. mCurrent will point to the next
* chunk behind afterwards. If no color chunk is found // -------------------------------------------------------------------
* QNAN is returned in all members. /** Parse a color chunk. mCurrent will point to the next
*/ * chunk behind afterwards. If no color chunk is found
void ParseColorChunk(aiColor3D* p_pcOut, * QNAN is returned in all members.
bool p_bAcceptPercent = true); */
void ParseColorChunk(aiColor3D* p_pcOut,
bool p_bAcceptPercent = true);
// -------------------------------------------------------------------
/** Skip a chunk in the file
*/ // -------------------------------------------------------------------
void SkipChunk(); /** Skip a chunk in the file
*/
// ------------------------------------------------------------------- void SkipChunk();
/** Generate the nodegraph
*/ // -------------------------------------------------------------------
void GenerateNodeGraph(aiScene* pcOut); /** Generate the nodegraph
*/
// ------------------------------------------------------------------- void GenerateNodeGraph(aiScene* pcOut);
/** Parse a main top-level chunk in the file
*/ // -------------------------------------------------------------------
void ParseMainChunk(); /** Parse a main top-level chunk in the file
*/
// ------------------------------------------------------------------- void ParseMainChunk();
/** Parse a top-level chunk in the file
*/ // -------------------------------------------------------------------
void ParseChunk(const char* name, unsigned int num); /** Parse a top-level chunk in the file
*/
// ------------------------------------------------------------------- void ParseChunk(const char* name, unsigned int num);
/** Parse a top-level editor chunk in the file
*/ // -------------------------------------------------------------------
void ParseEditorChunk(); /** Parse a top-level editor chunk in the file
*/
// ------------------------------------------------------------------- void ParseEditorChunk();
/** Parse a top-level object chunk in the file
*/ // -------------------------------------------------------------------
void ParseObjectChunk(); /** Parse a top-level object chunk in the file
*/
// ------------------------------------------------------------------- void ParseObjectChunk();
/** Parse a material chunk in the file
*/ // -------------------------------------------------------------------
void ParseMaterialChunk(); /** Parse a material chunk in the file
*/
// ------------------------------------------------------------------- void ParseMaterialChunk();
/** Parse a mesh chunk in the file
*/ // -------------------------------------------------------------------
void ParseMeshChunk(); /** Parse a mesh chunk in the file
*/
// ------------------------------------------------------------------- void ParseMeshChunk();
/** Parse a light chunk in the file
*/ // -------------------------------------------------------------------
void ParseLightChunk(); /** Parse a light chunk in the file
*/
// ------------------------------------------------------------------- void ParseLightChunk();
/** Parse a camera chunk in the file
*/ // -------------------------------------------------------------------
void ParseCameraChunk(); /** Parse a camera chunk in the file
*/
// ------------------------------------------------------------------- void ParseCameraChunk();
/** Parse a face list chunk in the file
*/ // -------------------------------------------------------------------
void ParseFaceChunk(); /** Parse a face list chunk in the file
*/
// ------------------------------------------------------------------- void ParseFaceChunk();
/** Parse a keyframe chunk in the file
*/ // -------------------------------------------------------------------
void ParseKeyframeChunk(); /** Parse a keyframe chunk in the file
*/
// ------------------------------------------------------------------- void ParseKeyframeChunk();
/** Parse a hierarchy chunk in the file
*/ // -------------------------------------------------------------------
void ParseHierarchyChunk(uint16_t parent); /** Parse a hierarchy chunk in the file
*/
// ------------------------------------------------------------------- void ParseHierarchyChunk(uint16_t parent);
/** Parse a texture chunk in the file
*/ // -------------------------------------------------------------------
void ParseTextureChunk(D3DS::Texture* pcOut); /** Parse a texture chunk in the file
*/
// ------------------------------------------------------------------- void ParseTextureChunk(D3DS::Texture* pcOut);
/** Convert the meshes in the file
*/ // -------------------------------------------------------------------
void ConvertMeshes(aiScene* pcOut); /** Convert the meshes in the file
*/
// ------------------------------------------------------------------- void ConvertMeshes(aiScene* pcOut);
/** Replace the default material in the scene
*/ // -------------------------------------------------------------------
void ReplaceDefaultMaterial(); /** Replace the default material in the scene
*/
// ------------------------------------------------------------------- void ReplaceDefaultMaterial();
/** Convert the whole scene
*/ // -------------------------------------------------------------------
void ConvertScene(aiScene* pcOut); /** Convert the whole scene
*/
// ------------------------------------------------------------------- void ConvertScene(aiScene* pcOut);
/** generate unique vertices for a mesh
*/ // -------------------------------------------------------------------
void MakeUnique(D3DS::Mesh& sMesh); /** generate unique vertices for a mesh
*/
// ------------------------------------------------------------------- void MakeUnique(D3DS::Mesh& sMesh);
/** Add a node to the node graph
*/ // -------------------------------------------------------------------
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn, /** Add a node to the node graph
aiMatrix4x4& absTrafo); */
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
// ------------------------------------------------------------------- aiMatrix4x4& absTrafo);
/** Search for a node in the graph.
* Called recursively // -------------------------------------------------------------------
*/ /** Search for a node in the graph.
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent); * Called recursively
*/
// ------------------------------------------------------------------- void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
/** Apply the master scaling factor to the mesh
*/ // -------------------------------------------------------------------
void ApplyMasterScale(aiScene* pScene); /** Apply the master scaling factor to the mesh
*/
// ------------------------------------------------------------------- void ApplyMasterScale(aiScene* pScene);
/** Clamp all indices in the file to a valid range
*/ // -------------------------------------------------------------------
void CheckIndices(D3DS::Mesh& sMesh); /** Clamp all indices in the file to a valid range
*/
// ------------------------------------------------------------------- void CheckIndices(D3DS::Mesh& sMesh);
/** Skip the TCB info in a track key
*/ // -------------------------------------------------------------------
void SkipTCBInfo(); /** Skip the TCB info in a track key
*/
protected: void SkipTCBInfo();
/** Stream to read from */ protected:
StreamReaderLE* stream;
/** Stream to read from */
/** Last touched node index */ StreamReaderLE* stream;
short mLastNodeIndex;
/** Last touched node index */
/** Current node, root node */ short mLastNodeIndex;
D3DS::Node* mCurrentNode, *mRootNode;
/** Current node, root node */
/** Scene under construction */ D3DS::Node* mCurrentNode, *mRootNode;
D3DS::Scene* mScene;
/** Scene under construction */
/** Ambient base color of the scene */ D3DS::Scene* mScene;
aiColor3D mClrAmbient;
/** Ambient base color of the scene */
/** Master scaling factor of the scene */ aiColor3D mClrAmbient;
float mMasterScale;
/** Master scaling factor of the scene */
/** Path to the background image of the scene */ float mMasterScale;
std::string mBackgroundImage;
bool bHasBG; /** Path to the background image of the scene */
std::string mBackgroundImage;
/** true if PRJ file */ bool bHasBG;
bool bIsPrj;
}; /** true if PRJ file */
bool bIsPrj;
} // end of namespace Assimp };
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER } // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // AI_3DSIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,267 +1,274 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ACLoader.h /** @file ACLoader.h
* @brief Declaration of the .ac importer class. * @brief Declaration of the .ac importer class.
*/ */
#ifndef AI_AC3DLOADER_H_INCLUDED #ifndef AI_AC3DLOADER_H_INCLUDED
#define AI_AC3DLOADER_H_INCLUDED #define AI_AC3DLOADER_H_INCLUDED
#include <vector> #include <vector>
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
namespace Assimp { struct aiNode;
struct aiMesh;
// --------------------------------------------------------------------------- struct aiMaterial;
/** AC3D (*.ac) importer class struct aiLight;
*/
class AC3DImporter : public BaseImporter
{ namespace Assimp {
public:
AC3DImporter(); // ---------------------------------------------------------------------------
~AC3DImporter(); /** AC3D (*.ac) importer class
*/
class AC3DImporter : public BaseImporter
{
// Represents an AC3D material public:
struct Material AC3DImporter();
{ ~AC3DImporter();
Material()
: rgb (0.6f,0.6f,0.6f)
, spec (1.f,1.f,1.f)
, shin (0.f) // Represents an AC3D material
, trans (0.f) struct Material
{} {
Material()
// base color of the material : rgb (0.6f,0.6f,0.6f)
aiColor3D rgb; , spec (1.f,1.f,1.f)
, shin (0.f)
// ambient color of the material , trans (0.f)
aiColor3D amb; {}
// emissive color of the material // base color of the material
aiColor3D emis; aiColor3D rgb;
// specular color of the material // ambient color of the material
aiColor3D spec; aiColor3D amb;
// shininess exponent // emissive color of the material
float shin; aiColor3D emis;
// transparency. 0 == opaque // specular color of the material
float trans; aiColor3D spec;
// name of the material. optional. // shininess exponent
std::string name; float shin;
};
// transparency. 0 == opaque
// Represents an AC3D surface float trans;
struct Surface
{ // name of the material. optional.
Surface() std::string name;
: mat (0) };
, flags (0)
{} // Represents an AC3D surface
struct Surface
unsigned int mat,flags; {
Surface()
typedef std::pair<unsigned int, aiVector2D > SurfaceEntry; : mat (0)
std::vector< SurfaceEntry > entries; , flags (0)
}; {}
// Represents an AC3D object unsigned int mat,flags;
struct Object
{ typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
Object() std::vector< SurfaceEntry > entries;
: type (World) };
, name( "" )
, children() // Represents an AC3D object
, texture( "" ) struct Object
, texRepeat( 1.f, 1.f ) {
, texOffset( 0.0f, 0.0f ) Object()
, rotation() : type (World)
, translation() , name( "" )
, vertices() , children()
, surfaces() , texture( "" )
, numRefs (0) , texRepeat( 1.f, 1.f )
, subDiv (0) , texOffset( 0.0f, 0.0f )
{} , rotation()
, translation()
// Type description , vertices()
enum Type , surfaces()
{ , numRefs (0)
World = 0x0, , subDiv (0)
Poly = 0x1, , crease()
Group = 0x2, {}
Light = 0x4
} type; // Type description
enum Type
// name of the object {
std::string name; World = 0x0,
Poly = 0x1,
// object children Group = 0x2,
std::vector<Object> children; Light = 0x4
} type;
// texture to be assigned to all surfaces of the object
std::string texture; // name of the object
std::string name;
// texture repat factors (scaling for all coordinates)
aiVector2D texRepeat, texOffset; // object children
std::vector<Object> children;
// rotation matrix
aiMatrix3x3 rotation; // texture to be assigned to all surfaces of the object
std::string texture;
// translation vector
aiVector3D translation; // texture repat factors (scaling for all coordinates)
aiVector2D texRepeat, texOffset;
// vertices
std::vector<aiVector3D> vertices; // rotation matrix
aiMatrix3x3 rotation;
// surfaces
std::vector<Surface> surfaces; // translation vector
aiVector3D translation;
// number of indices (= num verts in verbose format)
unsigned int numRefs; // vertices
std::vector<aiVector3D> vertices;
// number of subdivisions to be performed on the
// imported data // surfaces
unsigned int subDiv; std::vector<Surface> surfaces;
// max angle limit for smoothing // number of indices (= num verts in verbose format)
float crease; unsigned int numRefs;
};
// number of subdivisions to be performed on the
// imported data
public: unsigned int subDiv;
// ------------------------------------------------------------------- // max angle limit for smoothing
/** Returns whether the class can handle the format of the given file. float crease;
* See BaseImporter::CanRead() for details. };
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; public:
protected: // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
// ------------------------------------------------------------------- * See BaseImporter::CanRead() for details.
/** Return importer meta information. */
* See #BaseImporter::GetInfo for the details */ bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
const aiImporterDesc* GetInfo () const; bool checkSig) const;
// ------------------------------------------------------------------- protected:
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details*/ // -------------------------------------------------------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, /** Return importer meta information.
IOSystem* pIOHandler); * See #BaseImporter::GetInfo for the details */
const aiImporterDesc* GetInfo () const;
// -------------------------------------------------------------------
/** Called prior to ReadFile(). // -------------------------------------------------------------------
* The function is a request to the importer to update its configuration /** Imports the given file into the given scene structure.
* basing on the Importer's configuration property list.*/ * See BaseImporter::InternReadFile() for details*/
void SetupProperties(const Importer* pImp); void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
private:
// -------------------------------------------------------------------
// ------------------------------------------------------------------- /** Called prior to ReadFile().
/** Get the next line from the file. * The function is a request to the importer to update its configuration
* @return false if the end of the file was reached*/ * basing on the Importer's configuration property list.*/
bool GetNextLine(); void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- private:
/** Load the object section. This method is called recursively to
* load subobjects, the method returns after a 'kids 0' was // -------------------------------------------------------------------
* encountered. /** Get the next line from the file.
* @objects List of output objects*/ * @return false if the end of the file was reached*/
void LoadObjectSection(std::vector<Object>& objects); bool GetNextLine();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert all objects into meshes and nodes. /** Load the object section. This method is called recursively to
* @param object Current object to work on * load subobjects, the method returns after a 'kids 0' was
* @param meshes Pointer to the list of output meshes * encountered.
* @param outMaterials List of output materials * @objects List of output objects*/
* @param materials Material list void LoadObjectSection(std::vector<Object>& objects);
* @param Scenegraph node for the object */
aiNode* ConvertObjectSection(Object& object, // -------------------------------------------------------------------
std::vector<aiMesh*>& meshes, /** Convert all objects into meshes and nodes.
std::vector<aiMaterial*>& outMaterials, * @param object Current object to work on
const std::vector<Material>& materials, * @param meshes Pointer to the list of output meshes
aiNode* parent = NULL); * @param outMaterials List of output materials
* @param materials Material list
// ------------------------------------------------------------------- * @param Scenegraph node for the object */
/** Convert a material aiNode* ConvertObjectSection(Object& object,
* @param object Current object std::vector<aiMesh*>& meshes,
* @param matSrc Source material description std::vector<aiMaterial*>& outMaterials,
* @param matDest Destination material to be filled */ const std::vector<Material>& materials,
void ConvertMaterial(const Object& object, aiNode* parent = NULL);
const Material& matSrc,
aiMaterial& matDest); // -------------------------------------------------------------------
/** Convert a material
private: * @param object Current object
* @param matSrc Source material description
* @param matDest Destination material to be filled */
// points to the next data line void ConvertMaterial(const Object& object,
const char* buffer; const Material& matSrc,
aiMaterial& matDest);
// Configuration option: if enabled, up to two meshes
// are generated per material: those faces who have private:
// their bf cull flags set are separated.
bool configSplitBFCull;
// points to the next data line
// Configuration switch: subdivision surfaces are only const char* buffer;
// evaluated if the value is true.
bool configEvalSubdivision; // Configuration option: if enabled, up to two meshes
// are generated per material: those faces who have
// counts how many objects we have in the tree. // their bf cull flags set are separated.
// basing on this information we can find a bool configSplitBFCull;
// good estimate how many meshes we'll have in the final scene.
unsigned int mNumMeshes; // Configuration switch: subdivision surfaces are only
// evaluated if the value is true.
// current list of light sources bool configEvalSubdivision;
std::vector<aiLight*>* mLights;
// counts how many objects we have in the tree.
// name counters // basing on this information we can find a
unsigned int lights, groups, polys, worlds; // good estimate how many meshes we'll have in the final scene.
}; unsigned int mNumMeshes;
} // end of namespace Assimp // current list of light sources
std::vector<aiLight*>* mLights;
#endif // AI_AC3DIMPORTER_H_INC
// name counters
unsigned int lights, groups, polys, worlds;
};
} // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,205 +1,205 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ASELoader.h /** @file ASELoader.h
* @brief Definition of the .ASE importer class. * @brief Definition of the .ASE importer class.
*/ */
#ifndef AI_ASELOADER_H_INCLUDED #ifndef AI_ASELOADER_H_INCLUDED
#define AI_ASELOADER_H_INCLUDED #define AI_ASELOADER_H_INCLUDED
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
struct aiNode; struct aiNode;
#include "ASEParser.h" #include "ASEParser.h"
namespace Assimp { 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
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,11 +2,11 @@
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,11 @@
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -24,16 +24,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -48,9 +48,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseImporter.h" #include "BaseImporter.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
struct aiMesh;
struct aiNode;
struct aiBone;
struct aiMaterial;
struct aiMaterialProperty;
struct aiNodeAnim;
struct aiAnimation;
struct aiTexture;
struct aiLight;
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
@ -63,15 +74,15 @@ private:
protected: protected:
public: public:
virtual bool CanRead( virtual bool CanRead(
const std::string& pFile, const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const; ) const;
virtual const aiImporterDesc* GetInfo() const; virtual const aiImporterDesc* GetInfo() const;
virtual void InternReadFile( virtual void InternReadFile(
const std::string& pFile, const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
void ReadBinaryScene( IOStream * stream, aiScene* pScene ); void ReadBinaryScene( IOStream * stream, aiScene* pScene );

File diff suppressed because it is too large Load Diff

View File

@ -1,129 +1,129 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file AssimpCExport.cpp /** @file AssimpCExport.cpp
Assimp C export interface. See Exporter.cpp for some notes. Assimp C export interface. See Exporter.cpp for some notes.
*/ */
#include "AssimpPCH.h" #ifndef ASSIMP_BUILD_NO_EXPORT
#include "CInterfaceIOWrapper.h"
#ifndef ASSIMP_BUILD_NO_EXPORT #include "SceneCombiner.h"
#include "CInterfaceIOWrapper.h" #include "ScenePrivate.h"
#include "SceneCombiner.h" #include "../include/assimp/Exporter.hpp"
using namespace Assimp; 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

View File

@ -1,135 +0,0 @@
// Actually just a dummy, used by the compiler to build the precompiled header.
#include "AssimpPCH.h"
#include "./../include/assimp/version.h"
static const unsigned int MajorVersion = 3;
static const unsigned int MinorVersion = 1;
// --------------------------------------------------------------------------------
// Legal information string - dont't remove this.
static const char* LEGAL_INFORMATION =
"Open Asset Import Library (Assimp).\n"
"A free C/C++ library to import various 3D file formats into applications\n\n"
"(c) 2008-2010, assimp team\n"
"License under the terms and conditions of the 3-clause BSD license\n"
"http://assimp.sourceforge.net\n"
;
// ------------------------------------------------------------------------------------------------
// Get legal string
ASSIMP_API const char* aiGetLegalString () {
return LEGAL_INFORMATION;
}
// ------------------------------------------------------------------------------------------------
// Get Assimp minor version
ASSIMP_API unsigned int aiGetVersionMinor () {
return MinorVersion;
}
// ------------------------------------------------------------------------------------------------
// Get Assimp major version
ASSIMP_API unsigned int aiGetVersionMajor () {
return MajorVersion;
}
// ------------------------------------------------------------------------------------------------
// Get flags used for compilation
ASSIMP_API unsigned int aiGetCompileFlags () {
unsigned int flags = 0;
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
flags |= ASSIMP_CFLAGS_NOBOOST;
#endif
#ifdef ASSIMP_BUILD_SINGLETHREADED
flags |= ASSIMP_CFLAGS_SINGLETHREADED;
#endif
#ifdef ASSIMP_BUILD_DEBUG
flags |= ASSIMP_CFLAGS_DEBUG;
#endif
#ifdef ASSIMP_BUILD_DLL_EXPORT
flags |= ASSIMP_CFLAGS_SHARED;
#endif
#ifdef _STLPORT_VERSION
flags |= ASSIMP_CFLAGS_STLPORT;
#endif
return flags;
}
// include current build revision, which is even updated from time to time -- :-)
#include "revision.h"
// ------------------------------------------------------------------------------------------------
ASSIMP_API unsigned int aiGetVersionRevision ()
{
return GitVersion;
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API aiScene::aiScene()
: mFlags(0)
, mRootNode(NULL)
, mNumMeshes(0)
, mMeshes(NULL)
, mNumMaterials(0)
, mMaterials(NULL)
, mNumAnimations(0)
, mAnimations(NULL)
, mNumTextures(0)
, mTextures(NULL)
, mNumLights(0)
, mLights(NULL)
, mNumCameras(0)
, mCameras(NULL)
, mPrivate(new Assimp::ScenePrivateData())
{
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API aiScene::~aiScene()
{
// delete all sub-objects recursively
delete mRootNode;
// To make sure we won't crash if the data is invalid it's
// much better to check whether both mNumXXX and mXXX are
// valid instead of relying on just one of them.
if (mNumMeshes && mMeshes)
for( unsigned int a = 0; a < mNumMeshes; a++)
delete mMeshes[a];
delete [] mMeshes;
if (mNumMaterials && mMaterials)
for( unsigned int a = 0; a < mNumMaterials; a++)
delete mMaterials[a];
delete [] mMaterials;
if (mNumAnimations && mAnimations)
for( unsigned int a = 0; a < mNumAnimations; a++)
delete mAnimations[a];
delete [] mAnimations;
if (mNumTextures && mTextures)
for( unsigned int a = 0; a < mNumTextures; a++)
delete mTextures[a];
delete [] mTextures;
if (mNumLights && mLights)
for( unsigned int a = 0; a < mNumLights; a++)
delete mLights[a];
delete [] mLights;
if (mNumCameras && mCameras)
for( unsigned int a = 0; a < mNumCameras; a++)
delete mCameras[a];
delete [] mCameras;
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
}

View File

@ -1,162 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file AssimpPCH.h
* PCH master include. Every unit in Assimp has to include it.
*/
#ifndef ASSIMP_PCH_INCLUDED
#define ASSIMP_PCH_INCLUDED
#define ASSIMP_INTERNAL_BUILD
// ----------------------------------------------------------------------------------------
/* General compile config taken from defs.h. It is important that the user compiles
* using exactly the same settings in defs.h. Settings in AssimpPCH.h may differ,
* they won't affect the public API.
*/
#include "../include/assimp/defs.h"
// Include our stdint.h replacement header for MSVC, take the global header for gcc/mingw
#if defined( _MSC_VER) && (_MSC_VER < 1600)
# include "../include/assimp/Compiler/pstdint.h"
#else
# include <stdint.h>
#endif
/* Undefine the min/max macros defined by some platform headers (namely Windows.h) to
* avoid obvious conflicts with std::min() and std::max().
*/
#undef min
#undef max
/* Concatenate two tokens after evaluating them
*/
#define _AI_CONCAT(a,b) a ## b
#define AI_CONCAT(a,b) _AI_CONCAT(a,b)
/* Helper macro to set a pointer to NULL in debug builds
*/
#if (defined ASSIMP_BUILD_DEBUG)
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
#else
# define AI_DEBUG_INVALIDATE_PTR(x)
#endif
/* Beginning with MSVC8 some C string manipulation functions are mapped to their _safe_
* counterparts (e.g. _itoa_s). This avoids a lot of trouble with deprecation warnings.
*/
#if _MSC_VER >= 1400 && !(defined _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
# define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
#endif
/* size_t to unsigned int, possible loss of data. The compiler is right with his warning
* but this loss of data won't be a problem for us. So shut up, little boy.
*/
#ifdef _MSC_VER
# pragma warning (disable : 4267)
#endif
// ----------------------------------------------------------------------------------------
/* Actually that's not required for MSVC. It is included somewhere in the deeper parts of
* the MSVC STL but it's necessary for proper build with STLport.
*/
#include <ctype.h>
// Runtime/STL headers
#include <vector>
#include <list>
#include <map>
#include <set>
#include <string>
#include <sstream>
#include <iomanip>
#include <cassert>
#include <stack>
#include <queue>
#include <iostream>
#include <algorithm>
#include <numeric>
#include <new>
#include <cstdio>
#include <limits.h>
#include <memory>
// Boost headers
#include <boost/pointer_cast.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/make_shared.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <boost/static_assert.hpp>
#include <boost/lexical_cast.hpp>
// Public ASSIMP headers
#include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/IOStream.hpp"
#include "../include/assimp/IOSystem.hpp"
#include "../include/assimp/scene.h"
#include "../include/assimp/importerdesc.h"
#include "../include/assimp/postprocess.h"
#include "../include/assimp/Importer.hpp"
#include "../include/assimp/Exporter.hpp"
// Internal utility headers
#include "BaseImporter.h"
#include "StringComparison.h"
#include "StreamReader.h"
#include "qnan.h"
#include "ScenePrivate.h"
// We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0))
#endif
#if (!defined UINT_MAX)
# define UINT_MAX (~((unsigned int)0))
#endif
#endif // !! ASSIMP_PCH_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -2,11 +2,11 @@
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +1,130 @@
/*
/* Open Asset Import Library (assimp)
Open Asset Import Library (assimp) ----------------------------------------------------------------------
----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team
Copyright (c) 2006-2012, 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, with or without modification, are permitted provided that the
with or without modification, are permitted provided that the following conditions are met:
following conditions are met:
* Redistributions of source code must retain the above
* Redistributions of source code must retain the above copyright notice, this list of conditions and the
copyright notice, this list of conditions and the following disclaimer.
following disclaimer.
* Redistributions in binary form must reproduce the above
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
copyright notice, this list of conditions and the following disclaimer in the documentation and/or other
following disclaimer in the documentation and/or other materials provided with the distribution.
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
* Neither the name of the assimp team, nor the names of its contributors may be used to endorse or promote products
contributors may be used to endorse or promote products derived from this software without specific prior
derived from this software without specific prior written permission of the assimp team.
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
---------------------------------------------------------------------- */
*/
/** @file Definition of the .b3d importer class. */
/** @file Definition of the .b3d importer class. */
#ifndef AI_B3DIMPORTER_H_INC
#ifndef AI_B3DIMPORTER_H_INC #define AI_B3DIMPORTER_H_INC
#define AI_B3DIMPORTER_H_INC
#include "../include/assimp/types.h"
#include "../include/assimp/types.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/material.h"
#include "../include/assimp/material.h" #include "BaseImporter.h"
#include <string> #include <string>
#include <vector> #include <vector>
namespace Assimp{ struct aiNodeAnim;
struct aiNode;
class B3DImporter : public BaseImporter{ struct aiAnimation;
public:
namespace Assimp{
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
class B3DImporter : public BaseImporter{
protected: public:
virtual const aiImporterDesc* GetInfo () const; virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
protected:
private:
virtual const aiImporterDesc* GetInfo () const;
int ReadByte(); virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
int ReadInt();
float ReadFloat(); private:
aiVector2D ReadVec2();
aiVector3D ReadVec3(); int ReadByte();
aiQuaternion ReadQuat(); int ReadInt();
std::string ReadString(); float ReadFloat();
std::string ReadChunk(); aiVector2D ReadVec2();
void ExitChunk(); aiVector3D ReadVec3();
unsigned ChunkSize(); aiQuaternion ReadQuat();
std::string ReadString();
template<class T> std::string ReadChunk();
T *to_array( const std::vector<T> &v ); void ExitChunk();
unsigned ChunkSize();
struct Vertex{
aiVector3D vertex; template<class T>
aiVector3D normal; T *to_array( const std::vector<T> &v );
aiVector3D texcoords;
unsigned char bones[4]; struct Vertex{
float weights[4]; aiVector3D vertex;
}; aiVector3D normal;
aiVector3D texcoords;
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX; unsigned char bones[4];
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX; float weights[4];
};
void ReadTEXS();
void ReadBRUS(); AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
void ReadVRTS();
void ReadTRIS( int v0 ); void ReadTEXS();
void ReadMESH(); void ReadBRUS();
void ReadBONE( int id );
void ReadKEYS( aiNodeAnim *nodeAnim ); void ReadVRTS();
void ReadANIM(); void ReadTRIS( int v0 );
void ReadMESH();
aiNode *ReadNODE( aiNode *parent ); void ReadBONE( int id );
void ReadKEYS( aiNodeAnim *nodeAnim );
void ReadBB3D( aiScene *scene ); void ReadANIM();
unsigned _pos; aiNode *ReadNODE( aiNode *parent );
// unsigned _size;
std::vector<unsigned char> _buf; void ReadBB3D( aiScene *scene );
std::vector<unsigned> _stack;
unsigned _pos;
std::vector<std::string> _textures; // unsigned _size;
std::vector<aiMaterial*> _materials; std::vector<unsigned char> _buf;
std::vector<unsigned> _stack;
int _vflags,_tcsets,_tcsize;
std::vector<Vertex> _vertices; std::vector<std::string> _textures;
std::vector<aiMaterial*> _materials;
std::vector<aiNode*> _nodes;
std::vector<aiMesh*> _meshes; int _vflags,_tcsets,_tcsize;
std::vector<aiNodeAnim*> _nodeAnims; std::vector<Vertex> _vertices;
std::vector<aiAnimation*> _animations;
}; std::vector<aiNode*> _nodes;
std::vector<aiMesh*> _meshes;
} std::vector<aiNodeAnim*> _nodeAnims;
std::vector<aiAnimation*> _animations;
#endif };
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,169 +1,171 @@
/** Defines the BHV motion capturing loader class */ /** Defines the BHV motion capturing loader class */
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BVHLoader.h /** @file BVHLoader.h
* @brief Biovision BVH import * @brief Biovision BVH import
*/ */
#ifndef AI_BVHLOADER_H_INC #ifndef AI_BVHLOADER_H_INC
#define AI_BVHLOADER_H_INC #define AI_BVHLOADER_H_INC
#include "BaseImporter.h" #include "BaseImporter.h"
namespace Assimp struct aiNode;
{
namespace Assimp
// -------------------------------------------------------------------------------- {
/** Loader class to read Motion Capturing data from a .bvh file.
* // --------------------------------------------------------------------------------
* This format only contains a hierarchy of joints and a series of keyframes for /** Loader class to read Motion Capturing data from a .bvh file.
* the hierarchy. It contains no actual mesh data, but we generate a dummy mesh *
* inside the loader just to be able to see something. * This format only contains a hierarchy of joints and a series of keyframes for
*/ * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
class BVHLoader : public BaseImporter * inside the loader just to be able to see something.
{ */
class BVHLoader : public BaseImporter
/** Possible animation channels for which the motion data holds the values */ {
enum ChannelType
{ /** Possible animation channels for which the motion data holds the values */
Channel_PositionX, enum ChannelType
Channel_PositionY, {
Channel_PositionZ, Channel_PositionX,
Channel_RotationX, Channel_PositionY,
Channel_RotationY, Channel_PositionZ,
Channel_RotationZ Channel_RotationX,
}; Channel_RotationY,
Channel_RotationZ
/** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */ };
struct Node
{ /** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
const aiNode* mNode; struct Node
std::vector<ChannelType> mChannels; {
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames const aiNode* mNode;
std::vector<ChannelType> mChannels;
Node() { } std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
Node( const aiNode* pNode) : mNode( pNode) { }
}; Node() { }
Node( const aiNode* pNode) : mNode( pNode) { }
public: };
BVHLoader(); public:
~BVHLoader();
BVHLoader();
public: ~BVHLoader();
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ public:
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const; /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
void SetupProperties(const Importer* pImp); bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer* pImp);
protected: const aiImporterDesc* GetInfo () const;
protected:
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/ /** Imports the given file into the given scene structure.
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); * See BaseImporter::InternReadFile() for details
*/
protected: void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
/** Reads the file */
void ReadStructure( aiScene* pScene); protected:
/** Reads the file */
/** Reads the hierarchy */ void ReadStructure( aiScene* pScene);
void ReadHierarchy( aiScene* pScene);
/** Reads the hierarchy */
/** Reads a node and recursively its childs and returns the created node. */ void ReadHierarchy( aiScene* pScene);
aiNode* ReadNode();
/** Reads a node and recursively its childs and returns the created node. */
/** Reads an end node and returns the created node. */ aiNode* ReadNode();
aiNode* ReadEndSite( const std::string& pParentName);
/** Reads an end node and returns the created node. */
/** Reads a node offset for the given node */ aiNode* ReadEndSite( const std::string& pParentName);
void ReadNodeOffset( aiNode* pNode);
/** Reads a node offset for the given node */
/** Reads the animation channels into the given node */ void ReadNodeOffset( aiNode* pNode);
void ReadNodeChannels( BVHLoader::Node& pNode);
/** Reads the animation channels into the given node */
/** Reads the motion data */ void ReadNodeChannels( BVHLoader::Node& pNode);
void ReadMotion( aiScene* pScene);
/** Reads the motion data */
/** Retrieves the next token */ void ReadMotion( aiScene* pScene);
std::string GetNextToken();
/** Retrieves the next token */
/** Reads the next token as a float */ std::string GetNextToken();
float GetNextTokenAsFloat();
/** Reads the next token as a float */
/** Aborts the file reading with an exception */ float GetNextTokenAsFloat();
AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
/** Aborts the file reading with an exception */
/** Constructs an animation for the motion data and stores it in the given scene */ AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
void CreateAnimation( aiScene* pScene);
/** Constructs an animation for the motion data and stores it in the given scene */
protected: void CreateAnimation( aiScene* pScene);
/** Filename, for a verbose error message */
std::string mFileName; protected:
/** Filename, for a verbose error message */
/** Buffer to hold the loaded file */ std::string mFileName;
std::vector<char> mBuffer;
/** Buffer to hold the loaded file */
/** Next char to read from the buffer */ std::vector<char> mBuffer;
std::vector<char>::const_iterator mReader;
/** Next char to read from the buffer */
/** Current line, for error messages */ std::vector<char>::const_iterator mReader;
unsigned int mLine;
/** Current line, for error messages */
/** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index. unsigned int mLine;
* Also contain the motion data for the node's channels
*/ /** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
std::vector<Node> mNodes; * Also contain the motion data for the node's channels
*/
/** basic Animation parameters */ std::vector<Node> mNodes;
float mAnimTickDuration;
unsigned int mAnimNumFrames; /** basic Animation parameters */
float mAnimTickDuration;
bool noSkeletonMesh; unsigned int mAnimNumFrames;
};
bool noSkeletonMesh;
} // end of namespace Assimp };
#endif // AI_BVHLOADER_H_INC } // end of namespace Assimp
#endif // AI_BVHLOADER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,373 +1,375 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Definition of the base class for all importer worker classes. */ /** @file Definition of the base class for all importer worker classes. */
#ifndef INCLUDED_AI_BASEIMPORTER_H #ifndef INCLUDED_AI_BASEIMPORTER_H
#define INCLUDED_AI_BASEIMPORTER_H #define INCLUDED_AI_BASEIMPORTER_H
#include "Exceptional.h" #include "Exceptional.h"
#include <string> #include <string>
#include <map> #include <map>
#include <vector> #include <vector>
#include "./../include/assimp/types.h" #include <set>
#include "../include/assimp/types.h"
struct aiScene; #include "../include/assimp/ProgressHandler.hpp"
namespace Assimp { struct aiScene;
class IOSystem; namespace Assimp {
class Importer;
class BaseImporter; class Importer;
class BaseProcess; class IOSystem;
class SharedPostProcessInfo; class BaseProcess;
class IOStream; class SharedPostProcessInfo;
class IOStream;
// utility to do char4 to uint32 in a portable manner
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
(string[1] << 16) + (string[2] << 8) + string[3])) // utility to do char4 to uint32 in a portable manner
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
// --------------------------------------------------------------------------- (string[1] << 16) + (string[2] << 8) + string[3]))
template <typename T>
struct ScopeGuard // ---------------------------------------------------------------------------
{ template <typename T>
ScopeGuard(T* obj) : obj(obj), mdismiss() {} struct ScopeGuard
~ScopeGuard () throw() { {
if (!mdismiss) { ScopeGuard(T* obj) : obj(obj), mdismiss() {}
delete obj; ~ScopeGuard () throw() {
} if (!mdismiss) {
obj = NULL; delete obj;
} }
obj = NULL;
T* dismiss() { }
mdismiss=true;
return obj; T* dismiss() {
} mdismiss=true;
return obj;
operator T*() { }
return obj;
} operator T*() {
return obj;
T* operator -> () { }
return obj;
} T* operator -> () {
return obj;
private: }
// no copying allowed.
ScopeGuard(); private:
ScopeGuard( const ScopeGuard & ); // no copying allowed.
ScopeGuard &operator = ( const ScopeGuard & ); ScopeGuard();
ScopeGuard( const ScopeGuard & );
T* obj; ScopeGuard &operator = ( const ScopeGuard & );
bool mdismiss;
}; T* obj;
bool mdismiss;
};
// ---------------------------------------------------------------------------
/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
* for all importer worker classes. // ---------------------------------------------------------------------------
* /** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
* The interface defines two functions: CanRead() is used to check if the * for all importer worker classes.
* importer can handle the format of the given file. If an implementation of *
* this function returns true, the importer then calls ReadFile() which * The interface defines two functions: CanRead() is used to check if the
* imports the given file. ReadFile is not overridable, it just calls * importer can handle the format of the given file. If an implementation of
* InternReadFile() and catches any ImportErrorException that might occur. * this function returns true, the importer then calls ReadFile() which
*/ * imports the given file. ReadFile is not overridable, it just calls
class ASSIMP_API BaseImporter * InternReadFile() and catches any ImportErrorException that might occur.
{ */
friend class Importer; class ASSIMP_API BaseImporter
{
public: friend class Importer;
/** Constructor to be privately used by #Importer */ public:
BaseImporter();
/** Constructor to be privately used by #Importer */
/** Destructor, private as well */ BaseImporter();
virtual ~BaseImporter();
/** Destructor, private as well */
public: virtual ~BaseImporter();
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. public:
* // -------------------------------------------------------------------
* The implementation should be as quick as possible. A check for /** Returns whether the class can handle the format of the given file.
* the file extension is enough. If no suitable loader is found with *
* this strategy, CanRead() is called again, the 'checkSig' parameter * The implementation should be as quick as possible. A check for
* set to true this time. Now the implementation is expected to * the file extension is enough. If no suitable loader is found with
* perform a full check of the file structure, possibly searching the * this strategy, CanRead() is called again, the 'checkSig' parameter
* first bytes of the file for magic identifiers or keywords. * set to true this time. Now the implementation is expected to
* * perform a full check of the file structure, possibly searching the
* @param pFile Path and file name of the file to be examined. * first bytes of the file for magic identifiers or keywords.
* @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 pFile Path and file name of the file to be examined.
* This time, the implementation may take more time to examine the * @param pIOHandler The IO handler to use for accessing any file.
* contents of the file to be loaded for magic bytes, keywords, etc * @param checkSig Set to true if this method is called a second time.
* to be able to load files with unknown/not existent file extensions. * This time, the implementation may take more time to examine the
* @return true if the class can read this file, false if not. * contents of the file to be loaded for magic bytes, keywords, etc
*/ * to be able to load files with unknown/not existent file extensions.
virtual bool CanRead( * @return true if the class can read this file, false if not.
const std::string& pFile, */
IOSystem* pIOHandler, virtual bool CanRead(
bool checkSig const std::string& pFile,
) const = 0; IOSystem* pIOHandler,
bool checkSig
// ------------------------------------------------------------------- ) const = 0;
/** Imports the given file and returns the imported data.
* If the import succeeds, ownership of the data is transferred to // -------------------------------------------------------------------
* the caller. If the import fails, NULL is returned. The function /** Imports the given file and returns the imported data.
* takes care that any partially constructed data is destroyed * If the import succeeds, ownership of the data is transferred to
* beforehand. * the caller. If the import fails, NULL is returned. The function
* * takes care that any partially constructed data is destroyed
* @param pImp #Importer object hosting this loader. * beforehand.
* @param pFile Path of the file to be imported. *
* @param pIOHandler IO-Handler used to open this and possible other files. * @param pImp #Importer object hosting this loader.
* @return The imported data or NULL if failed. If it failed a * @param pFile Path of the file to be imported.
* human-readable error description can be retrieved by calling * @param pIOHandler IO-Handler used to open this and possible other files.
* GetErrorText() * @return The imported data or NULL if failed. If it failed a
* * human-readable error description can be retrieved by calling
* @note This function is not intended to be overridden. Implement * GetErrorText()
* InternReadFile() to do the import. If an exception is thrown somewhere *
* in InternReadFile(), this function will catch it and transform it into * @note This function is not intended to be overridden. Implement
* a suitable response to the caller. * InternReadFile() to do the import. If an exception is thrown somewhere
*/ * in InternReadFile(), this function will catch it and transform it into
aiScene* ReadFile( * a suitable response to the caller.
const Importer* pImp, */
const std::string& pFile, aiScene* ReadFile(
IOSystem* pIOHandler const Importer* pImp,
); const std::string& pFile,
IOSystem* pIOHandler
// ------------------------------------------------------------------- );
/** Returns the error description of the last error that occured.
* @return A description of the last error that occured. An empty // -------------------------------------------------------------------
* string if there was no error. /** Returns the error description of the last error that occured.
*/ * @return A description of the last error that occured. An empty
const std::string& GetErrorText() const { * string if there was no error.
return mErrorText; */
} const std::string& GetErrorText() const {
return mErrorText;
// ------------------------------------------------------------------- }
/** Called prior to ReadFile().
* The function is a request to the importer to update its configuration // -------------------------------------------------------------------
* basing on the Importer's configuration property list. /** Called prior to ReadFile().
* @param pImp Importer instance * The function is a request to the importer to update its configuration
*/ * basing on the Importer's configuration property list.
virtual void SetupProperties( * @param pImp Importer instance
const Importer* pImp */
); virtual void SetupProperties(
const Importer* pImp
);
// -------------------------------------------------------------------
/** Called by #Importer::GetImporterInfo to get a description of
* some loader features. Importers must provide this information. */ // -------------------------------------------------------------------
virtual const aiImporterDesc* GetInfo() const = 0; /** Called by #Importer::GetImporterInfo to get a description of
* some loader features. Importers must provide this information. */
virtual const aiImporterDesc* GetInfo() const = 0;
// -------------------------------------------------------------------
/** Called by #Importer::GetExtensionList for each loaded importer.
* Take the extension list contained in the structure returned by // -------------------------------------------------------------------
* #GetInfo and insert all file extensions into the given set. /** Called by #Importer::GetExtensionList for each loaded importer.
* @param extension set to collect file extensions in*/ * Take the extension list contained in the structure returned by
void GetExtensionList(std::set<std::string>& extensions); * #GetInfo and insert all file extensions into the given set.
* @param extension set to collect file extensions in*/
protected: void GetExtensionList(std::set<std::string>& extensions);
// ------------------------------------------------------------------- protected:
/** Imports the given file into the given scene structure. The
* function is expected to throw an ImportErrorException if there is // -------------------------------------------------------------------
* an error. If it terminates normally, the data in aiScene is /** Imports the given file into the given scene structure. The
* expected to be correct. Override this function to implement the * function is expected to throw an ImportErrorException if there is
* actual importing. * an error. If it terminates normally, the data in aiScene is
* <br> * expected to be correct. Override this function to implement the
* The output scene must meet the following requirements:<br> * actual importing.
* <ul> * <br>
* <li>At least a root node must be there, even if its only purpose * The output scene must meet the following requirements:<br>
* is to reference one mesh.</li> * <ul>
* <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives * <li>At least a root node must be there, even if its only purpose
* in the mesh are determined automatically in this case.</li> * is to reference one mesh.</li>
* <li>the vertex data is stored in a pseudo-indexed "verbose" format. * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
* In fact this means that every vertex that is referenced by * in the mesh are determined automatically in this case.</li>
* a face is unique. Or the other way round: a vertex index may * <li>the vertex data is stored in a pseudo-indexed "verbose" format.
* not occur twice in a single aiMesh.</li> * In fact this means that every vertex that is referenced by
* <li>aiAnimation::mDuration may be -1. Assimp determines the length * a face is unique. Or the other way round: a vertex index may
* of the animation automatically in this case as the length of * not occur twice in a single aiMesh.</li>
* the longest animation channel.</li> * <li>aiAnimation::mDuration may be -1. Assimp determines the length
* <li>aiMesh::mBitangents may be NULL if tangents and normals are * of the animation automatically in this case as the length of
* given. In this case bitangents are computed as the cross product * the longest animation channel.</li>
* between normal and tangent.</li> * <li>aiMesh::mBitangents may be NULL if tangents and normals are
* <li>There needn't be a material. If none is there a default material * given. In this case bitangents are computed as the cross product
* is generated. However, it is recommended practice for loaders * between normal and tangent.</li>
* to generate a default material for yourself that matches the * <li>There needn't be a material. If none is there a default material
* default material setting for the file format better than Assimp's * is generated. However, it is recommended practice for loaders
* generic default material. Note that default materials *should* * to generate a default material for yourself that matches the
* be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded * default material setting for the file format better than Assimp's
* or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy) * generic default material. Note that default materials *should*
* texture. </li> * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
* </ul> * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
* If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul> * texture. </li>
* <li> at least one mesh must be there</li> * </ul>
* <li> there may be no meshes with 0 vertices or faces</li> * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
* </ul> * <li> at least one mesh must be there</li>
* This won't be checked (except by the validation step): Assimp will * <li> there may be no meshes with 0 vertices or faces</li>
* crash if one of the conditions is not met! * </ul>
* * This won't be checked (except by the validation step): Assimp will
* @param pFile Path of the file to be imported. * crash if one of the conditions is not met!
* @param pScene The scene object to hold the imported data. *
* NULL is not a valid parameter. * @param pFile Path of the file to be imported.
* @param pIOHandler The IO handler to use for any file access. * @param pScene The scene object to hold the imported data.
* NULL is not a valid parameter. */ * NULL is not a valid parameter.
virtual void InternReadFile( * @param pIOHandler The IO handler to use for any file access.
const std::string& pFile, * NULL is not a valid parameter. */
aiScene* pScene, virtual void InternReadFile(
IOSystem* pIOHandler const std::string& pFile,
) = 0; aiScene* pScene,
IOSystem* pIOHandler
public: // static utilities ) = 0;
// ------------------------------------------------------------------- public: // static utilities
/** A utility for CanRead().
* // -------------------------------------------------------------------
* The function searches the header of a file for a specific token /** A utility for CanRead().
* and returns true if this token is found. This works for text *
* files only. There is a rudimentary handling of UNICODE files. * The function searches the header of a file for a specific token
* The comparison is case independent. * and returns true if this token is found. This works for text
* * files only. There is a rudimentary handling of UNICODE files.
* @param pIOSystem IO System to work with * The comparison is case independent.
* @param file File name of the file *
* @param tokens List of tokens to search for * @param pIOSystem IO System to work with
* @param numTokens Size of the token array * @param file File name of the file
* @param searchBytes Number of bytes to be searched for the tokens. * @param tokens List of tokens to search for
*/ * @param numTokens Size of the token array
static bool SearchFileHeaderForToken( * @param searchBytes Number of bytes to be searched for the tokens.
IOSystem* pIOSystem, */
const std::string& file, static bool SearchFileHeaderForToken(
const char** tokens, IOSystem* pIOSystem,
unsigned int numTokens, const std::string& file,
unsigned int searchBytes = 200, const char** tokens,
bool tokensSol = false); unsigned int numTokens,
unsigned int searchBytes = 200,
// ------------------------------------------------------------------- bool tokensSol = false);
/** @brief Check whether a file has a specific file extension
* @param pFile Input file // -------------------------------------------------------------------
* @param ext0 Extension to check for. Lowercase characters only, no dot! /** @brief Check whether a file has a specific file extension
* @param ext1 Optional second extension * @param pFile Input file
* @param ext2 Optional third extension * @param ext0 Extension to check for. Lowercase characters only, no dot!
* @note Case-insensitive * @param ext1 Optional second extension
*/ * @param ext2 Optional third extension
static bool SimpleExtensionCheck ( * @note Case-insensitive
const std::string& pFile, */
const char* ext0, static bool SimpleExtensionCheck (
const char* ext1 = NULL, const std::string& pFile,
const char* ext2 = NULL); const char* ext0,
const char* ext1 = NULL,
// ------------------------------------------------------------------- const char* ext2 = NULL);
/** @brief Extract file extension from a string
* @param pFile Input file // -------------------------------------------------------------------
* @return Extension without trailing dot, all lowercase /** @brief Extract file extension from a string
*/ * @param pFile Input file
static std::string GetExtension ( * @return Extension without trailing dot, all lowercase
const std::string& pFile); */
static std::string GetExtension (
// ------------------------------------------------------------------- const std::string& pFile);
/** @brief Check whether a file starts with one or more magic tokens
* @param pFile Input file // -------------------------------------------------------------------
* @param pIOHandler IO system to be used /** @brief Check whether a file starts with one or more magic tokens
* @param magic n magic tokens * @param pFile Input file
* @params num Size of magic * @param pIOHandler IO system to be used
* @param offset Offset from file start where tokens are located * @param magic n magic tokens
* @param Size of one token, in bytes. Maximally 16 bytes. * @params num Size of magic
* @return true if one of the given tokens was found * @param offset Offset from file start where tokens are located
* * @param Size of one token, in bytes. Maximally 16 bytes.
* @note For convinence, the check is also performed for the * @return true if one of the given tokens was found
* byte-swapped variant of all tokens (big endian). Only for *
* tokens of size 2,4. * @note For convinence, the check is also performed for the
*/ * byte-swapped variant of all tokens (big endian). Only for
static bool CheckMagicToken( * tokens of size 2,4.
IOSystem* pIOHandler, */
const std::string& pFile, static bool CheckMagicToken(
const void* magic, IOSystem* pIOHandler,
unsigned int num, const std::string& pFile,
unsigned int offset = 0, const void* magic,
unsigned int size = 4); unsigned int num,
unsigned int offset = 0,
// ------------------------------------------------------------------- unsigned int size = 4);
/** An utility for all text file loaders. It converts a file to our
* UTF8 character set. Errors are reported, but ignored. // -------------------------------------------------------------------
* /** An utility for all text file loaders. It converts a file to our
* @param data File buffer to be converted to UTF8 data. The buffer * UTF8 character set. Errors are reported, but ignored.
* is resized as appropriate. */ *
static void ConvertToUTF8( * @param data File buffer to be converted to UTF8 data. The buffer
std::vector<char>& data); * is resized as appropriate. */
static void ConvertToUTF8(
// ------------------------------------------------------------------- std::vector<char>& data);
/** 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. // -------------------------------------------------------------------
* /** An utility for all text file loaders. It converts a file from our
* @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer * UTF8 character set back to ISO-8859-1. Errors are reported, but ignored.
* is resized as appropriate. */ *
static void ConvertUTF8toISO8859_1( * @param data File buffer to be converted from UTF8 to ISO-8859-1. The buffer
std::string& data); * is resized as appropriate. */
static void ConvertUTF8toISO8859_1(
// ------------------------------------------------------------------- std::string& data);
/** Utility for text file loaders which copies the contents of the
* file into a memory buffer and converts it to our UTF8 // -------------------------------------------------------------------
* representation. /** Utility for text file loaders which copies the contents of the
* @param stream Stream to read from. * file into a memory buffer and converts it to our UTF8
* @param data Output buffer to be resized and filled with the * representation.
* converted text file data. The buffer is terminated with * @param stream Stream to read from.
* a binary 0. */ * @param data Output buffer to be resized and filled with the
static void TextFileToBuffer( * converted text file data. The buffer is terminated with
IOStream* stream, * a binary 0. */
std::vector<char>& data); static void TextFileToBuffer(
IOStream* stream,
protected: std::vector<char>& data);
/** Error description in case there was one. */ protected:
std::string mErrorText;
/** Error description in case there was one. */
/** Currently set progress handler */ std::string mErrorText;
ProgressHandler* progress;
}; /** Currently set progress handler */
ProgressHandler* progress;
};
} // end of namespace Assimp
#endif // AI_BASEIMPORTER_H_INC } // end of namespace Assimp
#endif // AI_BASEIMPORTER_H_INC

View File

@ -1,105 +1,105 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of BaseProcess */ /** @file Implementation of BaseProcess */
#include "AssimpPCH.h" #include "BaseImporter.h"
#include "BaseImporter.h" #include "BaseProcess.h"
#include "BaseProcess.h" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/scene.h"
#include "Importer.h" #include "Importer.h"
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
BaseProcess::BaseProcess() BaseProcess::BaseProcess()
: shared() : shared()
, progress() , progress()
{ {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// 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;
} }

View File

@ -1,294 +1,294 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Base class of all import post processing steps */ /** @file Base class of all import post processing steps */
#ifndef INCLUDED_AI_BASEPROCESS_H #ifndef INCLUDED_AI_BASEPROCESS_H
#define INCLUDED_AI_BASEPROCESS_H #define INCLUDED_AI_BASEPROCESS_H
#include <map> #include <map>
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "GenericProperty.h" #include "GenericProperty.h"
struct aiScene; struct aiScene;
namespace Assimp { namespace Assimp {
class Importer; class Importer;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Helper class to allow post-processing steps to interact with each other. /** Helper class to allow post-processing steps to interact with each other.
* *
* The class maintains a simple property list that can be used by pp-steps * The class maintains a simple property list that can be used by pp-steps
* to provide additional information to other steps. This is primarily * to provide additional information to other steps. This is primarily
* intended for cross-step optimizations. * intended for cross-step optimizations.
*/ */
class SharedPostProcessInfo 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
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Represents a dependency table for a postprocessing steps. /** @brief Represents a dependency table for a postprocessing steps.
* *
* For future use. * For future use.
*/ */
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
#define AI_SPP_SPATIAL_SORT "$Spat" #define AI_SPP_SPATIAL_SORT "$Spat"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The BaseProcess defines a common interface for all post processing steps. /** The BaseProcess defines a common interface for all post processing steps.
* A post processing step is run after a successful import if the caller * A post processing step is run after a successful import if the caller
* specified the corresponding flag when calling ReadFile(). * specified the corresponding flag when calling ReadFile().
* Enum #aiPostProcessSteps defines which flags are available. * Enum #aiPostProcessSteps defines which flags are available.
* After a successful import the Importer iterates over its internal array * After a successful import the Importer iterates over its internal array
* of processes and calls IsActive() on each process to evaluate if the step * of processes and calls IsActive() on each process to evaluate if the step
* should be executed. If the function returns true, the class' Execute() * should be executed. If the function returns true, the class' Execute()
* function is called subsequently. * function is called subsequently.
*/ */
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;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_BASEPROCESS_H_INC #endif // AI_BASEPROCESS_H_INC

View File

@ -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.
@ -45,101 +45,103 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Used for file formats which embed their textures into the model file. * Used for file formats which embed their textures into the model file.
*/ */
#include "AssimpPCH.h"
#include "Bitmap.h" #include "Bitmap.h"
#include "../include/assimp/texture.h"
#include "../include/assimp/IOStream.hpp"
#include "ByteSwapper.h"
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);
} }
} }
} }

View File

@ -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,89 +48,94 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_BITMAP_H_INC #ifndef AI_BITMAP_H_INC
#define AI_BITMAP_H_INC #define AI_BITMAP_H_INC
#include <stdint.h>
#include <cstddef>
struct aiTexture;
namespace Assimp { namespace Assimp {
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);
}; };

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2013, assimp team Copyright (c) 2006-2013, 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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Conversion of Blender's new BMesh stuff * @brief Conversion of Blender's new BMesh stuff
*/ */
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
@ -53,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;
@ -62,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

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2013, assimp team Copyright (c) 2006-2013, 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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -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

View File

@ -1,372 +1,373 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderDNA.cpp /** @file BlenderDNA.cpp
* @brief Implementation of the Blender `DNA`, that is its own * @brief Implementation of the Blender `DNA`, that is its own
* serialized set of data structures. * serialized set of data structures.
*/ */
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
#include "BlenderDNA.h" #include "BlenderDNA.h"
#include "StreamReader.h" #include "StreamReader.h"
#include "fast_atof.h" #include "fast_atof.h"
#include <boost/foreach.hpp>
using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Blender;
using namespace Assimp::Formatter;
#define for_each BOOST_FOREACH
bool match4(StreamReaderAny& stream, const char* string) { #define for_each BOOST_FOREACH
char tmp[] = { bool match4(StreamReaderAny& stream, const char* string) {
(stream).GetI1(), char tmp[] = {
(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 {
size_t size; struct Type {
std::string name; size_t size;
}; std::string name;
};
// ------------------------------------------------------------------------------------------------
void DNAParser :: Parse () // ------------------------------------------------------------------------------------------------
{ void DNAParser :: Parse ()
StreamReaderAny& stream = *db.reader.get(); {
DNA& dna = db.dna; StreamReaderAny& stream = *db.reader.get();
DNA& dna = db.dna;
if(!match4(stream,"SDNA")) {
throw DeadlyImportError("BlenderDNA: Expected SDNA chunk"); if(!match4(stream,"SDNA")) {
} throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
}
// name dictionary
if(!match4(stream,"NAME")) { // name dictionary
throw DeadlyImportError("BlenderDNA: Expected NAME field"); if(!match4(stream,"NAME")) {
} throw DeadlyImportError("BlenderDNA: Expected NAME field");
}
std::vector<std::string> names (stream.GetI4());
for_each(std::string& s, names) { std::vector<std::string> names (stream.GetI4());
while (char c = stream.GetI1()) { for_each(std::string& s, names) {
s += c; while (char c = stream.GetI1()) {
} s += c;
} }
}
// type dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); // type dictionary
if(!match4(stream,"TYPE")) { for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
throw DeadlyImportError("BlenderDNA: Expected TYPE field"); if(!match4(stream,"TYPE")) {
} throw DeadlyImportError("BlenderDNA: Expected TYPE field");
}
std::vector<Type> types (stream.GetI4());
for_each(Type& s, types) { std::vector<Type> types (stream.GetI4());
while (char c = stream.GetI1()) { for_each(Type& s, types) {
s.name += c; while (char c = stream.GetI1()) {
} s.name += c;
} }
}
// type length dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); // type length dictionary
if(!match4(stream,"TLEN")) { for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
throw DeadlyImportError("BlenderDNA: Expected TLEN field"); if(!match4(stream,"TLEN")) {
} throw DeadlyImportError("BlenderDNA: Expected TLEN field");
}
for_each(Type& s, types) {
s.size = stream.GetI2(); for_each(Type& s, types) {
} s.size = stream.GetI2();
}
// structures dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); // structures dictionary
if(!match4(stream,"STRC")) { for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
throw DeadlyImportError("BlenderDNA: Expected STRC field"); if(!match4(stream,"STRC")) {
} throw DeadlyImportError("BlenderDNA: Expected STRC field");
}
size_t end = stream.GetI4(), fields = 0;
size_t end = stream.GetI4(), fields = 0;
dna.structures.reserve(end);
for(size_t i = 0; i != end; ++i) { dna.structures.reserve(end);
for(size_t i = 0; i != end; ++i) {
uint16_t n = stream.GetI2();
if (n >= types.size()) { uint16_t n = stream.GetI2();
throw DeadlyImportError((format(), if (n >= types.size()) {
"BlenderDNA: Invalid type index in structure name" ,n, throw DeadlyImportError((format(),
" (there are only ", types.size(), " entries)" "BlenderDNA: Invalid type index in structure name" ,n,
)); " (there are only ", types.size(), " entries)"
} ));
}
// maintain separate indexes
dna.indices[types[n].name] = dna.structures.size(); // maintain separate indexes
dna.indices[types[n].name] = dna.structures.size();
dna.structures.push_back(Structure());
Structure& s = dna.structures.back(); dna.structures.push_back(Structure());
s.name = types[n].name; Structure& s = dna.structures.back();
//s.index = dna.structures.size()-1; s.name = types[n].name;
//s.index = dna.structures.size()-1;
n = stream.GetI2();
s.fields.reserve(n); n = stream.GetI2();
s.fields.reserve(n);
size_t offset = 0;
for (size_t m = 0; m < n; ++m, ++fields) { size_t offset = 0;
for (size_t m = 0; m < n; ++m, ++fields) {
uint16_t j = stream.GetI2();
if (j >= types.size()) { uint16_t j = stream.GetI2();
throw DeadlyImportError((format(), if (j >= types.size()) {
"BlenderDNA: Invalid type index in structure field ", j, throw DeadlyImportError((format(),
" (there are only ", types.size(), " entries)" "BlenderDNA: Invalid type index in structure field ", j,
)); " (there are only ", types.size(), " entries)"
} ));
s.fields.push_back(Field()); }
Field& f = s.fields.back(); s.fields.push_back(Field());
f.offset = offset; Field& f = s.fields.back();
f.offset = offset;
f.type = types[j].name;
f.size = types[j].size; f.type = types[j].name;
f.size = types[j].size;
j = stream.GetI2();
if (j >= names.size()) { j = stream.GetI2();
throw DeadlyImportError((format(), if (j >= names.size()) {
"BlenderDNA: Invalid name index in structure field ", j, throw DeadlyImportError((format(),
" (there are only ", names.size(), " entries)" "BlenderDNA: Invalid name index in structure field ", j,
)); " (there are only ", names.size(), " entries)"
} ));
}
f.name = names[j];
f.flags = 0u; f.name = names[j];
f.flags = 0u;
// pointers always specify the size of the pointee instead of their own.
// The pointer asterisk remains a property of the lookup name. // pointers always specify the size of the pointee instead of their own.
if (f.name[0] == '*') { // The pointer asterisk remains a property of the lookup name.
f.size = db.i64bit ? 8 : 4; if (f.name[0] == '*') {
f.flags |= FieldFlag_Pointer; f.size = db.i64bit ? 8 : 4;
} f.flags |= FieldFlag_Pointer;
}
// arrays, however, specify the size of a single element so we
// need to parse the (possibly multi-dimensional) array declaration // arrays, however, specify the size of a single element so we
// in order to obtain the actual size of the array in the file. // need to parse the (possibly multi-dimensional) array declaration
// Also we need to alter the lookup name to include no array // in order to obtain the actual size of the array in the file.
// brackets anymore or size fixup won't work (if our size does // Also we need to alter the lookup name to include no array
// not match the size read from the DNA). // brackets anymore or size fixup won't work (if our size does
if (*f.name.rbegin() == ']') { // not match the size read from the DNA).
const std::string::size_type rb = f.name.find('['); if (*f.name.rbegin() == ']') {
if (rb == std::string::npos) { const std::string::size_type rb = f.name.find('[');
throw DeadlyImportError((format(), if (rb == std::string::npos) {
"BlenderDNA: Encountered invalid array declaration ", throw DeadlyImportError((format(),
f.name "BlenderDNA: Encountered invalid array declaration ",
)); f.name
} ));
}
f.flags |= FieldFlag_Array;
DNA::ExtractArraySize(f.name,f.array_sizes); f.flags |= FieldFlag_Array;
f.name = f.name.substr(0,rb); DNA::ExtractArraySize(f.name,f.array_sizes);
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
s.indices[f.name] = s.fields.size()-1; // maintain separate indexes
offset += f.size; s.indices[f.name] = s.fields.size()-1;
} offset += f.size;
s.size = offset; }
} s.size = offset;
}
DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
" structures with totally ",fields," fields")); DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
" structures with totally ",fields," fields"));
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
dna.DumpToFile(); #ifdef ASSIMP_BUILD_BLENDER_DEBUG
#endif dna.DumpToFile();
#endif
dna.AddPrimitiveStructures();
dna.RegisterConverters(); dna.AddPrimitiveStructures();
} dna.RegisterConverters();
}
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
#include <fstream>
// ------------------------------------------------------------------------------------------------ #include <fstream>
void DNA :: DumpToFile() // ------------------------------------------------------------------------------------------------
{ void DNA :: DumpToFile()
// we dont't bother using the VFS here for this is only for debugging. {
// (and all your bases are belong to us). // we dont't bother using the VFS here for this is only for debugging.
// (and all your bases are belong to us).
std::ofstream f("dna.txt");
if (f.fail()) { std::ofstream f("dna.txt");
DefaultLogger::get()->error("Could not dump dna to dna.txt"); if (f.fail()) {
return; DefaultLogger::get()->error("Could not dump dna to dna.txt");
} return;
f << "Field format: type name offset size" << "\n"; }
f << "Structure format: name size" << "\n"; f << "Field format: type name offset size" << "\n";
f << "Structure format: name size" << "\n";
for_each(const Structure& s, structures) {
f << s.name << " " << s.size << "\n\n"; for_each(const Structure& s, structures) {
for_each(const Field& ff, s.fields) { f << s.name << " " << s.size << "\n\n";
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl; for_each(const Field& ff, s.fields) {
} 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( // ------------------------------------------------------------------------------------------------
const std::string& out, /*static*/ void DNA :: ExtractArraySize(
size_t array_sizes[2] const std::string& out,
) size_t array_sizes[2]
{ )
array_sizes[0] = array_sizes[1] = 1; {
std::string::size_type pos = out.find('['); array_sizes[0] = array_sizes[1] = 1;
if (pos++ == std::string::npos) { std::string::size_type pos = out.find('[');
return; if (pos++ == std::string::npos) {
} return;
array_sizes[0] = strtoul10(&out[pos]); }
array_sizes[0] = strtoul10(&out[pos]);
pos = out.find('[',pos);
if (pos++ == std::string::npos) { pos = out.find('[',pos);
return; if (pos++ == std::string::npos) {
} return;
array_sizes[1] = strtoul10(&out[pos]); }
} array_sizes[1] = strtoul10(&out[pos]);
}
// ------------------------------------------------------------------------------------------------
boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure( // ------------------------------------------------------------------------------------------------
const Structure& structure, boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
const FileDatabase& db const Structure& structure,
) const const FileDatabase& db
{ ) const
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name); {
if (it == converters.end()) { std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
return boost::shared_ptr< ElemBase >(); if (it == converters.end()) {
} return boost::shared_ptr< ElemBase >();
}
boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
(structure.*((*it).second.second))(ret,db); boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
(structure.*((*it).second.second))(ret,db);
return ret;
} return ret;
}
// ------------------------------------------------------------------------------------------------
DNA::FactoryPair DNA :: GetBlobToStructureConverter( // ------------------------------------------------------------------------------------------------
const Structure& structure, DNA::FactoryPair DNA :: GetBlobToStructureConverter(
const FileDatabase& /*db*/ const Structure& structure,
) const const FileDatabase& /*db*/
{ ) const
std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name); {
return it == converters.end() ? FactoryPair() : (*it).second; std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
} 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 {
// Structure::Convert<target_type> to be called on these // NOTE: these are just dummies. Their presence enforces
// empty structures. These converters are special // Structure::Convert<target_type> to be called on these
// overloads which scan the name of the structure and // empty structures. These converters are special
// perform the required data type conversion if one // overloads which scan the name of the structure and
// of these special names is found in the structure // perform the required data type conversion if one
// in question. // of these special names is found in the structure
// in question.
indices["int"] = structures.size();
structures.push_back( Structure() ); indices["int"] = structures.size();
structures.back().name = "int"; structures.push_back( Structure() );
structures.back().size = 4; structures.back().name = "int";
structures.back().size = 4;
indices["short"] = structures.size();
structures.push_back( Structure() ); indices["short"] = structures.size();
structures.back().name = "short"; structures.push_back( Structure() );
structures.back().size = 2; structures.back().name = "short";
structures.back().size = 2;
indices["char"] = structures.size();
structures.push_back( Structure() ); indices["char"] = structures.size();
structures.back().name = "char"; structures.push_back( Structure() );
structures.back().size = 1; structures.back().name = "char";
structures.back().size = 1;
indices["float"] = structures.size();
structures.push_back( Structure() ); indices["float"] = structures.size();
structures.back().name = "float"; structures.push_back( Structure() );
structures.back().size = 4; structures.back().name = "float";
structures.back().size = 4;
indices["double"] = structures.size();
structures.push_back( Structure() ); indices["double"] = structures.size();
structures.back().name = "double"; structures.push_back( Structure() );
structures.back().size = 8; structures.back().name = "double";
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[] = {
stream.GetI1(), const char tmp[] = {
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.address.val = ptr64 ? stream.GetU8() : stream.GetU4(); current.size = stream.GetI4();
current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
current.dna_index = stream.GetI4();
current.num = stream.GetI4(); current.dna_index = stream.GetI4();
current.num = stream.GetI4();
current.start = stream.GetCurrentPos();
if (stream.GetRemainingSizeToLimit() < current.size) { current.start = stream.GetCurrentPos();
throw DeadlyImportError("BLEND: invalid size of file block"); if (stream.GetRemainingSizeToLimit() < current.size) {
} throw DeadlyImportError("BLEND: invalid size of file block");
}
#ifdef ASSIMP_BUILD_BLENDER_DEBUG
DefaultLogger::get()->debug(current.id); #ifdef ASSIMP_BUILD_BLENDER_DEBUG
#endif DefaultLogger::get()->debug(current.id);
} #endif
}
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,183 +1,204 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderIntermediate.h /** @file BlenderIntermediate.h
* @brief Internal utility structures for the BlenderLoader. It also serves * @brief Internal utility structures for the BlenderLoader. It also serves
* as master include file for the whole (internal) Blender subsystem. * as master include file for the whole (internal) Blender subsystem.
*/ */
#ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H #ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H
#define INCLUDED_AI_BLEND_INTERMEDIATE_H #define INCLUDED_AI_BLEND_INTERMEDIATE_H
#include "BlenderLoader.h" #include "BlenderLoader.h"
#include "BlenderDNA.h" #include "BlenderDNA.h"
#include "BlenderScene.h" #include "BlenderScene.h"
#include "BlenderSceneGen.h" #include "BlenderSceneGen.h"
#include <boost/foreach.hpp>
#define for_each(x,y) BOOST_FOREACH(x,y) #include <deque>
#include "./../include/assimp/material.h"
namespace Assimp {
namespace Blender { struct aiTexture;
// -------------------------------------------------------------------- #define for_each(x,y) BOOST_FOREACH(x,y)
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
// -------------------------------------------------------------------- namespace Assimp {
template <template <typename,typename> class TCLASS, typename T> namespace Blender {
struct TempArray {
typedef TCLASS< T*,std::allocator<T*> > mywrap; // --------------------------------------------------------------------
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
TempArray() { // --------------------------------------------------------------------
} template <template <typename,typename> class TCLASS, typename T>
struct TempArray {
~TempArray () { typedef TCLASS< T*,std::allocator<T*> > mywrap;
for_each(T* elem, arr) {
delete elem; TempArray() {
} }
}
~TempArray () {
void dismiss() { for_each(T* elem, arr) {
arr.clear(); delete elem;
} }
}
mywrap* operator -> () {
return &arr; void dismiss() {
} arr.clear();
}
operator mywrap& () {
return arr; mywrap* operator -> () {
} return &arr;
}
operator const mywrap& () const {
return arr; operator mywrap& () {
} return arr;
}
mywrap& get () {
return arr; operator const mywrap& () const {
} return arr;
}
const mywrap& get () const {
return arr; mywrap& get () {
} return arr;
}
T* operator[] (size_t idx) const {
return arr[idx]; const mywrap& get () const {
} return arr;
}
T*& operator[] (size_t idx) {
return arr[idx]; T* operator[] (size_t idx) const {
} return arr[idx];
}
private:
// no copy semantics T*& operator[] (size_t idx) {
void operator= (const TempArray&) { return arr[idx];
} }
TempArray(const TempArray& arr) { private:
} // no copy semantics
void operator= (const TempArray&) {
private: }
mywrap arr;
}; TempArray(const TempArray& arr) {
}
#ifdef _MSC_VER
# pragma warning(disable:4351) private:
#endif mywrap arr;
// -------------------------------------------------------------------- };
/** ConversionData acts as intermediate storage location for
* the various ConvertXXX routines in BlenderImporter.*/ #ifdef _MSC_VER
// -------------------------------------------------------------------- # pragma warning(disable:4351)
struct ConversionData #endif
{
ConversionData(const FileDatabase& db) struct ObjectCompare {
: sentinel_cnt() bool operator() (const Object* left, const Object* right) const {
, next_texture() return strcmp(left->id.name, right->id.name) == -1;
, db(db) }
{} };
std::set<const Object*> objects; // When keeping objects in sets, sort them by their name.
typedef std::set<const Object*, ObjectCompare> ObjectSet;
TempArray <std::vector, aiMesh> meshes;
TempArray <std::vector, aiCamera> cameras; // --------------------------------------------------------------------
TempArray <std::vector, aiLight> lights; /** ConversionData acts as intermediate storage location for
TempArray <std::vector, aiMaterial> materials; * the various ConvertXXX routines in BlenderImporter.*/
TempArray <std::vector, aiTexture> textures; // --------------------------------------------------------------------
struct ConversionData
// set of all materials referenced by at least one mesh in the scene {
std::deque< boost::shared_ptr< Material > > materials_raw; ConversionData(const FileDatabase& db)
: sentinel_cnt()
// counter to name sentinel textures inserted as substitutes for procedural textures. , next_texture()
unsigned int sentinel_cnt; , db(db)
{}
// next texture ID for each texture type, respectively
unsigned int next_texture[aiTextureType_UNKNOWN+1]; struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const {
// original file data return strcmp(left->id.name, right->id.name) == -1;
const FileDatabase& db; }
}; };
#ifdef _MSC_VER
# pragma warning(default:4351) ObjectSet objects;
#endif
TempArray <std::vector, aiMesh> meshes;
// ------------------------------------------------------------------------------------------------ TempArray <std::vector, aiCamera> cameras;
inline const char* GetTextureTypeDisplayString(Tex::Type t) TempArray <std::vector, aiLight> lights;
{ TempArray <std::vector, aiMaterial> materials;
switch (t) { TempArray <std::vector, aiTexture> textures;
case Tex::Type_CLOUDS : return "Clouds";
case Tex::Type_WOOD : return "Wood"; // set of all materials referenced by at least one mesh in the scene
case Tex::Type_MARBLE : return "Marble"; std::deque< boost::shared_ptr< Material > > materials_raw;
case Tex::Type_MAGIC : return "Magic";
case Tex::Type_BLEND : return "Blend"; // counter to name sentinel textures inserted as substitutes for procedural textures.
case Tex::Type_STUCCI : return "Stucci"; unsigned int sentinel_cnt;
case Tex::Type_NOISE : return "Noise";
case Tex::Type_PLUGIN : return "Plugin"; // next texture ID for each texture type, respectively
case Tex::Type_MUSGRAVE : return "Musgrave"; unsigned int next_texture[aiTextureType_UNKNOWN+1];
case Tex::Type_VORONOI : return "Voronoi";
case Tex::Type_DISTNOISE : return "DistortedNoise"; // original file data
case Tex::Type_ENVMAP : return "EnvMap"; const FileDatabase& db;
case Tex::Type_IMAGE : return "Image"; };
default: #ifdef _MSC_VER
break; # pragma warning(default:4351)
} #endif
return "<Unknown>";
} // ------------------------------------------------------------------------------------------------
inline const char* GetTextureTypeDisplayString(Tex::Type t)
} // ! Blender {
} // ! Assimp switch (t) {
case Tex::Type_CLOUDS : return "Clouds";
#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H case Tex::Type_WOOD : return "Wood";
case Tex::Type_MARBLE : return "Marble";
case Tex::Type_MAGIC : return "Magic";
case Tex::Type_BLEND : return "Blend";
case Tex::Type_STUCCI : return "Stucci";
case Tex::Type_NOISE : return "Noise";
case Tex::Type_PLUGIN : return "Plugin";
case Tex::Type_MUSGRAVE : return "Musgrave";
case Tex::Type_VORONOI : return "Voronoi";
case Tex::Type_DISTNOISE : return "DistortedNoise";
case Tex::Type_ENVMAP : return "EnvMap";
case Tex::Type_IMAGE : return "Image";
default:
break;
}
return "<Unknown>";
}
} // ! Blender
} // ! Assimp
#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,223 +1,230 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderLoader.h /** @file BlenderLoader.h
* @brief Declaration of the Blender 3D (*.blend) importer class. * @brief Declaration of the Blender 3D (*.blend) importer class.
*/ */
#ifndef INCLUDED_AI_BLEND_LOADER_H #ifndef INCLUDED_AI_BLEND_LOADER_H
#define INCLUDED_AI_BLEND_LOADER_H #define INCLUDED_AI_BLEND_LOADER_H
#include "BaseImporter.h" #include "BaseImporter.h"
#include "LogAux.h" #include "LogAux.h"
#include <boost/shared_ptr.hpp>
namespace Assimp {
struct aiNode;
// TinyFormatter.h struct aiMesh;
namespace Formatter { struct aiLight;
template <typename T,typename TR, typename A> class basic_formatter; struct aiCamera;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; struct aiMaterial;
}
namespace Assimp {
// BlenderDNA.h
namespace Blender { // TinyFormatter.h
class FileDatabase; namespace Formatter {
struct ElemBase; template <typename T,typename TR, typename A> class basic_formatter;
} typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
}
// BlenderScene.h
namespace Blender { // BlenderDNA.h
struct Scene; namespace Blender {
struct Object; class FileDatabase;
struct Mesh; struct ElemBase;
struct Camera; }
struct Lamp;
struct MTex; // BlenderScene.h
struct Image; namespace Blender {
struct Material; struct Scene;
} struct Object;
struct Mesh;
// BlenderIntermediate.h struct Camera;
namespace Blender { struct Lamp;
struct ConversionData; struct MTex;
template <template <typename,typename> class TCLASS, typename T> struct TempArray; struct Image;
} struct Material;
}
// BlenderModifier.h
namespace Blender { // BlenderIntermediate.h
class BlenderModifierShowcase; namespace Blender {
class BlenderModifier; struct ConversionData;
} template <template <typename,typename> class TCLASS, typename T> struct TempArray;
}
// BlenderModifier.h
// ------------------------------------------------------------------------------------------- namespace Blender {
/** Load blenders official binary format. The actual file structure (the `DNA` how they class BlenderModifierShowcase;
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the class BlenderModifier;
* conversion from intermediate format to aiScene. */ }
// -------------------------------------------------------------------------------------------
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
{
public: // -------------------------------------------------------------------------------------------
BlenderImporter(); /** Load blenders official binary format. The actual file structure (the `DNA` how they
~BlenderImporter(); * call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
* conversion from intermediate format to aiScene. */
// -------------------------------------------------------------------------------------------
public: class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
{
// -------------------- public:
bool CanRead( const std::string& pFile, BlenderImporter();
IOSystem* pIOHandler, ~BlenderImporter();
bool checkSig
) const;
public:
protected:
// --------------------
// -------------------- bool CanRead( const std::string& pFile,
const aiImporterDesc* GetInfo () const; IOSystem* pIOHandler,
bool checkSig
// -------------------- ) const;
void GetExtensionList(std::set<std::string>& app);
protected:
// --------------------
void SetupProperties(const Importer* pImp); // --------------------
const aiImporterDesc* GetInfo () const;
// --------------------
void InternReadFile( const std::string& pFile, // --------------------
aiScene* pScene, void GetExtensionList(std::set<std::string>& app);
IOSystem* pIOHandler
); // --------------------
void SetupProperties(const Importer* pImp);
// --------------------
void ParseBlendFile(Blender::FileDatabase& out, // --------------------
boost::shared_ptr<IOStream> stream void InternReadFile( const std::string& pFile,
); aiScene* pScene,
IOSystem* pIOHandler
// -------------------- );
void ExtractScene(Blender::Scene& out,
const Blender::FileDatabase& file // --------------------
); void ParseBlendFile(Blender::FileDatabase& out,
boost::shared_ptr<IOStream> stream
// -------------------- );
void ConvertBlendFile(aiScene* out,
const Blender::Scene& in, // --------------------
const Blender::FileDatabase& file void ExtractScene(Blender::Scene& out,
); const Blender::FileDatabase& file
);
private:
// --------------------
// -------------------- void ConvertBlendFile(aiScene* out,
aiNode* ConvertNode(const Blender::Scene& in, const Blender::Scene& in,
const Blender::Object* obj, const Blender::FileDatabase& file
Blender::ConversionData& conv_info, );
const aiMatrix4x4& parentTransform
); private:
// -------------------- // --------------------
void ConvertMesh(const Blender::Scene& in, aiNode* ConvertNode(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Mesh* mesh, Blender::ConversionData& conv_info,
Blender::ConversionData& conv_data, const aiMatrix4x4& parentTransform
Blender::TempArray<std::vector,aiMesh>& temp );
);
// --------------------
// -------------------- void ConvertMesh(const Blender::Scene& in,
aiLight* ConvertLight(const Blender::Scene& in, const Blender::Object* obj,
const Blender::Object* obj, const Blender::Mesh* mesh,
const Blender::Lamp* mesh, Blender::ConversionData& conv_data,
Blender::ConversionData& conv_data Blender::TempArray<std::vector,aiMesh>& temp
); );
// -------------------- // --------------------
aiCamera* ConvertCamera(const Blender::Scene& in, aiLight* ConvertLight(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Camera* mesh, const Blender::Lamp* mesh,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
void BuildMaterials( aiCamera* ConvertCamera(const Blender::Scene& in,
Blender::ConversionData& conv_data const Blender::Object* obj,
) ; const Blender::Camera* mesh,
Blender::ConversionData& conv_data
// -------------------- );
void ResolveTexture(
aiMaterial* out, // --------------------
const Blender::Material* mat, void BuildMaterials(
const Blender::MTex* tex, Blender::ConversionData& conv_data
Blender::ConversionData& conv_data ) ;
);
// --------------------
// -------------------- void ResolveTexture(
void ResolveImage( aiMaterial* out,
aiMaterial* out, const Blender::Material* mat,
const Blender::Material* mat, const Blender::MTex* tex,
const Blender::MTex* tex, Blender::ConversionData& conv_data
const Blender::Image* img, );
Blender::ConversionData& conv_data
); // --------------------
void ResolveImage(
void AddSentinelTexture( aiMaterial* out,
aiMaterial* out, const Blender::Material* mat,
const Blender::Material* mat, const Blender::MTex* tex,
const Blender::MTex* tex, const Blender::Image* img,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
private: // static stuff, mostly logging and error reporting. void AddSentinelTexture(
aiMaterial* out,
// -------------------- const Blender::Material* mat,
static void CheckActualType(const Blender::ElemBase* dt, const Blender::MTex* tex,
const char* check Blender::ConversionData& conv_data
); );
// -------------------- private: // static stuff, mostly logging and error reporting.
static void NotSupportedObjectType(const Blender::Object* obj,
const char* type // --------------------
); static void CheckActualType(const Blender::ElemBase* dt,
const char* check
);
private:
// --------------------
Blender::BlenderModifierShowcase* modifier_cache; static void NotSupportedObjectType(const Blender::Object* obj,
const char* type
}; // !class BlenderImporter );
} // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC private:
Blender::BlenderModifierShowcase* modifier_cache;
}; // !class BlenderImporter
} // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC

View File

@ -1,324 +1,328 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderModifier.cpp /** @file BlenderModifier.cpp
* @brief Implementation of some blender modifiers (i.e subdivision, mirror). * @brief Implementation of some blender modifiers (i.e subdivision, mirror).
*/ */
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
#include "BlenderModifier.h" #include "BlenderModifier.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "Subdivision.h" #include "Subdivision.h"
#include "../include/assimp/scene.h"
#include <functional> #include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
using namespace Assimp; #include <boost/pointer_cast.hpp>
using namespace Assimp::Blender;
#include <functional>
template <typename T> BlenderModifier* god() {
return new T(); using namespace Assimp;
} using namespace Assimp::Blender;
// add all available modifiers here template <typename T> BlenderModifier* god() {
typedef BlenderModifier* (*fpCreateModifier)(); return new T();
static const fpCreateModifier creators[] = { }
&god<BlenderModifier_Mirror>,
&god<BlenderModifier_Subdivision>, // add all available modifiers here
typedef BlenderModifier* (*fpCreateModifier)();
NULL // sentinel static const fpCreateModifier creators[] = {
}; &god<BlenderModifier_Mirror>,
&god<BlenderModifier_Subdivision>,
// ------------------------------------------------------------------------------------------------
// just testing out some new macros to simplify logging NULL // sentinel
#define ASSIMP_LOG_WARN_F(string,...)\ };
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
// ------------------------------------------------------------------------------------------------
#define ASSIMP_LOG_ERROR_F(string,...)\ // just testing out some new macros to simplify logging
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__)) #define ASSIMP_LOG_WARN_F(string,...)\
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_DEBUG_F(string,...)\
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__)) #define ASSIMP_LOG_ERROR_F(string,...)\
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_INFO_F(string,...)\
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__)) #define ASSIMP_LOG_DEBUG_F(string,...)\
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_WARN(string)\ #define ASSIMP_LOG_INFO_F(string,...)\
DefaultLogger::get()->warn(string) DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_ERROR(string)\
DefaultLogger::get()->error(string) #define ASSIMP_LOG_WARN(string)\
DefaultLogger::get()->warn(string)
#define ASSIMP_LOG_DEBUG(string)\
DefaultLogger::get()->debug(string) #define ASSIMP_LOG_ERROR(string)\
DefaultLogger::get()->error(string)
#define ASSIMP_LOG_INFO(string)\
DefaultLogger::get()->info(string) #define ASSIMP_LOG_DEBUG(string)\
DefaultLogger::get()->debug(string)
// ------------------------------------------------------------------------------------------------ #define ASSIMP_LOG_INFO(string)\
struct SharedModifierData : ElemBase DefaultLogger::get()->info(string)
{
ModifierData modifier;
}; // ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase
// ------------------------------------------------------------------------------------------------ {
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object ) ModifierData modifier;
{ };
size_t cnt = 0u, ful = 0u;
// ------------------------------------------------------------------------------------------------
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
// 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 size_t cnt = 0u, ful = 0u;
// structures is at offset sizeof(vftable) with no padding.
const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() ); // NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) { // we're allowed to dereference the pointers without risking to crash. We might still be
ai_assert(cur->dna_type); // invoking UB btw - we're assuming that the ModifierData member of the respective modifier
// structures is at offset sizeof(vftable) with no padding.
const Structure* s = conv_data.db.dna.Get( cur->dna_type ); const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
if (!s) { for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type); ai_assert(cur->dna_type);
continue;
} const Structure* s = conv_data.db.dna.Get( cur->dna_type );
if (!s) {
// this is a common trait of all XXXMirrorData structures in BlenderDNA ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
const Field* f = s->Get("modifier"); continue;
if (!f || f->offset != 0) { }
ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
continue; // this is a common trait of all XXXMirrorData structures in BlenderDNA
} const Field* f = s->Get("modifier");
if (!f || f->offset != 0) {
s = conv_data.db.dna.Get( f->type ); ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
if (!s || s->name != "ModifierData") { continue;
ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member"); }
continue;
} s = conv_data.db.dna.Get( f->type );
if (!s || s->name != "ModifierData") {
// now, we can be sure that we should be fine to dereference *cur* as ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
// ModifierData (with the above note). continue;
const ModifierData& dat = cur->modifier; }
const fpCreateModifier* curgod = creators; // now, we can be sure that we should be fine to dereference *cur* as
std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end(); // ModifierData (with the above note).
const ModifierData& dat = cur->modifier;
for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
if (curmod == endmod) { const fpCreateModifier* curgod = creators;
cached_modifiers->push_back((*curgod)()); std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
endmod = cached_modifiers->end(); for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
curmod = endmod-1; if (curmod == endmod) {
} cached_modifiers->push_back((*curgod)());
BlenderModifier* const modifier = *curmod; endmod = cached_modifiers->end();
if(modifier->IsActive(dat)) { curmod = endmod-1;
modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object); }
cnt++;
BlenderModifier* const modifier = *curmod;
curgod = NULL; if(modifier->IsActive(dat)) {
break; modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
} cnt++;
}
if (curgod) { curgod = NULL;
ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name); break;
} }
} }
if (curgod) {
// Even though we managed to resolve some or all of the modifiers on this ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
// object, we still can't say whether our modifier implementations were }
// able to fully do their job. }
if (ful) {
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name, // Even though we managed to resolve some or all of the modifiers on this
"`, check log messages above for errors"); // object, we still can't say whether our modifier implementations were
} // able to fully do their job.
} if (ful) {
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
"`, check log messages above for errors");
}
// ------------------------------------------------------------------------------------------------ }
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
{
return modin.type == ModifierData::eModifierType_Mirror;
} // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
// ------------------------------------------------------------------------------------------------ {
void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier, return modin.type == ModifierData::eModifierType_Mirror;
const Scene& /*in*/, }
const Object& orig_object )
{ // ------------------------------------------------------------------------------------------------
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier); const Scene& /*in*/,
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror); const Object& orig_object )
{
conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes); // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
// XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ... ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
// take all input meshes and clone them conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
aiMesh* mesh; // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
// take all input meshes and clone them
const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f; for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f; aiMesh* mesh;
const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f; SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
if (mir.mirror_ob) { const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] ); const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
aiVector3D& v = mesh->mVertices[i];
if (mir.mirror_ob) {
v.x = center.x + xs*(center.x - v.x); const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
v.y = center.y + ys*(center.y - v.y); for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
v.z = center.z + zs*(center.z - v.z); aiVector3D& v = mesh->mVertices[i];
}
} v.x = center.x + xs*(center.x - v.x);
else { v.y = center.y + ys*(center.y - v.y);
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { v.z = center.z + zs*(center.z - v.z);
aiVector3D& v = mesh->mVertices[i]; }
v.x *= xs;v.y *= ys;v.z *= zs; }
} else {
} for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i];
if (mesh->mNormals) { v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { }
aiVector3D& v = mesh->mNormals[i]; }
v.x *= xs;v.y *= ys;v.z *= zs;
} if (mesh->mNormals) {
} for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mNormals[i];
if (mesh->mTangents) { v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { }
aiVector3D& v = mesh->mTangents[i]; }
v.x *= xs;v.y *= ys;v.z *= zs;
} if (mesh->mTangents) {
} for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTangents[i];
if (mesh->mBitangents) { v.x *= xs;v.y *= ys;v.z *= zs;
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { }
aiVector3D& v = mesh->mBitangents[i]; }
v.x *= xs;v.y *= ys;v.z *= zs;
} if (mesh->mBitangents) {
} for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mBitangents[i];
const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f; v.x *= xs;v.y *= ys;v.z *= zs;
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 i = 0; i < mesh->mNumVertices; ++i) { const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
aiVector3D& v = mesh->mTextureCoords[n][i]; const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
v.x *= us;v.y *= vs;
} for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
} for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTextureCoords[n][i];
// Only reverse the winding order if an odd number of axes were mirrored. v.x *= us;v.y *= vs;
if (xs * ys * zs < 0) { }
for( unsigned int i = 0; i < mesh->mNumFaces; i++) { }
aiFace& face = mesh->mFaces[i];
for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi) // Only reverse the winding order if an odd number of axes were mirrored.
std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]); if (xs * ys * zs < 0) {
} for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
} aiFace& face = mesh->mFaces[i];
for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
conv_data.meshes->push_back(mesh); std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
} }
unsigned int* nind = new unsigned int[out.mNumMeshes*2]; }
std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind); conv_data.meshes->push_back(mesh);
std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes, }
std::bind1st(std::plus< unsigned int >(),out.mNumMeshes)); unsigned int* nind = new unsigned int[out.mNumMeshes*2];
delete[] out.mMeshes; std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
out.mMeshes = nind; std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
out.mNumMeshes *= 2; std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `", delete[] out.mMeshes;
orig_object.id.name,"`"); out.mMeshes = nind;
} out.mNumMeshes *= 2;
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
orig_object.id.name,"`");
}
// ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
{
return modin.type == ModifierData::eModifierType_Subsurf;
} // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
// ------------------------------------------------------------------------------------------------ {
void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier, return modin.type == ModifierData::eModifierType_Subsurf;
const Scene& /*in*/, }
const Object& orig_object )
{ // ------------------------------------------------------------------------------------------------
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier); const Scene& /*in*/,
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf); const Object& orig_object )
{
Subdivider::Algorithm algo; // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
switch (mir.subdivType) const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
{ ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
case SubsurfModifierData::TYPE_CatmullClarke:
algo = Subdivider::CATMULL_CLARKE; Subdivider::Algorithm algo;
break; switch (mir.subdivType)
{
case SubsurfModifierData::TYPE_Simple: case SubsurfModifierData::TYPE_CatmullClarke:
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;
case SubsurfModifierData::TYPE_Simple:
default: ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType); algo = Subdivider::CATMULL_CLARKE;
return; break;
};
default:
boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo)); ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
ai_assert(subd); return;
};
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]()); boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
ai_assert(subd);
subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes); aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
orig_object.id.name,"`"); subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
} std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
#endif ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
orig_object.id.name,"`");
}
#endif

View File

@ -1,155 +1,155 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderModifier.h /** @file BlenderModifier.h
* @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror) * @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror)
*/ */
#ifndef INCLUDED_AI_BLEND_MODIFIER_H #ifndef INCLUDED_AI_BLEND_MODIFIER_H
#define INCLUDED_AI_BLEND_MODIFIER_H #define INCLUDED_AI_BLEND_MODIFIER_H
#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
* they should be stateless and not try to cache model data. */ * they should be stateless and not try to cache model data. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier 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;
} }
}; };
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Manage all known modifiers and instance and apply them if necessary */ /** Manage all known modifiers and instance and apply them if necessary */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifierShowcase 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;
}; };
// MODIFIERS // MODIFIERS
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Mirror modifier. Status: implemented. */ /** Mirror modifier. Status: implemented. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier_Mirror : public BlenderModifier 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
) ; ) ;
}; };
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Subdivision modifier. Status: dummy. */ /** Subdivision modifier. Status: dummy. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderModifier_Subdivision : public BlenderModifier 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
) ; ) ;
}; };
}} }}
#endif // !INCLUDED_AI_BLEND_MODIFIER_H #endif // !INCLUDED_AI_BLEND_MODIFIER_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,253 +1,256 @@
/* /*
Open Asset Import Library (ASSIMP) Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2010, ASSIMP Development Team Copyright (c) 2006-2010, ASSIMP Development 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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its * Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the ASSIMP Development Team. written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file BlenderSceneGen.h /** @file BlenderSceneGen.h
* @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
*/ */
#ifndef INCLUDED_AI_BLEND_SCENEGEN_H #ifndef INCLUDED_AI_BLEND_SCENEGEN_H
#define INCLUDED_AI_BLEND_SCENEGEN_H #define INCLUDED_AI_BLEND_SCENEGEN_H
namespace Assimp { #include "BlenderDNA.h"
namespace Blender { #include "BlenderScene.h"
namespace Assimp {
template <> void Structure :: Convert<Object> ( namespace Blender {
Object& dest,
const FileDatabase& db
) const template <> void Structure :: Convert<Object> (
; Object& dest,
const FileDatabase& db
template <> void Structure :: Convert<Group> ( ) const
Group& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Group> (
; Group& dest,
const FileDatabase& db
template <> void Structure :: Convert<MTex> ( ) const
MTex& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MTex> (
; MTex& dest,
const FileDatabase& db
template <> void Structure :: Convert<TFace> ( ) const
TFace& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<TFace> (
; TFace& dest,
const FileDatabase& db
template <> void Structure :: Convert<SubsurfModifierData> ( ) const
SubsurfModifierData& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<SubsurfModifierData> (
; SubsurfModifierData& dest,
const FileDatabase& db
template <> void Structure :: Convert<MFace> ( ) const
MFace& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MFace> (
; MFace& dest,
const FileDatabase& db
template <> void Structure :: Convert<Lamp> ( ) const
Lamp& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Lamp> (
; Lamp& dest,
const FileDatabase& db
template <> void Structure :: Convert<MDeformWeight> ( ) const
MDeformWeight& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MDeformWeight> (
; MDeformWeight& dest,
const FileDatabase& db
template <> void Structure :: Convert<PackedFile> ( ) const
PackedFile& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<PackedFile> (
; PackedFile& dest,
const FileDatabase& db
template <> void Structure :: Convert<Base> ( ) const
Base& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Base> (
; Base& dest,
const FileDatabase& db
template <> void Structure :: Convert<MTFace> ( ) const
MTFace& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MTFace> (
; MTFace& dest,
const FileDatabase& db
template <> void Structure :: Convert<Material> ( ) const
Material& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Material> (
; Material& dest,
const FileDatabase& db
template <> void Structure :: Convert<MTexPoly> ( ) const
MTexPoly& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MTexPoly> (
; MTexPoly& dest,
const FileDatabase& db
template <> void Structure :: Convert<Mesh> ( ) const
Mesh& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Mesh> (
; Mesh& dest,
const FileDatabase& db
template <> void Structure :: Convert<MDeformVert> ( ) const
MDeformVert& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MDeformVert> (
; MDeformVert& dest,
const FileDatabase& db
template <> void Structure :: Convert<World> ( ) const
World& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<World> (
; World& dest,
const FileDatabase& db
template <> void Structure :: Convert<MLoopCol> ( ) const
MLoopCol& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MLoopCol> (
; MLoopCol& dest,
const FileDatabase& db
template <> void Structure :: Convert<MVert> ( ) const
MVert& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MVert> (
; MVert& dest,
const FileDatabase& db
template <> void Structure :: Convert<MEdge> ( ) const
MEdge& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MEdge> (
; MEdge& dest,
const FileDatabase& db
template <> void Structure :: Convert<MLoopUV> ( ) const
MLoopUV& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MLoopUV> (
; MLoopUV& dest,
const FileDatabase& db
template <> void Structure :: Convert<GroupObject> ( ) const
GroupObject& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<GroupObject> (
; GroupObject& dest,
const FileDatabase& db
template <> void Structure :: Convert<ListBase> ( ) const
ListBase& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<ListBase> (
; ListBase& dest,
const FileDatabase& db
template <> void Structure :: Convert<MLoop> ( ) const
MLoop& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MLoop> (
; MLoop& dest,
const FileDatabase& db
template <> void Structure :: Convert<ModifierData> ( ) const
ModifierData& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<ModifierData> (
; ModifierData& dest,
const FileDatabase& db
template <> void Structure :: Convert<ID> ( ) const
ID& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<ID> (
; ID& dest,
const FileDatabase& db
template <> void Structure :: Convert<MCol> ( ) const
MCol& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MCol> (
; MCol& dest,
const FileDatabase& db
template <> void Structure :: Convert<MPoly> ( ) const
MPoly& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MPoly> (
; MPoly& dest,
const FileDatabase& db
template <> void Structure :: Convert<Scene> ( ) const
Scene& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Scene> (
; Scene& dest,
const FileDatabase& db
template <> void Structure :: Convert<Library> ( ) const
Library& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Library> (
; Library& dest,
const FileDatabase& db
template <> void Structure :: Convert<Tex> ( ) const
Tex& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Tex> (
; Tex& dest,
const FileDatabase& db
template <> void Structure :: Convert<Camera> ( ) const
Camera& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Camera> (
; Camera& dest,
const FileDatabase& db
template <> void Structure :: Convert<MirrorModifierData> ( ) const
MirrorModifierData& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<MirrorModifierData> (
; MirrorModifierData& dest,
const FileDatabase& db
template <> void Structure :: Convert<Image> ( ) const
Image& dest, ;
const FileDatabase& db
) const template <> void Structure :: Convert<Image> (
; Image& dest,
const FileDatabase& db
) const
} ;
}
#endif }
}
#endif

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2013, assimp team Copyright (c) 2006-2013, 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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief A simple tessellation wrapper * @brief A simple tessellation wrapper
*/ */
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
@ -57,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;
@ -69,7 +68,7 @@ using namespace Assimp::Blender;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ): BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
converter( &converter ) converter( &converter )
{ {
} }
@ -81,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
@ -250,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;
@ -258,7 +257,7 @@ using namespace Assimp::Blender;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ): BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ):
converter( &converter ) converter( &converter )
{ {
} }
@ -270,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;
} }
@ -449,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

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2013, assimp team Copyright (c) 2006-2013, 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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -46,15 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Use these to toggle between GLU Tessellate or poly2tri // Use these to toggle between GLU Tessellate or poly2tri
// Note (acg) keep GLU Tesselate disabled by default - if it is turned on, // Note (acg) keep GLU Tesselate disabled by default - if it is turned on,
// assimp needs to be linked against GLU, which is currently not yet // assimp needs to be linked against GLU, which is currently not yet
// 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

View File

@ -1,326 +1,337 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Provides cheat implementations for IOSystem and IOStream to /** @file Provides cheat implementations for IOSystem and IOStream to
* redirect exporter output to a blob chain.*/ * redirect exporter output to a blob chain.*/
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED #ifndef AI_BLOBIOSYSTEM_H_INCLUDED
#define AI_BLOBIOSYSTEM_H_INCLUDED #define AI_BLOBIOSYSTEM_H_INCLUDED
namespace Assimp { #include "./../include/assimp/IOStream.hpp"
class BlobIOSystem; #include "./../include/assimp/cexport.h"
#include "./../include/assimp/IOSystem.hpp"
// -------------------------------------------------------------------------------------------- #include "./../include/assimp/DefaultLogger.hpp"
/** Redirect IOStream to a blob */ #include <boost/foreach.hpp>
// -------------------------------------------------------------------------------------------- #include <stdint.h>
class BlobIOStream : public IOStream #include <set>
{ #include <vector>
public:
namespace Assimp {
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096) class BlobIOSystem;
: buffer()
, cur_size() // --------------------------------------------------------------------------------------------
, file_size() /** Redirect IOStream to a blob */
, cursor() // --------------------------------------------------------------------------------------------
, initial(initial) class BlobIOStream : public IOStream
, file(file) {
, creator(creator) public:
{
} BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
: buffer()
, cur_size()
virtual ~BlobIOStream(); , file_size()
, cursor()
public: , initial(initial)
, file(file)
// ------------------------------------------------------------------- , creator(creator)
aiExportDataBlob* GetBlob() {
{ }
aiExportDataBlob* blob = new aiExportDataBlob();
blob->size = file_size;
blob->data = buffer; virtual ~BlobIOStream();
buffer = NULL; public:
return blob; // -------------------------------------------------------------------
} aiExportDataBlob* GetBlob()
{
aiExportDataBlob* blob = new aiExportDataBlob();
public: blob->size = file_size;
blob->data = buffer;
// ------------------------------------------------------------------- buffer = NULL;
virtual size_t Read( void *,
size_t, return blob;
size_t ) }
{
return 0;
} public:
// -------------------------------------------------------------------
virtual size_t Write(const void* pvBuffer, // -------------------------------------------------------------------
size_t pSize, virtual size_t Read( void *,
size_t pCount) size_t,
{ size_t )
pSize *= pCount; {
if (cursor + pSize > cur_size) { return 0;
Grow(cursor + pSize); }
}
// -------------------------------------------------------------------
memcpy(buffer+cursor, pvBuffer, pSize); virtual size_t Write(const void* pvBuffer,
cursor += pSize; size_t pSize,
size_t pCount)
file_size = std::max(file_size,cursor); {
return pCount; pSize *= pCount;
} if (cursor + pSize > cur_size) {
Grow(cursor + pSize);
// ------------------------------------------------------------------- }
virtual aiReturn Seek(size_t pOffset,
aiOrigin pOrigin) memcpy(buffer+cursor, pvBuffer, pSize);
{ cursor += pSize;
switch(pOrigin)
{ file_size = std::max(file_size,cursor);
case aiOrigin_CUR: return pCount;
cursor += pOffset; }
case aiOrigin_END: // -------------------------------------------------------------------
cursor = file_size - pOffset; virtual aiReturn Seek(size_t pOffset,
aiOrigin pOrigin)
case aiOrigin_SET: {
cursor = pOffset; switch(pOrigin)
break; {
case aiOrigin_CUR:
default: cursor += pOffset;
return AI_FAILURE; break;
}
case aiOrigin_END:
if (cursor > file_size) { cursor = file_size - pOffset;
Grow(cursor); break;
}
case aiOrigin_SET:
file_size = std::max(cursor,file_size); cursor = pOffset;
return AI_SUCCESS; break;
}
default:
// ------------------------------------------------------------------- return AI_FAILURE;
virtual size_t Tell() const }
{
return cursor; if (cursor > file_size) {
} Grow(cursor);
}
// -------------------------------------------------------------------
virtual size_t FileSize() const file_size = std::max(cursor,file_size);
{ return AI_SUCCESS;
return file_size; }
}
// -------------------------------------------------------------------
// ------------------------------------------------------------------- virtual size_t Tell() const
virtual void Flush() {
{ return cursor;
// ignore }
}
// -------------------------------------------------------------------
virtual size_t FileSize() const
{
private: return file_size;
}
// -------------------------------------------------------------------
void Grow(size_t need = 0) // -------------------------------------------------------------------
{ virtual void Flush()
// 1.5 and phi are very heap-friendly growth factors (the first {
// allows for frequent re-use of heap blocks, the second // ignore
// forms a fibonacci sequence with similar characteristics - }
// since this heavily depends on the heap implementation
// and other factors as well, i'll just go with 1.5 since
// it is quicker to compute).
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); private:
const uint8_t* const old = buffer; // -------------------------------------------------------------------
buffer = new uint8_t[new_size]; void Grow(size_t need = 0)
{
if (old) { // 1.5 and phi are very heap-friendly growth factors (the first
memcpy(buffer,old,cur_size); // allows for frequent re-use of heap blocks, the second
delete[] old; // forms a fibonacci sequence with similar characteristics -
} // since this heavily depends on the heap implementation
// and other factors as well, i'll just go with 1.5 since
cur_size = new_size; // it is quicker to compute).
} size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
private: const uint8_t* const old = buffer;
buffer = new uint8_t[new_size];
uint8_t* buffer;
size_t cur_size,file_size, cursor, initial; if (old) {
memcpy(buffer,old,cur_size);
const std::string file; delete[] old;
BlobIOSystem* const creator; }
};
cur_size = new_size;
}
#define AI_BLOBIO_MAGIC "$blobfile"
private:
// --------------------------------------------------------------------------------------------
/** Redirect IOSystem to a blob */ uint8_t* buffer;
// -------------------------------------------------------------------------------------------- size_t cur_size,file_size, cursor, initial;
class BlobIOSystem : public IOSystem
{ const std::string file;
BlobIOSystem* const creator;
friend class BlobIOStream; };
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
public: #define AI_BLOBIO_MAGIC "$blobfile"
BlobIOSystem() // --------------------------------------------------------------------------------------------
{ /** Redirect IOSystem to a blob */
} // --------------------------------------------------------------------------------------------
class BlobIOSystem : public IOSystem
virtual ~BlobIOSystem() {
{
BOOST_FOREACH(BlobEntry& blobby, blobs) { friend class BlobIOStream;
delete blobby.second; typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
}
} public:
public: BlobIOSystem()
{
// ------------------------------------------------------------------- }
const char* GetMagicFileName() const
{ virtual ~BlobIOSystem()
return AI_BLOBIO_MAGIC; {
} BOOST_FOREACH(BlobEntry& blobby, blobs) {
delete blobby.second;
}
// ------------------------------------------------------------------- }
aiExportDataBlob* GetBlobChain()
{ public:
// one must be the master
aiExportDataBlob* master = NULL, *cur; // -------------------------------------------------------------------
BOOST_FOREACH(const BlobEntry& blobby, blobs) { const char* GetMagicFileName() const
if (blobby.first == AI_BLOBIO_MAGIC) { {
master = blobby.second; return AI_BLOBIO_MAGIC;
break; }
}
}
if (!master) { // -------------------------------------------------------------------
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly."); aiExportDataBlob* GetBlobChain()
return NULL; {
} // one must be the master
aiExportDataBlob* master = NULL, *cur;
master->name.Set(""); BOOST_FOREACH(const BlobEntry& blobby, blobs) {
if (blobby.first == AI_BLOBIO_MAGIC) {
cur = master; master = blobby.second;
BOOST_FOREACH(const BlobEntry& blobby, blobs) { break;
if (blobby.second == master) { }
continue; }
} if (!master) {
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
cur->next = blobby.second; return NULL;
cur = cur->next; }
// extract the file extension from the file written master->name.Set("");
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 = master;
} BOOST_FOREACH(const BlobEntry& blobby, blobs) {
if (blobby.second == master) {
// give up blob ownership continue;
blobs.clear(); }
return master;
} cur->next = blobby.second;
cur = cur->next;
public:
// extract the file extension from the file written
// ------------------------------------------------------------------- const std::string::size_type s = blobby.first.find_first_of('.');
virtual bool Exists( const char* pFile) const { cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
return created.find(std::string(pFile)) != created.end(); }
}
// give up blob ownership
blobs.clear();
// ------------------------------------------------------------------- return master;
virtual char getOsSeparator() const { }
return '/';
} public:
// -------------------------------------------------------------------
// ------------------------------------------------------------------- virtual bool Exists( const char* pFile) const {
virtual IOStream* Open(const char* pFile, return created.find(std::string(pFile)) != created.end();
const char* pMode) }
{
if (pMode[0] != 'w') {
return NULL; // -------------------------------------------------------------------
} virtual char getOsSeparator() const {
return '/';
created.insert(std::string(pFile)); }
return new BlobIOStream(this,std::string(pFile));
}
// -------------------------------------------------------------------
// ------------------------------------------------------------------- virtual IOStream* Open(const char* pFile,
virtual void Close( IOStream* pFile) const char* pMode)
{ {
delete pFile; if (pMode[0] != 'w') {
} return NULL;
}
private:
created.insert(std::string(pFile));
// ------------------------------------------------------------------- return new BlobIOStream(this,std::string(pFile));
void OnDestruct(const std::string& filename, BlobIOStream* child) }
{
// we don't know in which the files are closed, so we // -------------------------------------------------------------------
// can't reliably say that the first must be the master virtual void Close( IOStream* pFile)
// file ... {
blobs.push_back( BlobEntry(filename,child->GetBlob()) ); delete pFile;
} }
private: private:
std::set<std::string> created;
std::vector< BlobEntry > blobs; // -------------------------------------------------------------------
}; void OnDestruct(const std::string& filename, BlobIOStream* child)
{
// we don't know in which the files are closed, so we
// -------------------------------------------------------------------------------------------- // can't reliably say that the first must be the master
BlobIOStream :: ~BlobIOStream() // file ...
{ blobs.push_back( BlobEntry(filename,child->GetBlob()) );
creator->OnDestruct(file,this); }
delete[] buffer;
} private:
std::set<std::string> created;
std::vector< BlobEntry > blobs;
} // end Assimp };
#endif
// --------------------------------------------------------------------------------------------
BlobIOStream :: ~BlobIOStream()
{
creator->OnDestruct(file,this);
delete[] buffer;
}
} // end Assimp
#endif

View File

@ -1,81 +1,82 @@
/* DEPRECATED! - use code/TinyFormatter.h instead. /* DEPRECATED! - use code/TinyFormatter.h instead.
* *
* *
* */ * */
#ifndef AI_BOOST_FORMAT_DUMMY_INCLUDED #ifndef AI_BOOST_FORMAT_DUMMY_INCLUDED
#define AI_BOOST_FORMAT_DUMMY_INCLUDED #define AI_BOOST_FORMAT_DUMMY_INCLUDED
#if (!defined BOOST_FORMAT_HPP) || (defined ASSIMP_FORCE_NOBOOST) #if (!defined BOOST_FORMAT_HPP) || (defined ASSIMP_FORCE_NOBOOST)
#include <string> #include <string>
#include <vector> #include <vector>
#include <sstream>
namespace boost
{ namespace boost
{
class format
{ class format
public: {
format (const std::string& _d) public:
: d(_d) format (const std::string& _d)
{ : d(_d)
} {
}
template <typename T>
format& operator % (T in) template <typename T>
{ format& operator % (T in)
// XXX add replacement for boost::lexical_cast? {
// XXX add replacement for boost::lexical_cast?
std::ostringstream ss;
ss << in; // note: ss cannot be an rvalue, or the global operator << (const char*) is not called for T == const char*. std::ostringstream ss;
chunks.push_back( ss.str()); ss << in; // note: ss cannot be an rvalue, or the global operator << (const char*) is not called for T == const char*.
return *this; chunks.push_back( ss.str());
} return *this;
}
operator std::string () const {
std::string res; // pray for NRVO to kick in operator std::string () const {
std::string res; // pray for NRVO to kick in
size_t start = 0, last = 0;
size_t start = 0, last = 0;
std::vector<std::string>::const_iterator chunkin = chunks.begin();
std::vector<std::string>::const_iterator chunkin = chunks.begin();
for ( start = d.find('%');start != std::string::npos; start = d.find('%',last)) {
res += d.substr(last,start-last); for ( start = d.find('%');start != std::string::npos; start = d.find('%',last)) {
last = start+2; res += d.substr(last,start-last);
if (d[start+1] == '%') { last = start+2;
res += "%"; if (d[start+1] == '%') {
continue; res += "%";
} continue;
}
if (chunkin == chunks.end()) {
break; if (chunkin == chunks.end()) {
} break;
}
res += *chunkin++;
} res += *chunkin++;
res += d.substr(last); }
return res; res += d.substr(last);
} return res;
}
private:
std::string d; private:
std::vector<std::string> chunks; std::string d;
}; std::vector<std::string> chunks;
};
inline std::string str(const std::string& s) {
return s; inline std::string str(const std::string& s) {
} return s;
} }
}
#else
# error "format.h was already included" #else
#endif // # error "format.h was already included"
#endif // !! AI_BOOST_FORMAT_DUMMY_INCLUDED #endif //
#endif // !! AI_BOOST_FORMAT_DUMMY_INCLUDED

View File

@ -1,257 +1,260 @@
#ifndef INCLUDED_AI_BOOST_SHARED_PTR #ifndef INCLUDED_AI_BOOST_SHARED_PTR
#define INCLUDED_AI_BOOST_SHARED_PTR #define INCLUDED_AI_BOOST_SHARED_PTR
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
// ------------------------------ // ------------------------------
// Internal stub // Internal stub
namespace boost {
namespace detail { #include <stddef.h> //NULL
class controller { #include <algorithm> //std::swap
public: namespace boost {
namespace detail {
controller() class controller {
: cnt(1) public:
{}
controller()
public: : cnt(1)
{}
template <typename T>
controller* decref(T* pt) { public:
if (--cnt <= 0) {
delete this; template <typename T>
delete pt; controller* decref(T* pt) {
} if (--cnt <= 0) {
return NULL; delete this;
} delete pt;
}
controller* incref() { return NULL;
++cnt; }
return this;
} controller* incref() {
++cnt;
long get() const { return this;
return cnt; }
}
long get() const {
private: return cnt;
long cnt; }
};
private:
struct empty {}; long cnt;
};
template <typename DEST, typename SRC>
struct is_convertible_stub { struct empty {};
struct yes {char s[1];}; template <typename DEST, typename SRC>
struct no {char s[2];}; struct is_convertible_stub {
static yes foo(DEST*); struct yes {char s[1];};
static no foo(...); struct no {char s[2];};
enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)}; static yes foo(DEST*);
}; static no foo(...);
template <bool> struct enable_if {}; enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
template <> struct enable_if<true> { };
typedef empty result;
}; template <bool> struct enable_if {};
template <> struct enable_if<true> {
template <typename DEST, typename SRC> typedef empty result;
struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > { };
};
} template <typename DEST, typename SRC>
struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
// ------------------------------ };
// Small replacement for boost::shared_ptr, not threadsafe because no }
// atomic reference counter is in use.
// ------------------------------ // ------------------------------
template <class T> // Small replacement for boost::shared_ptr, not threadsafe because no
class shared_ptr // atomic reference counter is in use.
{ // ------------------------------
template <typename TT> friend class shared_ptr; template <class T>
class shared_ptr
template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr); {
template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr); template <typename TT> friend class shared_ptr;
template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b); template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b); template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
public: template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
typedef T element_type;
public:
public:
typedef T element_type;
// provide a default constructor
shared_ptr() public:
: ptr()
, ctr(NULL) // provide a default constructor
{ shared_ptr()
} : ptr()
, ctr(NULL)
// construction from an existing object of type T {
explicit shared_ptr(T* ptr) }
: ptr(ptr)
, ctr(ptr ? new detail::controller() : NULL) // construction from an existing object of type T
{ explicit shared_ptr(T* ptr)
} : ptr(ptr)
, ctr(ptr ? new detail::controller() : NULL)
shared_ptr(const shared_ptr& r) {
: ptr(r.ptr) }
, ctr(r.ctr ? r.ctr->incref() : NULL)
{ shared_ptr(const shared_ptr& r)
} : ptr(r.ptr)
, ctr(r.ctr ? r.ctr->incref() : NULL)
template <typename Y> {
shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty()) }
: ptr(r.ptr)
, ctr(r.ctr ? r.ctr->incref() : NULL) template <typename Y>
{ shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
} : ptr(r.ptr)
, ctr(r.ctr ? r.ctr->incref() : NULL)
// automatic destruction of the wrapped object when all {
// references are freed. }
~shared_ptr() {
if (ctr) { // automatic destruction of the wrapped object when all
ctr = ctr->decref(ptr); // references are freed.
} ~shared_ptr() {
} if (ctr) {
ctr = ctr->decref(ptr);
shared_ptr& operator=(const shared_ptr& r) { }
if (this == &r) { }
return *this;
} shared_ptr& operator=(const shared_ptr& r) {
if (ctr) { if (this == &r) {
ctr->decref(ptr); return *this;
} }
ptr = r.ptr; if (ctr) {
ctr = ptr?r.ctr->incref():NULL; ctr->decref(ptr);
return *this; }
} ptr = r.ptr;
ctr = ptr?r.ctr->incref():NULL;
template <typename Y> return *this;
shared_ptr& operator=(const shared_ptr<Y>& r) { }
if (this == &r) {
return *this; template <typename Y>
} shared_ptr& operator=(const shared_ptr<Y>& r) {
if (ctr) { if (this == &r) {
ctr->decref(ptr); return *this;
} }
ptr = r.ptr; if (ctr) {
ctr = ptr?r.ctr->incref():NULL; ctr->decref(ptr);
return *this; }
} ptr = r.ptr;
ctr = ptr?r.ctr->incref():NULL;
// pointer access return *this;
inline operator T*() const { }
return ptr;
} // pointer access
inline operator T*() const {
inline T* operator-> () const { return ptr;
return ptr; }
}
inline T* operator-> () const {
// standard semantics return ptr;
inline T* get() { }
return ptr;
} // standard semantics
inline T* get() {
inline const T* get() const { return ptr;
return ptr; }
}
inline const T* get() const {
inline operator bool () const { return ptr;
return ptr != NULL; }
}
inline operator bool () const {
inline bool unique() const { return ptr != NULL;
return use_count() == 1; }
}
inline bool unique() const {
inline long use_count() const { return use_count() == 1;
return ctr->get(); }
}
inline long use_count() const {
inline void reset (T* t = 0) { return ctr->get();
if (ctr) { }
ctr->decref(ptr);
} inline void reset (T* t = 0) {
ptr = t; if (ctr) {
ctr = ptr?new detail::controller():NULL; ctr->decref(ptr);
} }
ptr = t;
void swap(shared_ptr & b) { ctr = ptr?new detail::controller():NULL;
std::swap(ptr, b.ptr); }
std::swap(ctr, b.ctr);
} void swap(shared_ptr & b) {
std::swap(ptr, b.ptr);
private: std::swap(ctr, b.ctr);
}
// for use by the various xxx_pointer_cast helper templates private:
explicit shared_ptr(T* ptr, detail::controller* ctr)
: ptr(ptr)
, ctr(ctr->incref()) // for use by the various xxx_pointer_cast helper templates
{ explicit shared_ptr(T* ptr, detail::controller* ctr)
} : ptr(ptr)
, ctr(ctr->incref())
private: {
}
// encapsulated object pointer
T* ptr; private:
// control block // encapsulated object pointer
detail::controller* ctr; T* ptr;
};
// control block
template<class T> detail::controller* ctr;
inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) };
{
a.swap(b); template<class T>
} inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
{
template<class T> a.swap(b);
bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) { }
return a.ptr == b.ptr;
} template<class T>
template<class T> bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) { return a.ptr == b.ptr;
return a.ptr != b.ptr; }
} template<class T>
bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
template<class T> return a.ptr != b.ptr;
bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) { }
return a.ptr < b.ptr;
} template<class T>
bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
return a.ptr < b.ptr;
template<class T, class U> }
inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
{
return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr); template<class T, class U>
} inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
{
template<class T, class U> return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr) }
{
return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr); template<class T, class U>
} inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
{
template<class T, class U> return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr) }
{
return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr); template<class T, class U>
} inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
{
return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
}
} // end of namespace boost
#else
# error "shared_ptr.h was already included" } // end of namespace boost
#endif
#endif // INCLUDED_AI_BOOST_SHARED_PTR #else
# error "shared_ptr.h was already included"
#endif
#endif // INCLUDED_AI_BOOST_SHARED_PTR

View File

@ -1,72 +1,73 @@
// boost timer.hpp header file ---------------------------------------------// // boost timer.hpp header file ---------------------------------------------//
// Copyright Beman Dawes 1994-99. Distributed under the Boost // Copyright Beman Dawes 1994-99. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/timer for documentation. // See http://www.boost.org/libs/timer for documentation.
// Revision History // Revision History
// 01 Apr 01 Modified to use new <boost/limits.hpp> header. (JMaddock) // 01 Apr 01 Modified to use new <boost/limits.hpp> header. (JMaddock)
// 12 Jan 01 Change to inline implementation to allow use without library // 12 Jan 01 Change to inline implementation to allow use without library
// builds. See docs for more rationale. (Beman Dawes) // builds. See docs for more rationale. (Beman Dawes)
// 25 Sep 99 elapsed_max() and elapsed_min() added (John Maddock) // 25 Sep 99 elapsed_max() and elapsed_min() added (John Maddock)
// 16 Jul 99 Second beta // 16 Jul 99 Second beta
// 6 Jul 99 Initial boost version // 6 Jul 99 Initial boost version
#ifndef BOOST_TIMER_HPP #ifndef BOOST_TIMER_HPP
#define BOOST_TIMER_HPP #define BOOST_TIMER_HPP
//#include <boost/config.hpp> //#include <boost/config.hpp>
#include <ctime> #include <ctime>
//#include <boost/limits.hpp> #include <limits>
//#include <boost/limits.hpp>
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::clock_t; using ::clock; } # ifdef BOOST_NO_STDC_NAMESPACE
# endif namespace std { using ::clock_t; using ::clock; }
# endif
namespace boost {
namespace boost {
// timer -------------------------------------------------------------------//
// timer -------------------------------------------------------------------//
// A timer object measures elapsed time.
// A timer object measures elapsed time.
// It is recommended that implementations measure wall clock rather than CPU
// time since the intended use is performance measurement on systems where // It is recommended that implementations measure wall clock rather than CPU
// total elapsed time is more important than just process or CPU time. // time since the intended use is performance measurement on systems where
// total elapsed time is more important than just process or CPU time.
// Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
// due to implementation limitations. The accuracy of timings depends on the // Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
// accuracy of timing information provided by the underlying platform, and // due to implementation limitations. The accuracy of timings depends on the
// this varies a great deal from platform to platform. // accuracy of timing information provided by the underlying platform, and
// this varies a great deal from platform to platform.
class timer
{ class timer
public: {
timer() { _start_time = std::clock(); } // postcondition: elapsed()==0 public:
// timer( const timer& src ); // post: elapsed()==src.elapsed() timer() { _start_time = std::clock(); } // postcondition: elapsed()==0
// ~timer(){} // timer( const timer& src ); // post: elapsed()==src.elapsed()
// timer& operator=( const timer& src ); // post: elapsed()==src.elapsed() // ~timer(){}
void restart() { _start_time = std::clock(); } // post: elapsed()==0 // timer& operator=( const timer& src ); // post: elapsed()==src.elapsed()
double elapsed() const // return elapsed time in seconds void restart() { _start_time = std::clock(); } // post: elapsed()==0
{ return double(std::clock() - _start_time) / CLOCKS_PER_SEC; } double elapsed() const // return elapsed time in seconds
{ return double(std::clock() - _start_time) / CLOCKS_PER_SEC; }
double elapsed_max() const // return estimated maximum value for elapsed()
// Portability warning: elapsed_max() may return too high a value on systems double elapsed_max() const // return estimated maximum value for elapsed()
// where std::clock_t overflows or resets at surprising values. // Portability warning: elapsed_max() may return too high a value on systems
{ // where std::clock_t overflows or resets at surprising values.
return (double((std::numeric_limits<std::clock_t>::max)()) {
- double(_start_time)) / double(CLOCKS_PER_SEC); return (double((std::numeric_limits<std::clock_t>::max)())
} - double(_start_time)) / double(CLOCKS_PER_SEC);
}
double elapsed_min() const // return minimum value for elapsed()
{ return double(1)/double(CLOCKS_PER_SEC); } double elapsed_min() const // return minimum value for elapsed()
{ return double(1)/double(CLOCKS_PER_SEC); }
private:
std::clock_t _start_time; private:
}; // timer std::clock_t _start_time;
}; // timer
} // namespace boost
} // namespace boost
#endif // BOOST_TIMER_HPP
#endif // BOOST_TIMER_HPP

View File

@ -1,285 +0,0 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */
#ifndef AI_BYTESWAP_H_INC
#define AI_BYTESWAP_H_INC
#include "../include/assimp/ai_assert.h"
#include "../include/assimp/types.h"
#if _MSC_VER >= 1400
#include <stdlib.h>
#endif
namespace Assimp {
// --------------------------------------------------------------------------------------
/** Defines some useful byte order swap routines.
*
* This is required to read big-endian model formats on little-endian machines,
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
// --------------------------------------------------------------------------------------
class ByteSwap
{
ByteSwap() {}
public:
// ----------------------------------------------------------------------
/** Swap two bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap2(void* _szOut)
{
ai_assert(_szOut);
#if _MSC_VER >= 1400
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
*szOut = _byteswap_ushort(*szOut);
#else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[1]);
#endif
}
// ----------------------------------------------------------------------
/** Swap four bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap4(void* _szOut)
{
ai_assert(_szOut);
#if _MSC_VER >= 1400
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
*szOut = _byteswap_ulong(*szOut);
#else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[3]);
std::swap(szOut[1],szOut[2]);
#endif
}
// ----------------------------------------------------------------------
/** Swap eight bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap8(void* _szOut)
{
ai_assert(_szOut);
#if _MSC_VER >= 1400
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
*szOut = _byteswap_uint64(*szOut);
#else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[7]);
std::swap(szOut[1],szOut[6]);
std::swap(szOut[2],szOut[5]);
std::swap(szOut[3],szOut[4]);
#endif
}
// ----------------------------------------------------------------------
/** ByteSwap a float. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(float* fOut) {
Swap4(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap a double. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(double* fOut) {
Swap8(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap an int16t. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(int16_t* fOut) {
Swap2(fOut);
}
static inline void Swap(uint16_t* fOut) {
Swap2(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap an int32t. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(int32_t* fOut){
Swap4(fOut);
}
static inline void Swap(uint32_t* fOut){
Swap4(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap an int64t. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(int64_t* fOut) {
Swap8(fOut);
}
static inline void Swap(uint64_t* fOut) {
Swap8(fOut);
}
// ----------------------------------------------------------------------
//! Templatized ByteSwap
//! \returns param tOut as swapped
template<typename Type>
static inline Type Swapped(Type tOut)
{
return _swapper<Type,sizeof(Type)>()(tOut);
}
private:
template <typename T, size_t size> struct _swapper;
};
template <typename T> struct ByteSwap::_swapper<T,2> {
T operator() (T tOut) {
Swap2(&tOut);
return tOut;
}
};
template <typename T> struct ByteSwap::_swapper<T,4> {
T operator() (T tOut) {
Swap4(&tOut);
return tOut;
}
};
template <typename T> struct ByteSwap::_swapper<T,8> {
T operator() (T tOut) {
Swap8(&tOut);
return tOut;
}
};
// --------------------------------------------------------------------------------------
// ByteSwap macros for BigEndian/LittleEndian support
// --------------------------------------------------------------------------------------
#if (defined AI_BUILD_BIG_ENDIAN)
# define AI_LE(t) (t)
# define AI_BE(t) ByteSwap::Swapped(t)
# define AI_LSWAP2(p)
# define AI_LSWAP4(p)
# define AI_LSWAP8(p)
# define AI_LSWAP2P(p)
# define AI_LSWAP4P(p)
# define AI_LSWAP8P(p)
# define LE_NCONST const
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
# define BE_NCONST
#else
# define AI_BE(t) (t)
# define AI_LE(t) ByteSwap::Swapped(t)
# define AI_SWAP2(p)
# define AI_SWAP4(p)
# define AI_SWAP8(p)
# define AI_SWAP2P(p)
# define AI_SWAP4P(p)
# define AI_SWAP8P(p)
# define BE_NCONST const
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
# define LE_NCONST
#endif
namespace Intern {
// --------------------------------------------------------------------------------------------
template <typename T, bool doit>
struct ByteSwapper {
void operator() (T* inout) {
ByteSwap::Swap(inout);
}
};
template <typename T>
struct ByteSwapper<T,false> {
void operator() (T*) {
}
};
// --------------------------------------------------------------------------------------------
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
struct Getter {
void operator() (T* inout, bool le) {
#ifdef AI_BUILD_BIG_ENDIAN
le = le;
#else
le = !le;
#endif
if (le) {
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
}
else ByteSwapper<T,false> () (inout);
}
};
template <bool SwapEndianess, typename T>
struct Getter<SwapEndianess,T,false> {
void operator() (T* inout, bool /*le*/) {
// static branch
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
}
};
} // end Intern
} // end Assimp
#endif //!! AI_BYTESWAP_H_INC

286
code/ByteSwapper.h 100644
View File

@ -0,0 +1,286 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */
#ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC
#include "../include/assimp/ai_assert.h"
#include "../include/assimp/types.h"
#include <stdint.h>
#if _MSC_VER >= 1400
#include <stdlib.h>
#endif
namespace Assimp {
// --------------------------------------------------------------------------------------
/** Defines some useful byte order swap routines.
*
* This is required to read big-endian model formats on little-endian machines,
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
// --------------------------------------------------------------------------------------
class ByteSwap
{
ByteSwap() {}
public:
// ----------------------------------------------------------------------
/** Swap two bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap2(void* _szOut)
{
ai_assert(_szOut);
#if _MSC_VER >= 1400
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
*szOut = _byteswap_ushort(*szOut);
#else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[1]);
#endif
}
// ----------------------------------------------------------------------
/** Swap four bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap4(void* _szOut)
{
ai_assert(_szOut);
#if _MSC_VER >= 1400
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
*szOut = _byteswap_ulong(*szOut);
#else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[3]);
std::swap(szOut[1],szOut[2]);
#endif
}
// ----------------------------------------------------------------------
/** Swap eight bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap8(void* _szOut)
{
ai_assert(_szOut);
#if _MSC_VER >= 1400
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
*szOut = _byteswap_uint64(*szOut);
#else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[7]);
std::swap(szOut[1],szOut[6]);
std::swap(szOut[2],szOut[5]);
std::swap(szOut[3],szOut[4]);
#endif
}
// ----------------------------------------------------------------------
/** ByteSwap a float. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(float* fOut) {
Swap4(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap a double. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(double* fOut) {
Swap8(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap an int16t. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(int16_t* fOut) {
Swap2(fOut);
}
static inline void Swap(uint16_t* fOut) {
Swap2(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap an int32t. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(int32_t* fOut){
Swap4(fOut);
}
static inline void Swap(uint32_t* fOut){
Swap4(fOut);
}
// ----------------------------------------------------------------------
/** ByteSwap an int64t. Not a joke.
* @param[inout] fOut ehm. .. */
static inline void Swap(int64_t* fOut) {
Swap8(fOut);
}
static inline void Swap(uint64_t* fOut) {
Swap8(fOut);
}
// ----------------------------------------------------------------------
//! Templatized ByteSwap
//! \returns param tOut as swapped
template<typename Type>
static inline Type Swapped(Type tOut)
{
return _swapper<Type,sizeof(Type)>()(tOut);
}
private:
template <typename T, size_t size> struct _swapper;
};
template <typename T> struct ByteSwap::_swapper<T,2> {
T operator() (T tOut) {
Swap2(&tOut);
return tOut;
}
};
template <typename T> struct ByteSwap::_swapper<T,4> {
T operator() (T tOut) {
Swap4(&tOut);
return tOut;
}
};
template <typename T> struct ByteSwap::_swapper<T,8> {
T operator() (T tOut) {
Swap8(&tOut);
return tOut;
}
};
// --------------------------------------------------------------------------------------
// ByteSwap macros for BigEndian/LittleEndian support
// --------------------------------------------------------------------------------------
#if (defined AI_BUILD_BIG_ENDIAN)
# define AI_LE(t) (t)
# define AI_BE(t) ByteSwap::Swapped(t)
# define AI_LSWAP2(p)
# define AI_LSWAP4(p)
# define AI_LSWAP8(p)
# define AI_LSWAP2P(p)
# define AI_LSWAP4P(p)
# define AI_LSWAP8P(p)
# define LE_NCONST const
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
# define BE_NCONST
#else
# define AI_BE(t) (t)
# define AI_LE(t) ByteSwap::Swapped(t)
# define AI_SWAP2(p)
# define AI_SWAP4(p)
# define AI_SWAP8(p)
# define AI_SWAP2P(p)
# define AI_SWAP4P(p)
# define AI_SWAP8P(p)
# define BE_NCONST const
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
# define LE_NCONST
#endif
namespace Intern {
// --------------------------------------------------------------------------------------------
template <typename T, bool doit>
struct ByteSwapper {
void operator() (T* inout) {
ByteSwap::Swap(inout);
}
};
template <typename T>
struct ByteSwapper<T,false> {
void operator() (T*) {
}
};
// --------------------------------------------------------------------------------------------
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
struct Getter {
void operator() (T* inout, bool le) {
#ifdef AI_BUILD_BIG_ENDIAN
le = le;
#else
le = !le;
#endif
if (le) {
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
}
else ByteSwapper<T,false> () (inout);
}
};
template <bool SwapEndianess, typename T>
struct Getter<SwapEndianess,T,false> {
void operator() (T* inout, bool /*le*/) {
// static branch
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
}
};
} // end Intern
} // end Assimp
#endif //!! AI_BYTESWAPPER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2012, assimp team Copyright (c) 2006-2012, 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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
@ -23,16 +23,16 @@ following conditions are met:
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -48,23 +48,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "LogAux.h" #include "LogAux.h"
#include <set> #include <set>
struct aiNode;
struct aiMesh;
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
@ -76,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

View File

@ -1,158 +1,160 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file aiFileIO -> IOSystem wrapper*/ /** @file aiFileIO -> IOSystem wrapper*/
#ifndef AI_CIOSYSTEM_H_INCLUDED #ifndef AI_CIOSYSTEM_H_INCLUDED
#define AI_CIOSYSTEM_H_INCLUDED #define AI_CIOSYSTEM_H_INCLUDED
#include "../include/assimp/cfileio.h" #include "../include/assimp/cfileio.h"
#include "../include/assimp/IOStream.hpp"
namespace Assimp { #include "../include/assimp/IOSystem.hpp"
// ------------------------------------------------------------------------------------------------ namespace Assimp {
// Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream // ------------------------------------------------------------------------------------------------
{ // Custom IOStream implementation for the C-API
friend class CIOSystemWrapper; class CIOStreamWrapper : public IOStream
public: {
friend class CIOSystemWrapper;
CIOStreamWrapper(aiFile* pFile) public:
: mFile(pFile)
{} CIOStreamWrapper(aiFile* pFile)
: mFile(pFile)
// ................................................................... {}
size_t Read(void* pvBuffer,
size_t pSize, // ...................................................................
size_t pCount size_t Read(void* pvBuffer,
){ size_t pSize,
// need to typecast here as C has no void* size_t pCount
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount); ){
} // need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
// ................................................................... }
size_t Write(const void* pvBuffer,
size_t pSize, // ...................................................................
size_t pCount size_t Write(const void* pvBuffer,
){ size_t pSize,
// need to typecast here as C has no void* size_t pCount
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount); ){
} // need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
// ................................................................... }
aiReturn Seek(size_t pOffset,
aiOrigin pOrigin // ...................................................................
){ aiReturn Seek(size_t pOffset,
return mFile->SeekProc(mFile,pOffset,pOrigin); aiOrigin pOrigin
} ){
return mFile->SeekProc(mFile,pOffset,pOrigin);
// ................................................................... }
size_t Tell(void) const {
return mFile->TellProc(mFile); // ...................................................................
} size_t Tell(void) const {
return mFile->TellProc(mFile);
// ................................................................... }
size_t FileSize() const {
return mFile->FileSizeProc(mFile); // ...................................................................
} size_t FileSize() const {
return mFile->FileSizeProc(mFile);
// ................................................................... }
void Flush () {
return mFile->FlushProc(mFile); // ...................................................................
} void Flush () {
return mFile->FlushProc(mFile);
private: }
aiFile* mFile;
}; private:
aiFile* mFile;
// ------------------------------------------------------------------------------------------------ };
// Custom IOStream implementation for the C-API
class CIOSystemWrapper : public IOSystem // ------------------------------------------------------------------------------------------------
{ // Custom IOStream implementation for the C-API
public: class CIOSystemWrapper : public IOSystem
CIOSystemWrapper(aiFileIO* pFile) {
: mFileSystem(pFile) public:
{} CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile)
// ................................................................... {}
bool Exists( const char* pFile) const {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb"); // ...................................................................
if (p){ bool Exists( const char* pFile) const {
mFileSystem->CloseProc(mFileSystem,p); aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
return true; if (p){
} mFileSystem->CloseProc(mFileSystem,p);
return false; return true;
} }
return false;
// ................................................................... }
char getOsSeparator() const {
#ifndef _WIN32 // ...................................................................
return '/'; char getOsSeparator() const {
#else #ifndef _WIN32
return '\\'; return '/';
#endif #else
} return '\\';
#endif
// ................................................................... }
IOStream* Open(const char* pFile,const char* pMode = "rb") {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode); // ...................................................................
if (!p) { IOStream* Open(const char* pFile,const char* pMode = "rb") {
return NULL; aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
} if (!p) {
return new CIOStreamWrapper(p); return NULL;
} }
return new CIOStreamWrapper(p);
// ................................................................... }
void Close( IOStream* pFile) {
if (!pFile) { // ...................................................................
return; void Close( IOStream* pFile) {
} if (!pFile) {
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile); return;
delete pFile; }
} mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
private: delete pFile;
aiFileIO* mFileSystem; }
}; private:
aiFileIO* mFileSystem;
} };
#endif }
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,170 +1,174 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file COBLoader.h /** @file COBLoader.h
* @brief Declaration of the TrueSpace (*.cob,*.scn) importer class. * @brief Declaration of the TrueSpace (*.cob,*.scn) importer class.
*/ */
#ifndef INCLUDED_AI_COB_LOADER_H #ifndef INCLUDED_AI_COB_LOADER_H
#define INCLUDED_AI_COB_LOADER_H #define INCLUDED_AI_COB_LOADER_H
#include "BaseImporter.h" #include "BaseImporter.h"
namespace Assimp { #include "StreamReader.h"
class LineSplitter;
struct aiNode;
// TinyFormatter.h
namespace Formatter { namespace Assimp {
template <typename T,typename TR, typename A> class basic_formatter; class LineSplitter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} // TinyFormatter.h
namespace Formatter {
// COBScene.h template <typename T,typename TR, typename A> class basic_formatter;
namespace COB { typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
struct ChunkInfo; }
struct Node;
struct Scene; // COBScene.h
} namespace COB {
struct ChunkInfo;
// ------------------------------------------------------------------------------------------- struct Node;
/** Importer class to load TrueSpace files (cob,scn) up to v6. struct Scene;
* }
* Currently relatively limited, loads only ASCII files and needs more test coverage. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter /** Importer class to load TrueSpace files (cob,scn) up to v6.
{ *
public: * Currently relatively limited, loads only ASCII files and needs more test coverage. */
COBImporter(); // -------------------------------------------------------------------------------------------
~COBImporter(); class COBImporter : public BaseImporter
{
public:
public: COBImporter();
~COBImporter();
// --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; public:
protected: // --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
// -------------------- bool checkSig) const;
const aiImporterDesc* GetInfo () const;
protected:
// --------------------
void SetupProperties(const Importer* pImp); // --------------------
const aiImporterDesc* GetInfo () const;
// --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, // --------------------
IOSystem* pIOHandler); void SetupProperties(const Importer* pImp);
private: // --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene,
// ------------------------------------------------------------------- IOSystem* pIOHandler);
/** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX; private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Read from an ascii scene/object file /** Prepend 'COB: ' and throw msg.*/
* @param out Receives output data. AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
* @param stream Stream to read from. */
void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream); // -------------------------------------------------------------------
/** @brief Read from an ascii scene/object file
// ------------------------------------------------------------------- * @param out Receives output data.
/** @brief Read from a binary scene/object file * @param stream Stream to read from. */
* @param out Receives output data. void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
* @param stream Stream to read from. */
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream); // -------------------------------------------------------------------
/** @brief Read from a binary scene/object file
* @param out Receives output data.
private: * @param stream Stream to read from. */
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
// Conversion to Assimp output format
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill); private:
private: // Conversion to Assimp output format
// ASCII file support aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name); private:
void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo); // ASCII file support
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
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 ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadChan_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 ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
// ASCII file logging stuff to add proper line numbers to messages void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
static void LogWarn_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); // ASCII file logging stuff to add proper line numbers to messages
static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogWarn_Ascii (const Formatter::format& message); static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogError_Ascii (const Formatter::format& message); static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogInfo_Ascii (const Formatter::format& message); static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogDebug_Ascii (const Formatter::format& message);
static void LogWarn_Ascii (const Formatter::format& message);
static void LogError_Ascii (const Formatter::format& message);
// Binary file support static void LogInfo_Ascii (const Formatter::format& message);
static void LogDebug_Ascii (const Formatter::format& message);
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
void ReadString_Binary(std::string& out, StreamReaderLE& reader);
void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo); // Binary file support
void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadString_Binary(std::string& out, StreamReaderLE& reader);
void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadBasicNodeInfo_Binary(COB::Node& msh, 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 ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadUnit_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 ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
}; // !class COBImporter void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
} // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC
}; // !class COBImporter
} // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC

View File

@ -1,271 +1,274 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file COBScene.h /** @file COBScene.h
* @brief Utilities for the COB importer. * @brief Utilities for the COB importer.
*/ */
#ifndef INCLUDED_AI_COB_SCENE_H #ifndef INCLUDED_AI_COB_SCENE_H
#define INCLUDED_AI_COB_SCENE_H #define INCLUDED_AI_COB_SCENE_H
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include "BaseImporter.h" #include <deque>
namespace Assimp { #include "BaseImporter.h"
namespace COB { #include "./../include/assimp/material.h"
// ------------------ namespace Assimp {
/** Represents a single vertex index in a face */ namespace COB {
struct VertexIndex
{ // ------------------
// intentionally uninitialized /** Represents a single vertex index in a face */
unsigned int pos_idx,uv_idx; struct VertexIndex
}; {
// intentionally uninitialized
// ------------------ unsigned int pos_idx,uv_idx;
/** COB Face data structure */ };
struct Face
{ // ------------------
// intentionally uninitialized /** COB Face data structure */
unsigned int material, flags; struct Face
std::vector<VertexIndex> indices; {
}; // intentionally uninitialized
unsigned int material, flags;
// ------------------ std::vector<VertexIndex> indices;
/** COB chunk header information */ };
struct ChunkInfo
{ // ------------------
enum {NO_SIZE=UINT_MAX}; /** COB chunk header information */
struct ChunkInfo
ChunkInfo () {
: id (0) enum {NO_SIZE=UINT_MAX};
, parent_id (0)
, version (0) ChunkInfo ()
, size (NO_SIZE) : id (0)
{} , parent_id (0)
, version (0)
// Id of this chunk, unique within file , size (NO_SIZE)
unsigned int id; {}
// and the corresponding parent // Id of this chunk, unique within file
unsigned int parent_id; unsigned int id;
// version. v1.23 becomes 123 // and the corresponding parent
unsigned int version; unsigned int parent_id;
// chunk size in bytes, only relevant for binary files // version. v1.23 becomes 123
// NO_SIZE is also valid. unsigned int version;
unsigned int size;
}; // chunk size in bytes, only relevant for binary files
// NO_SIZE is also valid.
// ------------------ unsigned int size;
/** A node in the scenegraph */ };
struct Node : public ChunkInfo
{ // ------------------
enum Type { /** A node in the scenegraph */
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE struct Node : public ChunkInfo
}; {
enum Type {
virtual ~Node() {} TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
Node(Type type) : type(type), unit_scale(1.f){} };
Type type; virtual ~Node() {}
Node(Type type) : type(type), unit_scale(1.f){}
// used during resolving
typedef std::deque<const Node*> ChildList; Type type;
mutable ChildList temp_children;
// used during resolving
// unique name typedef std::deque<const Node*> ChildList;
std::string name; mutable ChildList temp_children;
// local mesh transformation // unique name
aiMatrix4x4 transform; std::string name;
// scaling for this node to get to the metric system // local mesh transformation
float unit_scale; aiMatrix4x4 transform;
};
// scaling for this node to get to the metric system
// ------------------ float unit_scale;
/** COB Mesh data structure */ };
struct Mesh : public Node
{ // ------------------
using ChunkInfo::operator=; /** COB Mesh data structure */
enum DrawFlags { struct Mesh : public Node
SOLID = 0x1, {
TRANS = 0x2, using ChunkInfo::operator=;
WIRED = 0x4, enum DrawFlags {
BBOX = 0x8, SOLID = 0x1,
HIDE = 0x10 TRANS = 0x2,
}; WIRED = 0x4,
BBOX = 0x8,
Mesh() HIDE = 0x10
: Node(TYPE_MESH) };
, draw_flags(SOLID)
{} Mesh()
: Node(TYPE_MESH)
// vertex elements , draw_flags(SOLID)
std::vector<aiVector2D> texture_coords; {}
std::vector<aiVector3D> vertex_positions;
// vertex elements
// face data std::vector<aiVector2D> texture_coords;
std::vector<Face> faces; std::vector<aiVector3D> vertex_positions;
// misc. drawing flags // face data
unsigned int draw_flags; std::vector<Face> faces;
// used during resolving // misc. drawing flags
typedef std::deque<Face*> FaceRefList; unsigned int draw_flags;
typedef std::map< unsigned int,FaceRefList > TempMap;
TempMap temp_map; // used during resolving
}; typedef std::deque<Face*> FaceRefList;
typedef std::map< unsigned int,FaceRefList > TempMap;
// ------------------ TempMap temp_map;
/** COB Group data structure */ };
struct Group : public Node
{ // ------------------
using ChunkInfo::operator=; /** COB Group data structure */
Group() : Node(TYPE_GROUP) {} struct Group : public Node
}; {
using ChunkInfo::operator=;
// ------------------ Group() : Node(TYPE_GROUP) {}
/** COB Bone data structure */ };
struct Bone : public Node
{ // ------------------
using ChunkInfo::operator=; /** COB Bone data structure */
Bone() : Node(TYPE_BONE) {} struct Bone : public Node
}; {
using ChunkInfo::operator=;
// ------------------ Bone() : Node(TYPE_BONE) {}
/** COB Light data structure */ };
struct Light : public Node
{ // ------------------
enum LightType { /** COB Light data structure */
SPOT,LOCAL,INFINITE struct Light : public Node
}; {
enum LightType {
using ChunkInfo::operator=; SPOT,LOCAL,INFINITE
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {} };
aiColor3D color; using ChunkInfo::operator=;
float angle,inner_angle; Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
LightType ltype; aiColor3D color;
}; float angle,inner_angle;
// ------------------ LightType ltype;
/** COB Camera data structure */ };
struct Camera : public Node
{ // ------------------
using ChunkInfo::operator=; /** COB Camera data structure */
Camera() : Node(TYPE_CAMERA) {} struct Camera : public Node
}; {
using ChunkInfo::operator=;
// ------------------ Camera() : Node(TYPE_CAMERA) {}
/** COB Texture data structure */ };
struct Texture
{ // ------------------
std::string path; /** COB Texture data structure */
aiUVTransform transform; struct Texture
}; {
std::string path;
// ------------------ aiUVTransform transform;
/** COB Material data structure */ };
struct Material : ChunkInfo
{ // ------------------
using ChunkInfo::operator=; /** COB Material data structure */
enum Shader { struct Material : ChunkInfo
FLAT,PHONG,METAL {
}; using ChunkInfo::operator=;
enum Shader {
enum AutoFacet { FLAT,PHONG,METAL
FACETED,AUTOFACETED,SMOOTH };
};
enum AutoFacet {
Material() : alpha(),exp(),ior(),ka(),ks(1.f), FACETED,AUTOFACETED,SMOOTH
matnum(UINT_MAX), };
shader(FLAT),autofacet(FACETED),
autofacet_angle() Material() : alpha(),exp(),ior(),ka(),ks(1.f),
{} matnum(UINT_MAX),
shader(FLAT),autofacet(FACETED),
std::string type; autofacet_angle()
{}
aiColor3D rgb;
float alpha, exp, ior,ka,ks; std::string type;
unsigned int matnum; aiColor3D rgb;
Shader shader; float alpha, exp, ior,ka,ks;
AutoFacet autofacet; unsigned int matnum;
float autofacet_angle; Shader shader;
boost::shared_ptr<Texture> tex_env,tex_bump,tex_color; AutoFacet autofacet;
}; float autofacet_angle;
// ------------------ boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
/** Embedded bitmap, for instance for the thumbnail image */ };
struct Bitmap : ChunkInfo
{ // ------------------
Bitmap() : orig_size() {} /** Embedded bitmap, for instance for the thumbnail image */
struct BitmapHeader struct Bitmap : ChunkInfo
{ {
}; Bitmap() : orig_size() {}
struct BitmapHeader
BitmapHeader head; {
size_t orig_size; };
std::vector<char> buff_zipped;
}; BitmapHeader head;
size_t orig_size;
typedef std::deque< boost::shared_ptr<Node> > NodeList; std::vector<char> buff_zipped;
typedef std::vector< Material > MaterialList; };
// ------------------ typedef std::deque< boost::shared_ptr<Node> > NodeList;
/** Represents a master COB scene, even if we loaded just a single COB file */ typedef std::vector< Material > MaterialList;
struct Scene
{ // ------------------
NodeList nodes; /** Represents a master COB scene, even if we loaded just a single COB file */
MaterialList materials; struct Scene
{
// becomes *0 later NodeList nodes;
Bitmap thumbnail; MaterialList materials;
};
// becomes *0 later
} // end COB Bitmap thumbnail;
} // end Assimp };
#endif } // end COB
} // end Assimp
#endif

View File

@ -1,299 +1,306 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file CSMLoader.cpp /** @file CSMLoader.cpp
* Implementation of the CSM importer class. * Implementation of the CSM importer class.
*/ */
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
#include "CSMLoader.h" #include "CSMLoader.h"
#include "SkeletonMeshBuilder.h" #include "SkeletonMeshBuilder.h"
#include "ParsingUtils.h" #include "ParsingUtils.h"
#include "fast_atof.h" #include "fast_atof.h"
#include "../include/assimp/Importer.hpp"
using namespace Assimp; #include <boost/scoped_ptr.hpp>
#include "../include/assimp/IOSystem.hpp"
static const aiImporterDesc desc = { #include "../include/assimp/anim.h"
"CharacterStudio Motion Importer (MoCap)", #include "../include/assimp/DefaultLogger.hpp"
"", #include "../include/assimp/scene.h"
"",
"",
aiImporterFlags_SupportTextFlavour, using namespace Assimp;
0,
0, static const aiImporterDesc desc = {
0, "CharacterStudio Motion Importer (MoCap)",
0, "",
"csm" "",
}; "",
aiImporterFlags_SupportTextFlavour,
0,
// ------------------------------------------------------------------------------------------------ 0,
// Constructor to be privately used by Importer 0,
CSMImporter::CSMImporter() 0,
: noSkeletonMesh() "csm"
{} };
// ------------------------------------------------------------------------------------------------
// Destructor, private as well // ------------------------------------------------------------------------------------------------
CSMImporter::~CSMImporter() // Constructor to be privately used by Importer
{} CSMImporter::CSMImporter()
: noSkeletonMesh()
// ------------------------------------------------------------------------------------------------ {}
// Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const // ------------------------------------------------------------------------------------------------
{ // Destructor, private as well
// check file extension CSMImporter::~CSMImporter()
const std::string extension = GetExtension(pFile); {}
if( extension == "csm") // ------------------------------------------------------------------------------------------------
return true; // Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
if ((checkSig || !extension.length()) && pIOHandler) { {
const char* tokens[] = {"$Filename"}; // check file extension
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); const std::string extension = GetExtension(pFile);
}
return false; if( extension == "csm")
} return true;
// ------------------------------------------------------------------------------------------------ if ((checkSig || !extension.length()) && pIOHandler) {
// Build a string of all file extensions supported const char* tokens[] = {"$Filename"};
const aiImporterDesc* CSMImporter::GetInfo () const return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
{ }
return &desc; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader // Build a string of all file extensions supported
void CSMImporter::SetupProperties(const Importer* pImp) const aiImporterDesc* CSMImporter::GetInfo () const
{ {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Setup configuration properties for the loader
void CSMImporter::InternReadFile( const std::string& pFile, void CSMImporter::SetupProperties(const Importer* pImp)
aiScene* pScene, IOSystem* pIOHandler) {
{ noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); }
// Check whether we can read from the file // ------------------------------------------------------------------------------------------------
if( file.get() == NULL) { // Imports the given file into the given scene structure.
throw DeadlyImportError( "Failed to open CSM file " + pFile + "."); void CSMImporter::InternReadFile( const std::string& pFile,
} aiScene* pScene, IOSystem* pIOHandler)
{
// allocate storage and copy the contents of the file to a memory buffer boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2); // Check whether we can read from the file
const char* buffer = &mBuffer2[0]; if( file.get() == NULL) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
aiAnimation* anim = new aiAnimation(); }
int first = 0, last = 0x00ffffff;
// allocate storage and copy the contents of the file to a memory buffer
// now process the file and look out for '$' sections std::vector<char> mBuffer2;
while (1) { TextFileToBuffer(file.get(),mBuffer2);
SkipSpaces(&buffer); const char* buffer = &mBuffer2[0];
if ('\0' == *buffer)
break; aiAnimation* anim = new aiAnimation();
int first = 0, last = 0x00ffffff;
if ('$' == *buffer) {
++buffer; // now process the file and look out for '$' sections
if (TokenMatchI(buffer,"firstframe",10)) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
first = strtol10(buffer,&buffer); if ('\0' == *buffer)
} break;
else if (TokenMatchI(buffer,"lastframe",9)) {
SkipSpaces(&buffer); if ('$' == *buffer) {
last = strtol10(buffer,&buffer); ++buffer;
} if (TokenMatchI(buffer,"firstframe",10)) {
else if (TokenMatchI(buffer,"rate",4)) { SkipSpaces(&buffer);
SkipSpaces(&buffer); first = strtol10(buffer,&buffer);
float d; }
buffer = fast_atoreal_move<float>(buffer,d); else if (TokenMatchI(buffer,"lastframe",9)) {
anim->mTicksPerSecond = d; SkipSpaces(&buffer);
} last = strtol10(buffer,&buffer);
else if (TokenMatchI(buffer,"order",5)) { }
std::vector< aiNodeAnim* > anims_temp; else if (TokenMatchI(buffer,"rate",4)) {
anims_temp.reserve(30); SkipSpaces(&buffer);
while (1) { float d;
SkipSpaces(&buffer); buffer = fast_atoreal_move<float>(buffer,d);
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$') anim->mTicksPerSecond = d;
break; // next section }
else if (TokenMatchI(buffer,"order",5)) {
// Construct a new node animation channel and setup its name std::vector< aiNodeAnim* > anims_temp;
anims_temp.push_back(new aiNodeAnim()); anims_temp.reserve(30);
aiNodeAnim* nda = anims_temp.back(); while (1) {
SkipSpaces(&buffer);
char* ot = nda->mNodeName.data; if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
while (!IsSpaceOrNewLine(*buffer)) break; // next section
*ot++ = *buffer++;
// Construct a new node animation channel and setup its name
*ot = '\0'; anims_temp.push_back(new aiNodeAnim());
nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data); aiNodeAnim* nda = anims_temp.back();
}
char* ot = nda->mNodeName.data;
anim->mNumChannels = anims_temp.size(); while (!IsSpaceOrNewLine(*buffer))
if (!anim->mNumChannels) *ot++ = *buffer++;
throw DeadlyImportError("CSM: Empty $order section");
*ot = '\0';
// copy over to the output animation nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
anim->mChannels = new aiNodeAnim*[anim->mNumChannels]; }
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
} anim->mNumChannels = anims_temp.size();
else if (TokenMatchI(buffer,"points",6)) { if (!anim->mNumChannels)
if (!anim->mNumChannels) throw DeadlyImportError("CSM: Empty $order section");
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
// copy over to the output animation
// If we know how many frames we'll read, we can preallocate some storage anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
unsigned int alloc = 100; ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
if (last != 0x00ffffff) }
{ else if (TokenMatchI(buffer,"points",6)) {
alloc = last-first; if (!anim->mNumChannels)
alloc += alloc>>2u; // + 25% throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
for (unsigned int i = 0; i < anim->mNumChannels;++i)
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc]; // If we know how many frames we'll read, we can preallocate some storage
} unsigned int alloc = 100;
if (last != 0x00ffffff)
unsigned int filled = 0; {
alloc = last-first;
// Now read all point data. alloc += alloc>>2u; // + 25%
while (1) { for (unsigned int i = 0; i < anim->mNumChannels;++i)
SkipSpaces(&buffer); anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) { }
break; // next section
} unsigned int filled = 0;
// read frame // Now read all point data.
const int frame = ::strtoul10(buffer,&buffer); while (1) {
last = std::max(frame,last); SkipSpaces(&buffer);
first = std::min(frame,last); if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
for (unsigned int i = 0; i < anim->mNumChannels;++i) { break; // next section
}
aiNodeAnim* s = anim->mChannels[i];
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */ // read frame
const int frame = ::strtoul10(buffer,&buffer);
aiVectorKey* old = s->mPositionKeys; last = std::max(frame,last);
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2]; first = std::min(frame,last);
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc); for (unsigned int i = 0; i < anim->mNumChannels;++i) {
delete[] old;
} aiNodeAnim* s = anim->mChannels[i];
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
// read x,y,z
if(!SkipSpacesAndLineEnd(&buffer)) aiVectorKey* old = s->mPositionKeys;
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord"); s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
if (TokenMatchI(buffer, "DROPOUT", 7)) { delete[] old;
// seems this is invalid marker data; at least the doc says it's possible }
DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
} // read x,y,z
else { if(!SkipSpacesAndLineEnd(&buffer))
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys; throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
sub->mTime = (double)frame;
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x); if (TokenMatchI(buffer, "DROPOUT", 7)) {
// seems this is invalid marker data; at least the doc says it's possible
if(!SkipSpacesAndLineEnd(&buffer)) DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord"); }
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y); else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
if(!SkipSpacesAndLineEnd(&buffer)) sub->mTime = (double)frame;
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord"); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
if(!SkipSpacesAndLineEnd(&buffer))
++s->mNumPositionKeys; throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
} buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
}
if(!SkipSpacesAndLineEnd(&buffer))
// update allocation granularity throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
if (filled == alloc) buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
alloc *= 2;
++s->mNumPositionKeys;
++filled; }
} }
// all channels must be complete in order to continue safely.
for (unsigned int i = 0; i < anim->mNumChannels;++i) { // update allocation granularity
if (filled == alloc)
if (!anim->mChannels[i]->mNumPositionKeys) alloc *= 2;
throw DeadlyImportError("CSM: Invalid marker track");
} ++filled;
} }
} // all channels must be complete in order to continue safely.
else { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
// advance to the next line
SkipLine(&buffer); if (!anim->mChannels[i]->mNumPositionKeys)
} throw DeadlyImportError("CSM: Invalid marker track");
} }
}
// Setup a proper animation duration }
anim->mDuration = last - std::min( first, 0 ); else {
// advance to the next line
// build a dummy root node with the tiny markers as children SkipLine(&buffer);
pScene->mRootNode = new aiNode(); }
pScene->mRootNode->mName.Set("$CSM_DummyRoot"); }
pScene->mRootNode->mNumChildren = anim->mNumChannels; // Setup a proper animation duration
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels]; anim->mDuration = last - std::min( first, 0 );
for (unsigned int i = 0; i < anim->mNumChannels;++i) { // build a dummy root node with the tiny markers as children
aiNodeAnim* na = anim->mChannels[i]; pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("$CSM_DummyRoot");
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
nd->mName = anim->mChannels[i]->mNodeName; pScene->mRootNode->mNumChildren = anim->mNumChannels;
nd->mParent = pScene->mRootNode; pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation); for (unsigned int i = 0; i < anim->mNumChannels;++i) {
} aiNodeAnim* na = anim->mChannels[i];
// Store the one and only animation in the scene aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1]; nd->mName = anim->mChannels[i]->mNodeName;
pScene->mAnimations[0] = anim; nd->mParent = pScene->mRootNode;
anim->mName.Set("$CSM_MasterAnim");
aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
// mark the scene as incomplete and run SkeletonMeshBuilder on it }
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
// Store the one and only animation in the scene
if (!noSkeletonMesh) { pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true); pScene->mAnimations[0] = anim;
} anim->mName.Set("$CSM_MasterAnim");
}
// mark the scene as incomplete and run SkeletonMeshBuilder on it
#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
if (!noSkeletonMesh) {
SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
}
}
#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER

View File

@ -1,88 +1,91 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file CSMLoader.h /** @file CSMLoader.h
* Declaration of the CharacterStudio Motion importer class. * Declaration of the CharacterStudio Motion importer class.
*/ */
#ifndef INCLUDED_AI_CSM_LOADER_H #ifndef INCLUDED_AI_CSM_LOADER_H
#define INCLUDED_AI_CSM_LOADER_H #define INCLUDED_AI_CSM_LOADER_H
namespace Assimp {
#include "BaseImporter.h"
// ---------------------------------------------------------------------------
/** Importer class to load MOCAPs in CharacterStudio Motion format. namespace Assimp {
*
* A very rudimentary loader for the moment. No support for the hierarchy, // ---------------------------------------------------------------------------
* every marker is returned as child of root. /** Importer class to load MOCAPs in CharacterStudio Motion format.
* *
* Link to file format specification: * A very rudimentary loader for the moment. No support for the hierarchy,
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf * every marker is returned as child of root.
*/ *
class CSMImporter : public BaseImporter * Link to file format specification:
{ * <max_8_dvd>\samples\Motion\Docs\CSM.rtf
public: */
CSMImporter(); class CSMImporter : public BaseImporter
~CSMImporter(); {
public:
CSMImporter();
public: ~CSMImporter();
// -------------------------------------------------------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; public:
// -------------------------------------------------------------------
protected: bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
// -------------------------------------------------------------------
const aiImporterDesc* GetInfo () const; protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void SetupProperties(const Importer* pImp); const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, void SetupProperties(const Importer* pImp);
IOSystem* pIOHandler);
// -------------------------------------------------------------------
private: void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
bool noSkeletonMesh;
private:
}; // end of class CSMImporter
} // end of namespace Assimp bool noSkeletonMesh;
#endif // AI_AC3DIMPORTER_H_INC
}; // end of class CSMImporter
} // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC

View File

@ -1,318 +1,317 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file Implementation of the post processing step to calculate /** @file Implementation of the post processing step to calculate
* tangents and bitangents for all imported meshes * tangents and bitangents for all imported meshes
*/ */
#include "AssimpPCH.h" // internal headers
#include "CalcTangentsProcess.h"
// internal headers #include "ProcessHelper.h"
#include "CalcTangentsProcess.h" #include "TinyFormatter.h"
#include "ProcessHelper.h" #include "qnan.h"
#include "TinyFormatter.h"
using namespace Assimp;
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer
// Constructor to be privately used by Importer 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; }
}
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------ // Executes the post processing step on the given imported data.
// Executes the post processing step on the given imported data. void CalcTangentsProcess::SetupProperties(const Importer* pImp)
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); }
}
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------ // Executes the post processing step on the given imported data.
// Executes the post processing step on the given imported data. void CalcTangentsProcess::Execute( aiScene* pScene)
void CalcTangentsProcess::Execute( aiScene* pScene) {
{ ai_assert( NULL != pScene );
ai_assert( NULL != 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"); }
} }
}
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------ // 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); bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z);
bool invalid_bitangent = is_special_float(localBitangent.x) || is_special_float(localBitangent.y) || is_special_float(localBitangent.z); if (invalid_tangent != invalid_bitangent) {
if (invalid_tangent != invalid_bitangent) { if (invalid_tangent) {
if (invalid_tangent) { localTangent = meshNorm[p] ^ localBitangent;
localTangent = meshNorm[p] ^ localBitangent; localTangent.Normalize();
localTangent.Normalize(); } else {
} else { localBitangent = localTangent ^ meshNorm[p];
localBitangent = localTangent ^ meshNorm[p]; localBitangent.Normalize();
localBitangent.Normalize(); }
} }
}
// 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; }
}

View File

@ -1,115 +1,115 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to calculate tangents and /** @file Defines a post processing step to calculate tangents and
bitangents on all imported meshes.*/ bitangents on all imported meshes.*/
#ifndef AI_CALCTANGENTSPROCESS_H_INC #ifndef AI_CALCTANGENTSPROCESS_H_INC
#define AI_CALCTANGENTSPROCESS_H_INC #define AI_CALCTANGENTSPROCESS_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
struct aiMesh; struct aiMesh;
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex /** The CalcTangentsProcess calculates the tangent and bitangent for any vertex
* of all meshes. It is expected to be run before the JoinVerticesProcess runs * of all meshes. It is expected to be run before the JoinVerticesProcess runs
* because the joining of vertices also considers tangents and bitangents for * because the joining of vertices also considers tangents and bitangents for
* uniqueness. * uniqueness.
*/ */
class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess 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
#endif // AI_CALCTANGENTSPROCESS_H_INC #endif // AI_CALCTANGENTSPROCESS_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +1,202 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ColladaExporter.h /** @file ColladaExporter.h
* Declares the exporter class to write a scene to a Collada file * Declares the exporter class to write a scene to a Collada file
*/ */
#ifndef AI_COLLADAEXPORTER_H_INC #ifndef AI_COLLADAEXPORTER_H_INC
#define AI_COLLADAEXPORTER_H_INC #define AI_COLLADAEXPORTER_H_INC
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include <sstream> #include "../include/assimp/material.h"
#include "../include/assimp/mesh.h"
struct aiScene; #include "../include/assimp/light.h"
struct aiNode; #include "../include/assimp/Exporter.hpp"
#include <sstream>
namespace Assimp #include <vector>
{ #include <map>
#include <boost/lexical_cast.hpp>
/// Helper class to export a given scene to a Collada file. Just for my personal
/// comfort when implementing it. struct aiScene;
class ColladaExporter struct aiNode;
{
public: namespace Assimp
/// Constructor for a specific scene to export {
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
/// Helper class to export a given scene to a Collada file. Just for my personal
/// Destructor /// comfort when implementing it.
virtual ~ColladaExporter(); class ColladaExporter
{
protected: public:
/// Starts writing the contents /// Constructor for a specific scene to export
void WriteFile(); ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
/// Writes the asset header /// Destructor
void WriteHeader(); virtual ~ColladaExporter();
/// Writes the embedded textures protected:
void WriteTextures(); /// Starts writing the contents
void WriteFile();
/// Writes the material setup
void WriteMaterials(); /// Writes the asset header
void WriteHeader();
/// Writes the geometry library
void WriteGeometryLibrary(); /// Writes the embedded textures
void WriteTextures();
/// Writes the given mesh
void WriteGeometry( size_t pIndex); /// Writes the material setup
void WriteMaterials();
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
/// Writes the cameras library
/// Writes a float array of the given type void WriteCamerasLibrary();
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
// Write a camera entry
/// Writes the scene library void WriteCamera(size_t pIndex);
void WriteSceneLibrary();
/// Writes the cameras library
/// Recursively writes the given node void WriteLightsLibrary();
void WriteNode( aiNode* pNode);
// Write a camera entry
/// Enters a new xml element, which increases the indentation void WriteLight(size_t pIndex);
void PushTag() { startstr.append( " "); } void WritePointLight(const aiLight *const light);
/// Leaves an element, decreasing the indentation void WriteDirectionalLight(const aiLight *const light);
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); } void WriteSpotLight(const aiLight *const light);
void WriteAmbienttLight(const aiLight *const light);
/// 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); } /// Writes the geometry library
void WriteGeometryLibrary();
public:
/// Stringstream to write all output into /// Writes the given mesh
std::stringstream mOutput; void WriteGeometry( size_t pIndex);
protected: enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
/// The IOSystem for output
IOSystem* mIOSystem; /// Writes a float array of the given type
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
/// Path of the directory where the scene will be exported
const std::string mPath; /// Writes the scene library
void WriteSceneLibrary();
/// Name of the file (without extension) where the scene will be exported
const std::string mFile; /// Recursively writes the given node
void WriteNode( aiNode* pNode);
/// The scene to be written
const aiScene* mScene; /// Enters a new xml element, which increases the indentation
bool mSceneOwned; void PushTag() { startstr.append( " "); }
/// Leaves an element, decreasing the indentation
/// current line start string, contains the current indentation for simple stream insertion void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
std::string startstr;
/// current line end string for simple stream insertion /// Creates a mesh ID for the given mesh
std::string endstr; std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); }
// pair of color and texture - texture precedences color public:
struct Surface /// Stringstream to write all output into
{ std::stringstream mOutput;
bool exist;
aiColor4D color; protected:
std::string texture; /// The IOSystem for output
size_t channel; IOSystem* mIOSystem;
Surface() { exist = false; channel = 0; }
}; /// Path of the directory where the scene will be exported
const std::string mPath;
struct Property
{ /// Name of the file (without extension) where the scene will be exported
bool exist; const std::string mFile;
float value;
Property() { exist = false; } /// The scene to be written
}; const aiScene* mScene;
bool mSceneOwned;
// summarize a material in an convinient way.
struct Material /// current line start string, contains the current indentation for simple stream insertion
{ std::string startstr;
std::string name; /// current line end string for simple stream insertion
std::string shading_model; std::string endstr;
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
Property shininess, transparency, index_refraction; // pair of color and texture - texture precedences color
struct Surface
Material() {} {
}; bool exist;
aiColor4D color;
std::vector<Material> materials; std::string texture;
size_t channel;
std::map<unsigned int, std::string> textures; Surface() { exist = false; channel = 0; }
};
protected:
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions struct Property
/// Reads a single surface entry from the given material keys {
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex); bool exist;
/// Writes an image entry for the given surface float value;
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd); Property()
/// Writes the two parameters necessary for referencing a texture in an effect entry : exist(false)
void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName); , value(0.0f)
/// Writes a color-or-texture entry into an effect definition {}
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName); };
/// Writes a scalar property
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName); // summarize a material in an convinient way.
}; struct Material
{
} std::string name;
std::string shading_model;
#endif // !! AI_COLLADAEXPORTER_H_INC Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
Property shininess, transparency, index_refraction;
Material() {}
};
std::vector<Material> materials;
std::map<unsigned int, std::string> textures;
protected:
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
/// Reads a single surface entry from the given material keys
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
/// Writes an image entry for the given surface
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
/// Writes the two parameters necessary for referencing a texture in an effect entry
void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName);
/// Writes a color-or-texture entry into an effect definition
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
/// Writes a scalar property
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName);
};
}
#endif // !! AI_COLLADAEXPORTER_H_INC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,245 +1,252 @@
/** Defines the collada loader class */ /** Defines the collada loader class */
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef AI_COLLADALOADER_H_INC #ifndef AI_COLLADALOADER_H_INC
#define AI_COLLADALOADER_H_INC #define AI_COLLADALOADER_H_INC
#include "BaseImporter.h" #include "BaseImporter.h"
#include "ColladaParser.h" #include "ColladaParser.h"
namespace Assimp struct aiNode;
{ struct aiCamera;
struct aiLight;
struct ColladaMeshIndex struct aiTexture;
{ struct aiAnimation;
std::string mMeshID;
size_t mSubMesh; namespace Assimp
std::string mMaterial; {
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial) struct ColladaMeshIndex
{ } {
std::string mMeshID;
bool operator < (const ColladaMeshIndex& p) const size_t mSubMesh;
{ std::string mMaterial;
if( mMeshID == p.mMeshID) ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
{ : mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
if( mSubMesh == p.mSubMesh) { }
return mMaterial < p.mMaterial;
else bool operator < (const ColladaMeshIndex& p) const
return mSubMesh < p.mSubMesh; {
} else if( mMeshID == p.mMeshID)
{ {
return mMeshID < p.mMeshID; if( mSubMesh == p.mSubMesh)
} return mMaterial < p.mMaterial;
} else
}; return mSubMesh < p.mSubMesh;
} else
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing {
* more useless stuff, so I limited the data to what I think is useful for games. return mMeshID < p.mMeshID;
*/ }
class ColladaLoader : public BaseImporter }
{ };
public:
ColladaLoader(); /** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
~ColladaLoader(); * more useless stuff, so I limited the data to what I think is useful for games.
*/
class ColladaLoader : public BaseImporter
public: {
/** Returns whether the class can handle the format of the given file. public:
* See BaseImporter::CanRead() for details. */ ColladaLoader();
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; ~ColladaLoader();
protected:
/** Return importer meta information. public:
* See #BaseImporter::GetInfo for the details /** Returns whether the class can handle the format of the given file.
*/ * See BaseImporter::CanRead() for details. */
const aiImporterDesc* GetInfo () const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
void SetupProperties(const Importer* pImp); protected:
/** Return importer meta information.
/** Imports the given file into the given scene structure. * See #BaseImporter::GetInfo for the details
* See BaseImporter::InternReadFile() for details */
*/ const aiImporterDesc* GetInfo () const;
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
void SetupProperties(const Importer* pImp);
/** Recursively constructs a scene node for the given parser node and returns it. */
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode); /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
/** Resolve node instances */ */
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode, void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
std::vector<const Collada::Node*>& resolved);
/** Recursively constructs a scene node for the given parser node and returns it. */
/** Builds meshes for the given node and references them */ aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); /** Resolve node instances */
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */ std::vector<const Collada::Node*>& resolved);
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace); /** Builds meshes for the given node and references them */
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
/** Builds cameras for the given node and references them */ aiNode* pTarget);
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); /** 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,
/** Builds lights for the given node and references them */ const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); /** Builds cameras for the given node and references them */
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
/** Stores all meshes in the given scene */ aiNode* pTarget);
void StoreSceneMeshes( aiScene* pScene);
/** Builds lights for the given node and references them */
/** Stores all materials in the given scene */ void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
void StoreSceneMaterials( aiScene* pScene); aiNode* pTarget);
/** Stores all lights in the given scene */ /** Stores all meshes in the given scene */
void StoreSceneLights( aiScene* pScene); void StoreSceneMeshes( aiScene* pScene);
/** Stores all cameras in the given scene */ /** Stores all materials in the given scene */
void StoreSceneCameras( aiScene* pScene); void StoreSceneMaterials( aiScene* pScene);
/** Stores all textures in the given scene */ /** Stores all lights in the given scene */
void StoreSceneTextures( aiScene* pScene); void StoreSceneLights( aiScene* pScene);
/** Stores all animations /** Stores all cameras in the given scene */
* @param pScene target scene to store the anims void StoreSceneCameras( aiScene* pScene);
*/
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser); /** Stores all textures in the given scene */
void StoreSceneTextures( aiScene* pScene);
/** Stores all animations for the given source anim and its nested child animations
* @param pScene target scene to store the anims /** Stores all animations
* @param pSrcAnim the source animation to process * @param pScene target scene to store the anims
* @param pPrefix Prefix to the name in case of nested animations */
*/ void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string pPrefix);
/** Stores all animations for the given source anim and its nested child animations
/** Constructs the animation for the given source anim */ * @param pScene target scene to store the anims
void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName); * @param pSrcAnim the source animation to process
* @param pPrefix Prefix to the name in case of nested animations
/** Constructs materials from the collada material definitions */ */
void BuildMaterials( ColladaParser& pParser, aiScene* pScene); void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
/** Fill materials from the collada material definitions */ /** Constructs the animation for the given source anim */
void FillMaterials( const ColladaParser& pParser, aiScene* pScene); void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
/** Resolve UV channel mappings*/ /** Constructs materials from the collada material definitions */
void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler, void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
const Collada::SemanticMappingTable& table);
/** Fill materials from the collada material definitions */
/** Add a texture and all of its sampling properties to a material*/ void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
const Collada::Effect& effect, /** Resolve UV channel mappings*/
const Collada::Sampler& sampler, void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
aiTextureType type, unsigned int idx = 0); const Collada::SemanticMappingTable& table);
/** Resolves the texture name for the given effect texture entry */ /** Add a texture and all of its sampling properties to a material*/
aiString FindFilenameForEffectTexture( const ColladaParser& pParser, void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName); const Collada::Effect& effect,
const Collada::Sampler& sampler,
/** Converts a path read from a collada file to the usual representation */ aiTextureType type, unsigned int idx = 0);
void ConvertPath( aiString& ss);
/** Resolves the texture name for the given effect texture entry */
/** Reads a float value from an accessor and its data array. aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
* @param pAccessor The accessor to use for reading const Collada::Effect& pEffect, const std::string& pName);
* @param pData The data array to read from
* @param pIndex The index of the element to retrieve /** Converts a path read from a collada file to the usual representation */
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices void ConvertPath( aiString& ss);
* @return the specified value
*/ /** Reads a float value from an accessor and its data array.
float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const; * @param pAccessor The accessor to use for reading
* @param pData The data array to read from
/** Reads a string value from an accessor and its data array. * @param pIndex The index of the element to retrieve
* @param pAccessor The accessor to use for reading * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
* @param pData The data array to read from * @return the specified value
* @param pIndex The index of the element to retrieve */
* @return the specified value float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
*/
const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const; /** Reads a string value from an accessor and its data array.
* @param pAccessor The accessor to use for reading
/** Recursively collects all nodes into the given array */ * @param pData The data array to read from
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const; * @param pIndex The index of the element to retrieve
* @return the specified value
/** 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 std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
/** Finds a node in the collada scene by the given SID */
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const; /** Recursively collects all nodes into the given array */
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
/** Finds a proper name for a node derived from the collada-node's properties */
std::string FindNameForNode( const Collada::Node* pNode); /** Finds a node in the collada scene by the given name */
const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
protected: /** Finds a node in the collada scene by the given SID */
/** Filename, for a verbose error message */ const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
std::string mFileName;
/** Finds a proper name for a node derived from the collada-node's properties */
/** Which mesh-material compound was stored under which mesh ID */ std::string FindNameForNode( const Collada::Node* pNode);
std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
protected:
/** Which material was stored under which index in the scene */ /** Filename, for a verbose error message */
std::map<std::string, size_t> mMaterialIndexByName; std::string mFileName;
/** Accumulated meshes for the target scene */ /** Which mesh-material compound was stored under which mesh ID */
std::vector<aiMesh*> mMeshes; std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
/** Temporary material list */ /** Which material was stored under which index in the scene */
std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats; std::map<std::string, size_t> mMaterialIndexByName;
/** Temporary camera list */ /** Accumulated meshes for the target scene */
std::vector<aiCamera*> mCameras; std::vector<aiMesh*> mMeshes;
/** Temporary light list */ /** Temporary material list */
std::vector<aiLight*> mLights; std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
/** Temporary texture list */ /** Temporary camera list */
std::vector<aiTexture*> mTextures; std::vector<aiCamera*> mCameras;
/** Accumulated animations for the target scene */ /** Temporary light list */
std::vector<aiAnimation*> mAnims; std::vector<aiLight*> mLights;
bool noSkeletonMesh; /** Temporary texture list */
bool ignoreUpDirection; std::vector<aiTexture*> mTextures;
/** Used by FindNameForNode() to generate unique node names */ /** Accumulated animations for the target scene */
unsigned int mNodeNameCounter; std::vector<aiAnimation*> mAnims;
};
bool noSkeletonMesh;
} // end of namespace Assimp bool ignoreUpDirection;
bool invertTransparency;
#endif // AI_COLLADALOADER_H_INC
/** Used by FindNameForNode() to generate unique node names */
unsigned int mNodeNameCounter;
};
} // end of namespace Assimp
#endif // AI_COLLADALOADER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,352 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2015, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file ColladaParser.h
* @brief Defines the parser helper class for the collada loader
*/
#ifndef AI_COLLADAPARSER_H_INC
#define AI_COLLADAPARSER_H_INC
#include "irrXMLWrapper.h"
#include "ColladaHelper.h"
#include "../include/assimp/ai_assert.h"
#include <boost/format.hpp>
namespace Assimp
{
// ------------------------------------------------------------------------------------------
/** Parser helper class for the Collada loader.
*
* Does all the XML reading and builds internal data structures from it,
* but leaves the resolving of all the references to the loader.
*/
class ColladaParser
{
friend class ColladaLoader;
protected:
/** Constructor from XML file */
ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
/** Destructor */
~ColladaParser();
/** Reads the contents of the file */
void ReadContents();
/** Reads the structure of the file */
void ReadStructure();
/** Reads asset informations such as coordinate system informations and legal blah */
void ReadAssetInfo();
/** Reads the animation library */
void ReadAnimationLibrary();
/** Reads an animation into the given parent structure */
void ReadAnimation( Collada::Animation* pParent);
/** Reads an animation sampler into the given anim channel */
void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
/** Reads the skeleton controller library */
void ReadControllerLibrary();
/** Reads a controller into the given mesh structure */
void ReadController( Collada::Controller& pController);
/** Reads the joint definitions for the given controller */
void ReadControllerJoints( Collada::Controller& pController);
/** Reads the joint weights for the given controller */
void ReadControllerWeights( Collada::Controller& pController);
/** Reads the image library contents */
void ReadImageLibrary();
/** Reads an image entry into the given image */
void ReadImage( Collada::Image& pImage);
/** Reads the material library */
void ReadMaterialLibrary();
/** Reads a material entry into the given material */
void ReadMaterial( Collada::Material& pMaterial);
/** Reads the camera library */
void ReadCameraLibrary();
/** Reads a camera entry into the given camera */
void ReadCamera( Collada::Camera& pCamera);
/** Reads the light library */
void ReadLightLibrary();
/** Reads a light entry into the given light */
void ReadLight( Collada::Light& pLight);
/** Reads the effect library */
void ReadEffectLibrary();
/** Reads an effect entry into the given effect*/
void ReadEffect( Collada::Effect& pEffect);
/** Reads an COMMON effect profile */
void ReadEffectProfileCommon( Collada::Effect& pEffect);
/** Read sampler properties */
void ReadSamplerProperties( Collada::Sampler& pSampler);
/** Reads an effect entry containing a color or a texture defining that color */
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
/** Reads an effect entry containing a float */
void ReadEffectFloat( float& pFloat);
/** Reads an effect parameter specification of any kind */
void ReadEffectParam( Collada::EffectParam& pParam);
/** Reads the geometry library contents */
void ReadGeometryLibrary();
/** Reads a geometry from the geometry library. */
void ReadGeometry( Collada::Mesh* pMesh);
/** Reads a mesh from the geometry library */
void ReadMesh( Collada::Mesh* pMesh);
/** Reads a source element - a combination of raw data and an accessor defining
* things that should not be redefinable. Yes, that's another rant.
*/
void ReadSource();
/** 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.
*/
void ReadDataArray();
/** Reads an accessor and stores it in the global library under the given ID -
* accessors use the ID of the parent <source> element
*/
void ReadAccessor( const std::string& pID);
/** Reads input declarations of per-vertex mesh data into the given mesh */
void ReadVertexData( Collada::Mesh* pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */
void ReadIndexData( Collada::Mesh* pMesh);
/** Reads a single input channel element and stores it in the given array, if valid */
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
/** 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 pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
/** 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,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t currentPrimitive, const std::vector<size_t>& indices);
/** Reads one triangle of a tristrip into the mesh */
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);
/** 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);
/** Reads the library of node hierarchies and scene parts */
void ReadSceneLibrary();
/** Reads a scene node's contents including children and stores it in the given node */
void ReadSceneNode( Collada::Node* pNode);
/** 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);
/** Reads a mesh reference in a node and adds it to the node's mesh list */
void ReadNodeGeometry( Collada::Node* pNode);
/** Reads the collada scene */
void ReadScene();
// Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
protected:
/** Aborts the file reading with an exception */
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 */
void SkipElement();
/** Skips all data until the end node of the given element */
void SkipElement( const char* pElement);
/** Compares the current xml element name to the given string and returns true if equal */
bool IsElement( const char* pName) const;
/** Tests for the opening tag of the given element, throws an exception if not found */
void TestOpening( const char* pName);
/** Tests for the closing tag of the given element, throws an exception if not found */
void TestClosing( const char* pName);
/** Checks the present element for the presence of the attribute, returns its index
or throws an exception if not found */
int GetAttribute( const char* pAttr) const;
/** Returns the index of the named attribute or -1 if not found. Does not throw,
therefore useful for optional attributes */
int TestAttribute( const char* pAttr) const;
/** Reads the text contents of an element, throws an exception if not given.
Skips leading whitespace. */
const char* GetTextContent();
/** Reads the text contents of an element, returns NULL if not given.
Skips leading whitespace. */
const char* TestTextContent();
/** Reads a single bool from current text content */
bool ReadBoolFromTextContent();
/** Reads a single float from current text content */
float ReadFloatFromTextContent();
/** Calculates the resulting transformation from all the given transform steps */
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
/** Determines the input data type for the given semantic string */
Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
/** Finds the item in the given library by its reference, throws if not found */
template <typename Type> const Type& ResolveLibraryReference(
const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
protected:
/** Filename, for a verbose error message */
std::string mFileName;
/** XML reader, member for everyday use */
irr::io::IrrXMLReader* mReader;
/** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary;
DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node*> NodeLibrary;
NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary;
ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary;
EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary;
MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary;
LightLibrary mLightLibrary;
/** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary;
CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
ControllerLibrary mControllerLibrary;
/** Pointer to the root node. Don't delete, it just points to one of
the nodes in the node library. */
Collada::Node* mRootNode;
/** Root animation container */
Collada::Animation mAnims;
/** Size unit: how large compared to a meter */
float mUnitSize;
/** Which is the up vector */
enum { UP_X, UP_Y, UP_Z } mUpDirection;
/** Collada file format version */
Collada::FormatVersion mFormat;
};
// ------------------------------------------------------------------------------------------------
// Check for element match
inline bool ColladaParser::IsElement( const char* pName) const
{
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp( mReader->getNodeName(), pName) == 0;
}
// ------------------------------------------------------------------------------------------------
// Finds the item in the given library by its reference, throws if not found
template <typename Type>
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);
if( it == pLibrary.end())
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
return it->second;
}
} // end of namespace Assimp
#endif // AI_COLLADAPARSER_H_INC

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +1,353 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file ColladaParser.h /** @file ColladaParser.h
* @brief Defines the parser helper class for the collada loader * @brief Defines the parser helper class for the collada loader
*/ */
#ifndef AI_COLLADAPARSER_H_INC #ifndef AI_COLLADAPARSER_H_INC
#define AI_COLLADAPARSER_H_INC #define AI_COLLADAPARSER_H_INC
#include "irrXMLWrapper.h" #include "irrXMLWrapper.h"
#include "ColladaHelper.h" #include "ColladaHelper.h"
#include "../include/assimp/ai_assert.h"
namespace Assimp #include <boost/format.hpp>
{
namespace Assimp
// ------------------------------------------------------------------------------------------ {
/** Parser helper class for the Collada loader.
* // ------------------------------------------------------------------------------------------
* Does all the XML reading and builds internal data structures from it, /** Parser helper class for the Collada loader.
* but leaves the resolving of all the references to the loader. *
*/ * Does all the XML reading and builds internal data structures from it,
class ColladaParser * but leaves the resolving of all the references to the loader.
{ */
friend class ColladaLoader; class ColladaParser
{
protected: friend class ColladaLoader;
/** Constructor from XML file */
ColladaParser( IOSystem* pIOHandler, const std::string& pFile); protected:
/** Constructor from XML file */
/** Destructor */ ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
~ColladaParser();
/** Destructor */
/** Reads the contents of the file */ ~ColladaParser();
void ReadContents();
/** Reads the contents of the file */
/** Reads the structure of the file */ void ReadContents();
void ReadStructure();
/** Reads the structure of the file */
/** Reads asset informations such as coordinate system informations and legal blah */ void ReadStructure();
void ReadAssetInfo();
/** Reads asset informations such as coordinate system informations and legal blah */
/** Reads the animation library */ void ReadAssetInfo();
void ReadAnimationLibrary();
/** Reads the animation library */
/** Reads an animation into the given parent structure */ void ReadAnimationLibrary();
void ReadAnimation( Collada::Animation* pParent);
/** Reads an animation into the given parent structure */
/** Reads an animation sampler into the given anim channel */ void ReadAnimation( Collada::Animation* pParent);
void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
/** Reads an animation sampler into the given anim channel */
/** Reads the skeleton controller library */ void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
void ReadControllerLibrary();
/** Reads the skeleton controller library */
/** Reads a controller into the given mesh structure */ void ReadControllerLibrary();
void ReadController( Collada::Controller& pController);
/** Reads a controller into the given mesh structure */
/** Reads the joint definitions for the given controller */ void ReadController( Collada::Controller& pController);
void ReadControllerJoints( Collada::Controller& pController);
/** Reads the joint definitions for the given controller */
/** Reads the joint weights for the given controller */ void ReadControllerJoints( Collada::Controller& pController);
void ReadControllerWeights( Collada::Controller& pController);
/** Reads the joint weights for the given controller */
/** Reads the image library contents */ void ReadControllerWeights( Collada::Controller& pController);
void ReadImageLibrary();
/** Reads the image library contents */
/** Reads an image entry into the given image */ void ReadImageLibrary();
void ReadImage( Collada::Image& pImage);
/** Reads an image entry into the given image */
/** Reads the material library */ void ReadImage( Collada::Image& pImage);
void ReadMaterialLibrary();
/** Reads the material library */
/** Reads a material entry into the given material */ void ReadMaterialLibrary();
void ReadMaterial( Collada::Material& pMaterial);
/** Reads a material entry into the given material */
/** Reads the camera library */ void ReadMaterial( Collada::Material& pMaterial);
void ReadCameraLibrary();
/** Reads the camera library */
/** Reads a camera entry into the given camera */ void ReadCameraLibrary();
void ReadCamera( Collada::Camera& pCamera);
/** Reads a camera entry into the given camera */
/** Reads the light library */ void ReadCamera( Collada::Camera& pCamera);
void ReadLightLibrary();
/** Reads the light library */
/** Reads a light entry into the given light */ void ReadLightLibrary();
void ReadLight( Collada::Light& pLight);
/** Reads a light entry into the given light */
/** Reads the effect library */ void ReadLight( Collada::Light& pLight);
void ReadEffectLibrary();
/** Reads the effect library */
/** Reads an effect entry into the given effect*/ void ReadEffectLibrary();
void ReadEffect( Collada::Effect& pEffect);
/** Reads an effect entry into the given effect*/
/** Reads an COMMON effect profile */ void ReadEffect( Collada::Effect& pEffect);
void ReadEffectProfileCommon( Collada::Effect& pEffect);
/** Reads an COMMON effect profile */
/** Read sampler properties */ void ReadEffectProfileCommon( Collada::Effect& pEffect);
void ReadSamplerProperties( Collada::Sampler& pSampler);
/** Read sampler properties */
/** Reads an effect entry containing a color or a texture defining that color */ void ReadSamplerProperties( Collada::Sampler& pSampler);
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
/** Reads an effect entry containing a color or a texture defining that color */
/** Reads an effect entry containing a float */ void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
void ReadEffectFloat( float& pFloat);
/** Reads an effect entry containing a float */
/** Reads an effect parameter specification of any kind */ void ReadEffectFloat( float& pFloat);
void ReadEffectParam( Collada::EffectParam& pParam);
/** Reads an effect parameter specification of any kind */
/** Reads the geometry library contents */ void ReadEffectParam( Collada::EffectParam& pParam);
void ReadGeometryLibrary();
/** Reads the geometry library contents */
/** Reads a geometry from the geometry library. */ void ReadGeometryLibrary();
void ReadGeometry( Collada::Mesh* pMesh);
/** Reads a geometry from the geometry library. */
/** Reads a mesh from the geometry library */ void ReadGeometry( Collada::Mesh* pMesh);
void ReadMesh( Collada::Mesh* pMesh);
/** Reads a mesh from the geometry library */
/** Reads a source element - a combination of raw data and an accessor defining void ReadMesh( Collada::Mesh* pMesh);
* things that should not be redefinable. Yes, that's another rant.
*/ /** Reads a source element - a combination of raw data and an accessor defining
void ReadSource(); * things that should not be redefinable. Yes, that's another rant.
*/
/** Reads a data array holding a number of elements, and stores it in the global library. void ReadSource();
* Currently supported are array of floats and arrays of strings.
*/ /** Reads a data array holding a number of elements, and stores it in the global library.
void ReadDataArray(); * Currently supported are array of floats and arrays of strings.
*/
/** Reads an accessor and stores it in the global library under the given ID - void ReadDataArray();
* accessors use the ID of the parent <source> element
*/ /** Reads an accessor and stores it in the global library under the given ID -
void ReadAccessor( const std::string& pID); * accessors use the ID of the parent <source> element
*/
/** Reads input declarations of per-vertex mesh data into the given mesh */ void ReadAccessor( const std::string& pID);
void ReadVertexData( Collada::Mesh* pMesh);
/** Reads input declarations of per-vertex mesh data into the given mesh */
/** Reads input declarations of per-index mesh data into the given mesh */ void ReadVertexData( Collada::Mesh* pMesh);
void ReadIndexData( Collada::Mesh* pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */
/** Reads a single input channel element and stores it in the given array, if valid */ void ReadIndexData( Collada::Mesh* pMesh);
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
/** Reads a single input channel element and stores it in the given array, if valid */
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */ void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType); /** 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,
/** Copies the data for a single primitive into the mesh, based on the InputChannels */ size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, /** Copies the data for a single primitive into the mesh, based on the InputChannels */
size_t currentPrimitive, const std::vector<size_t>& indices); void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
/** Reads one triangle of a tristrip into the mesh */ size_t currentPrimitive, const std::vector<size_t>& indices);
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); /** Reads one triangle of a tristrip into the mesh */
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */ std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
/** Reads the library of node hierarchies and scene parts */ void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
void ReadSceneLibrary();
/** Reads the library of node hierarchies and scene parts */
/** Reads a scene node's contents including children and stores it in the given node */ void ReadSceneLibrary();
void ReadSceneNode( Collada::Node* pNode);
/** Reads a scene node's contents including children and stores it in the given node */
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ void ReadSceneNode( Collada::Node* pNode);
void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
/** Reads a mesh reference in a node and adds it to the node's mesh list */ void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
void ReadNodeGeometry( Collada::Node* pNode);
/** Reads a mesh reference in a node and adds it to the node's mesh list */
/** Reads the collada scene */ void ReadNodeGeometry( Collada::Node* pNode);
void ReadScene();
/** Reads the collada scene */
// Processes bind_vertex_input and bind elements void ReadScene();
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
// Processes bind_vertex_input and bind elements
protected: void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
/** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX; protected:
void ReportWarning(const char* msg,...); /** Aborts the file reading with an exception */
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 */ void ReportWarning(const char* msg,...);
void SkipElement();
/** Skips all data until the end node of the current element */
/** Skips all data until the end node of the given element */ void SkipElement();
void SkipElement( const char* pElement);
/** Skips all data until the end node of the given element */
/** Compares the current xml element name to the given string and returns true if equal */ void SkipElement( const char* pElement);
bool IsElement( const char* pName) const;
/** Compares the current xml element name to the given string and returns true if equal */
/** Tests for the opening tag of the given element, throws an exception if not found */ bool IsElement( const char* pName) const;
void TestOpening( const char* pName);
/** Tests for the opening 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 TestOpening( const char* pName);
void TestClosing( const char* pName);
/** Tests for the closing tag of the given element, throws an exception if not found */
/** Checks the present element for the presence of the attribute, returns its index void TestClosing( const char* pName);
or throws an exception if not found */
int GetAttribute( const char* pAttr) const; /** Checks the present element for the presence of the attribute, returns its index
or throws an exception if not found */
/** Returns the index of the named attribute or -1 if not found. Does not throw, int GetAttribute( const char* pAttr) const;
therefore useful for optional attributes */
int TestAttribute( const char* pAttr) const; /** Returns the index of the named attribute or -1 if not found. Does not throw,
therefore useful for optional attributes */
/** Reads the text contents of an element, throws an exception if not given. int TestAttribute( const char* pAttr) const;
Skips leading whitespace. */
const char* GetTextContent(); /** Reads the text contents of an element, throws an exception if not given.
Skips leading whitespace. */
/** Reads the text contents of an element, returns NULL if not given. const char* GetTextContent();
Skips leading whitespace. */
const char* TestTextContent(); /** Reads the text contents of an element, returns NULL if not given.
Skips leading whitespace. */
/** Reads a single bool from current text content */ const char* TestTextContent();
bool ReadBoolFromTextContent();
/** Reads a single bool from current text content */
/** Reads a single float from current text content */ bool ReadBoolFromTextContent();
float ReadFloatFromTextContent();
/** Reads a single float from current text content */
/** Calculates the resulting transformation from all the given transform steps */ float ReadFloatFromTextContent();
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
/** Calculates the resulting transformation from all the given transform steps */
/** Determines the input data type for the given semantic string */ aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
/** Determines the input data type for the given semantic string */
/** Finds the item in the given library by its reference, throws if not found */ Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
template <typename Type> const Type& ResolveLibraryReference(
const std::map<std::string, Type>& pLibrary, const std::string& pURL) const; /** Finds the item in the given library by its reference, throws if not found */
template <typename Type> const Type& ResolveLibraryReference(
protected: const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
/** Filename, for a verbose error message */
std::string mFileName; protected:
/** Filename, for a verbose error message */
/** XML reader, member for everyday use */ std::string mFileName;
irr::io::IrrXMLReader* mReader;
/** XML reader, member for everyday use */
/** All data arrays found in the file by ID. Might be referred to by actually irr::io::IrrXMLReader* mReader;
everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary; /** All data arrays found in the file by ID. Might be referred to by actually
DataLibrary mDataLibrary; everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */ DataLibrary mDataLibrary;
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
AccessorLibrary mAccessorLibrary; /** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
/** Mesh library: mesh by ID */ AccessorLibrary mAccessorLibrary;
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
MeshLibrary mMeshLibrary; /** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
/** node library: root node of the hierarchy part by ID */ MeshLibrary mMeshLibrary;
typedef std::map<std::string, Collada::Node*> NodeLibrary;
NodeLibrary mNodeLibrary; /** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node*> NodeLibrary;
/** Image library: stores texture properties by ID */ NodeLibrary mNodeLibrary;
typedef std::map<std::string, Collada::Image> ImageLibrary;
ImageLibrary mImageLibrary; /** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary;
/** Effect library: surface attributes by ID */ ImageLibrary mImageLibrary;
typedef std::map<std::string, Collada::Effect> EffectLibrary;
EffectLibrary mEffectLibrary; /** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary;
/** Material library: surface material by ID */ EffectLibrary mEffectLibrary;
typedef std::map<std::string, Collada::Material> MaterialLibrary;
MaterialLibrary mMaterialLibrary; /** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary;
/** Light library: surface light by ID */ MaterialLibrary mMaterialLibrary;
typedef std::map<std::string, Collada::Light> LightLibrary;
LightLibrary mLightLibrary; /** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary;
/** Camera library: surface material by ID */ LightLibrary mLightLibrary;
typedef std::map<std::string, Collada::Camera> CameraLibrary;
CameraLibrary mCameraLibrary; /** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary;
/** Controller library: joint controllers by ID */ CameraLibrary mCameraLibrary;
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
ControllerLibrary mControllerLibrary; /** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
/** Pointer to the root node. Don't delete, it just points to one of ControllerLibrary mControllerLibrary;
the nodes in the node library. */
Collada::Node* mRootNode; /** Pointer to the root node. Don't delete, it just points to one of
the nodes in the node library. */
/** Root animation container */ Collada::Node* mRootNode;
Collada::Animation mAnims;
/** Root animation container */
/** Size unit: how large compared to a meter */ Collada::Animation mAnims;
float mUnitSize;
/** Size unit: how large compared to a meter */
/** Which is the up vector */ float mUnitSize;
enum { UP_X, UP_Y, UP_Z } mUpDirection;
/** Which is the up vector */
/** Collada file format version */ enum { UP_X, UP_Y, UP_Z } mUpDirection;
Collada::FormatVersion mFormat;
}; /** Collada file format version */
Collada::FormatVersion mFormat;
// ------------------------------------------------------------------------------------------------ };
// Check for element match
inline bool ColladaParser::IsElement( const char* pName) const // ------------------------------------------------------------------------------------------------
{ // Check for element match
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); inline bool ColladaParser::IsElement( const char* pName) const
return ::strcmp( mReader->getNodeName(), pName) == 0; {
} ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp( mReader->getNodeName(), pName) == 0;
// ------------------------------------------------------------------------------------------------ }
// Finds the item in the given library by its reference, throws if not found
template <typename Type> // ------------------------------------------------------------------------------------------------
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const // Finds the item in the given library by its reference, throws if not found
{ template <typename Type>
typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL); const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
if( it == pLibrary.end()) {
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL)); typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
return it->second; if( it == pLibrary.end())
} ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
return it->second;
} // end of namespace Assimp }
#endif // AI_COLLADAPARSER_H_INC } // end of namespace Assimp
#endif // AI_COLLADAPARSER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,144 +1,147 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file Defines a post processing step to compute UV coordinates /** @file Defines a post processing step to compute UV coordinates
from abstract mappings, such as box or spherical*/ from abstract mappings, such as box or spherical*/
#ifndef AI_COMPUTEUVMAPPING_H_INC #ifndef AI_COMPUTEUVMAPPING_H_INC
#define AI_COMPUTEUVMAPPING_H_INC #define AI_COMPUTEUVMAPPING_H_INC
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/material.h"
class ComputeUVMappingTest; #include "../include/assimp/types.h"
namespace Assimp
{ class ComputeUVMappingTest;
// --------------------------------------------------------------------------- namespace Assimp
/** ComputeUVMappingProcess - converts special mappings, such as spherical, {
* cylindrical or boxed to proper UV coordinates for rendering.
*/ // ---------------------------------------------------------------------------
class ComputeUVMappingProcess : public BaseProcess /** ComputeUVMappingProcess - converts special mappings, such as spherical,
{ * cylindrical or boxed to proper UV coordinates for rendering.
public: */
ComputeUVMappingProcess(); class ComputeUVMappingProcess : public BaseProcess
~ComputeUVMappingProcess(); {
public:
public: ComputeUVMappingProcess();
~ComputeUVMappingProcess();
// -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field. public:
* @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps. // -------------------------------------------------------------------
* @return true if the process is present in this flag fields, false if not. /** Returns whether the processing step is present in the given flag field.
*/ * @param pFlags The processing flags the importer was called with. A bitwise
bool IsActive( unsigned int pFlags) const; * combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not.
// ------------------------------------------------------------------- */
/** Executes the post processing step on the given imported data. bool IsActive( unsigned int pFlags) const;
* At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. // -------------------------------------------------------------------
*/ /** Executes the post processing step on the given imported data.
void Execute( aiScene* pScene); * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at.
protected: */
void Execute( aiScene* pScene);
// -------------------------------------------------------------------
/** Computes spherical UV coordinates for a mesh protected:
*
* @param mesh Mesh to be processed // -------------------------------------------------------------------
* @param axis Main axis /** Computes spherical UV coordinates for a mesh
* @param out Receives output UV coordinates *
*/ * @param mesh Mesh to be processed
void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, * @param axis Main axis
aiVector3D* out); * @param out Receives output UV coordinates
*/
// ------------------------------------------------------------------- void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
/** Computes cylindrical UV coordinates for a mesh aiVector3D* out);
*
* @param mesh Mesh to be processed // -------------------------------------------------------------------
* @param axis Main axis /** Computes cylindrical UV coordinates for a mesh
* @param out Receives output UV coordinates *
*/ * @param mesh Mesh to be processed
void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, * @param axis Main axis
aiVector3D* out); * @param out Receives output UV coordinates
*/
// ------------------------------------------------------------------- void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
/** Computes planar UV coordinates for a mesh aiVector3D* out);
*
* @param mesh Mesh to be processed // -------------------------------------------------------------------
* @param axis Main axis /** Computes planar UV coordinates for a mesh
* @param out Receives output UV coordinates *
*/ * @param mesh Mesh to be processed
void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, * @param axis Main axis
aiVector3D* out); * @param out Receives output UV coordinates
*/
// ------------------------------------------------------------------- void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
/** Computes cubic UV coordinates for a mesh aiVector3D* out);
*
* @param mesh Mesh to be processed // -------------------------------------------------------------------
* @param out Receives output UV coordinates /** Computes cubic UV coordinates for a mesh
*/ *
void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out); * @param mesh Mesh to be processed
* @param out Receives output UV coordinates
private: */
void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
// temporary structure to describe a mapping
struct MappingInfo private:
{
MappingInfo(aiTextureMapping _type) // temporary structure to describe a mapping
: type (_type) struct MappingInfo
, axis (0.f,1.f,0.f) {
, uv (0u) MappingInfo(aiTextureMapping _type)
{} : type (_type)
, axis (0.f,1.f,0.f)
aiTextureMapping type; , uv (0u)
aiVector3D axis; {}
unsigned int uv;
aiTextureMapping type;
bool operator== (const MappingInfo& other) aiVector3D axis;
{ unsigned int uv;
return type == other.type && axis == other.axis;
} bool operator== (const MappingInfo& other)
}; {
}; return type == other.type && axis == other.axis;
}
} // end of namespace Assimp };
};
#endif // AI_COMPUTEUVMAPPING_H_INC
} // end of namespace Assimp
#endif // AI_COMPUTEUVMAPPING_H_INC

View File

@ -1,328 +1,331 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
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,
with or without modification, are permitted provided that the following with or without modification, are permitted provided that the following
conditions are met: conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/** @file MakeLeftHandedProcess.cpp /** @file MakeLeftHandedProcess.cpp
* @brief Implementation of the post processing step to convert all * @brief Implementation of the post processing step to convert all
* imported data to a left-handed coordinate system. * imported data to a left-handed coordinate system.
* *
* Face order & UV flip are also implemented here, for the sake of a * Face order & UV flip are also implemented here, for the sake of a
* better location. * better location.
*/ */
#include "AssimpPCH.h"
#include "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include "../include/assimp/scene.h"
using namespace Assimp; #include "../include/assimp/postprocess.h"
#include "../include/assimp/DefaultLogger.hpp"
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer #ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
MakeLeftHandedProcess::MakeLeftHandedProcess()
: BaseProcess() { // ------------------------------------------------------------------------------------------------
// empty // Constructor to be privately used by Importer
} MakeLeftHandedProcess::MakeLeftHandedProcess()
: BaseProcess() {
// ------------------------------------------------------------------------------------------------ // empty
// Destructor, private as well }
MakeLeftHandedProcess::~MakeLeftHandedProcess() {
// empty // ------------------------------------------------------------------------------------------------
} // Destructor, private as well
MakeLeftHandedProcess::~MakeLeftHandedProcess() {
// ------------------------------------------------------------------------------------------------ // empty
// Returns whether the processing step is present in the given flag field. }
bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
{ // ------------------------------------------------------------------------------------------------
return 0 != (pFlags & aiProcess_MakeLeftHanded); // Returns whether the processing step is present in the given flag field.
} bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
{
// ------------------------------------------------------------------------------------------------ return 0 != (pFlags & aiProcess_MakeLeftHanded);
// Executes the post processing step on the given imported data. }
void MakeLeftHandedProcess::Execute( aiScene* pScene)
{ // ------------------------------------------------------------------------------------------------
// Check for an existent root node to proceed // Executes the post processing step on the given imported data.
ai_assert(pScene->mRootNode != NULL); void MakeLeftHandedProcess::Execute( aiScene* pScene)
DefaultLogger::get()->debug("MakeLeftHandedProcess begin"); {
// Check for an existent root node to proceed
// recursively convert all the nodes ai_assert(pScene->mRootNode != NULL);
ProcessNode( pScene->mRootNode, aiMatrix4x4()); DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
// process the meshes accordingly // recursively convert all the nodes
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) ProcessNode( pScene->mRootNode, aiMatrix4x4());
ProcessMesh( pScene->mMeshes[a]);
// process the meshes accordingly
// process the materials accordingly for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a) ProcessMesh( pScene->mMeshes[a]);
ProcessMaterial( pScene->mMaterials[a]);
// process the materials accordingly
// transform all animation channels as well for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
for( unsigned int a = 0; a < pScene->mNumAnimations; a++) ProcessMaterial( pScene->mMaterials[a]);
{
aiAnimation* anim = pScene->mAnimations[a]; // transform all animation channels as well
for( unsigned int b = 0; b < anim->mNumChannels; b++) for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
{ {
aiNodeAnim* nodeAnim = anim->mChannels[b]; aiAnimation* anim = pScene->mAnimations[a];
ProcessAnimation( nodeAnim); for( unsigned int b = 0; b < anim->mNumChannels; b++)
} {
} aiNodeAnim* nodeAnim = anim->mChannels[b];
DefaultLogger::get()->debug("MakeLeftHandedProcess finished"); ProcessAnimation( nodeAnim);
} }
}
// ------------------------------------------------------------------------------------------------ DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
// Recursively converts a node, all of its children and all of its meshes }
void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
{ // ------------------------------------------------------------------------------------------------
// mirror all base vectors at the local Z axis // Recursively converts a node, all of its children and all of its meshes
pNode->mTransformation.c1 = -pNode->mTransformation.c1; void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
pNode->mTransformation.c2 = -pNode->mTransformation.c2; {
pNode->mTransformation.c3 = -pNode->mTransformation.c3; // mirror all base vectors at the local Z axis
pNode->mTransformation.c4 = -pNode->mTransformation.c4; pNode->mTransformation.c1 = -pNode->mTransformation.c1;
pNode->mTransformation.c2 = -pNode->mTransformation.c2;
// now invert the Z axis again to keep the matrix determinant positive. pNode->mTransformation.c3 = -pNode->mTransformation.c3;
// The local meshes will be inverted accordingly so that the result should look just fine again. pNode->mTransformation.c4 = -pNode->mTransformation.c4;
pNode->mTransformation.a3 = -pNode->mTransformation.a3;
pNode->mTransformation.b3 = -pNode->mTransformation.b3; // now invert the Z axis again to keep the matrix determinant positive.
pNode->mTransformation.c3 = -pNode->mTransformation.c3; // The local meshes will be inverted accordingly so that the result should look just fine again.
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways... pNode->mTransformation.a3 = -pNode->mTransformation.a3;
pNode->mTransformation.b3 = -pNode->mTransformation.b3;
// continue for all children pNode->mTransformation.c3 = -pNode->mTransformation.c3;
for( size_t a = 0; a < pNode->mNumChildren; ++a ) { pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
} // continue for all children
} for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
// ------------------------------------------------------------------------------------------------ }
// Converts a single mesh to left handed coordinates. }
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
{ // ------------------------------------------------------------------------------------------------
// mirror positions, normals and stuff along the Z axis // Converts a single mesh to left handed coordinates.
for( size_t a = 0; a < pMesh->mNumVertices; ++a) void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
{ {
pMesh->mVertices[a].z *= -1.0f; // mirror positions, normals and stuff along the Z axis
if( pMesh->HasNormals()) for( size_t a = 0; a < pMesh->mNumVertices; ++a)
pMesh->mNormals[a].z *= -1.0f; {
if( pMesh->HasTangentsAndBitangents()) pMesh->mVertices[a].z *= -1.0f;
{ if( pMesh->HasNormals())
pMesh->mTangents[a].z *= -1.0f; pMesh->mNormals[a].z *= -1.0f;
pMesh->mBitangents[a].z *= -1.0f; if( pMesh->HasTangentsAndBitangents())
} {
} pMesh->mTangents[a].z *= -1.0f;
pMesh->mBitangents[a].z *= -1.0f;
// mirror offset matrices of all bones }
for( size_t a = 0; a < pMesh->mNumBones; ++a) }
{
aiBone* bone = pMesh->mBones[a]; // mirror offset matrices of all bones
bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3; for( size_t a = 0; a < pMesh->mNumBones; ++a)
bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3; {
bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3; aiBone* bone = pMesh->mBones[a];
bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1; bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2; bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4; bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
} bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
// mirror bitangents as well as they're derived from the texture coords bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
if( pMesh->HasTangentsAndBitangents()) }
{
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) // mirror bitangents as well as they're derived from the texture coords
pMesh->mBitangents[a] *= -1.0f; if( pMesh->HasTangentsAndBitangents())
} {
} for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
pMesh->mBitangents[a] *= -1.0f;
// ------------------------------------------------------------------------------------------------ }
// Converts a single material to left handed coordinates. }
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
{ // ------------------------------------------------------------------------------------------------
aiMaterial* mat = (aiMaterial*)_mat; // Converts a single material to left handed coordinates.
for (unsigned int a = 0; a < mat->mNumProperties;++a) { void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
aiMaterialProperty* prop = mat->mProperties[a]; {
aiMaterial* mat = (aiMaterial*)_mat;
// Mapping axis for UV mappings? for (unsigned int a = 0; a < mat->mNumProperties;++a) {
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) { aiMaterialProperty* prop = mat->mProperties[a];
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
aiVector3D* pff = (aiVector3D*)prop->mData; // Mapping axis for UV mappings?
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
pff->z *= -1.f; ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
} aiVector3D* pff = (aiVector3D*)prop->mData;
}
} pff->z *= -1.f;
}
// ------------------------------------------------------------------------------------------------ }
// Converts the given animation to LH coordinates. }
void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
{ // ------------------------------------------------------------------------------------------------
// position keys // Converts the given animation to LH coordinates.
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++) void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
pAnim->mPositionKeys[a].mValue.z *= -1.0f; {
// position keys
// rotation keys for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) pAnim->mPositionKeys[a].mValue.z *= -1.0f;
{
/* That's the safe version, but the float errors add up. So we try the short version instead // rotation keys
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix(); for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3; {
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2; /* That's the safe version, but the float errors add up. So we try the short version instead
aiQuaternion rotquat( rotmat); aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
pAnim->mRotationKeys[a].mValue = rotquat; rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
*/ rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
pAnim->mRotationKeys[a].mValue.x *= -1.0f; aiQuaternion rotquat( rotmat);
pAnim->mRotationKeys[a].mValue.y *= -1.0f; pAnim->mRotationKeys[a].mValue = rotquat;
} */
} pAnim->mRotationKeys[a].mValue.x *= -1.0f;
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS }
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS }
// # FlipUVsProcess
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
// ------------------------------------------------------------------------------------------------ #ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
// Constructor to be privately used by Importer // # FlipUVsProcess
FlipUVsProcess::FlipUVsProcess()
{} // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
// ------------------------------------------------------------------------------------------------ FlipUVsProcess::FlipUVsProcess()
// Destructor, private as well {}
FlipUVsProcess::~FlipUVsProcess()
{} // ------------------------------------------------------------------------------------------------
// Destructor, private as well
// ------------------------------------------------------------------------------------------------ FlipUVsProcess::~FlipUVsProcess()
// Returns whether the processing step is present in the given flag field. {}
bool FlipUVsProcess::IsActive( unsigned int pFlags) const
{ // ------------------------------------------------------------------------------------------------
return 0 != (pFlags & aiProcess_FlipUVs); // Returns whether the processing step is present in the given flag field.
} bool FlipUVsProcess::IsActive( unsigned int pFlags) const
{
// ------------------------------------------------------------------------------------------------ return 0 != (pFlags & aiProcess_FlipUVs);
// Executes the post processing step on the given imported data. }
void FlipUVsProcess::Execute( aiScene* pScene)
{ // ------------------------------------------------------------------------------------------------
DefaultLogger::get()->debug("FlipUVsProcess begin"); // Executes the post processing step on the given imported data.
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) void FlipUVsProcess::Execute( aiScene* pScene)
ProcessMesh(pScene->mMeshes[i]); {
DefaultLogger::get()->debug("FlipUVsProcess begin");
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMaterial(pScene->mMaterials[i]); ProcessMesh(pScene->mMeshes[i]);
DefaultLogger::get()->debug("FlipUVsProcess finished");
} for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
ProcessMaterial(pScene->mMaterials[i]);
// ------------------------------------------------------------------------------------------------ DefaultLogger::get()->debug("FlipUVsProcess finished");
// Converts a single material }
void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
{ // ------------------------------------------------------------------------------------------------
aiMaterial* mat = (aiMaterial*)_mat; // Converts a single material
for (unsigned int a = 0; a < mat->mNumProperties;++a) { void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
aiMaterialProperty* prop = mat->mProperties[a]; {
if( !prop ) { aiMaterial* mat = (aiMaterial*)_mat;
DefaultLogger::get()->debug( "Property is null" ); for (unsigned int a = 0; a < mat->mNumProperties;++a) {
continue; aiMaterialProperty* prop = mat->mProperties[a];
} if( !prop ) {
DefaultLogger::get()->debug( "Property is null" );
// UV transformation key? continue;
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) { }
ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
aiUVTransform* uv = (aiUVTransform*)prop->mData; // UV transformation key?
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
// just flip it, that's everything ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
uv->mTranslation.y *= -1.f; aiUVTransform* uv = (aiUVTransform*)prop->mData;
uv->mRotation *= -1.f;
} // just flip it, that's everything
} uv->mTranslation.y *= -1.f;
} uv->mRotation *= -1.f;
}
// ------------------------------------------------------------------------------------------------ }
// Converts a single mesh }
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{ // ------------------------------------------------------------------------------------------------
// mirror texture y coordinate // Converts a single mesh
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
if( !pMesh->HasTextureCoords( a ) ) { {
break; // mirror texture y coordinate
} for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
if( !pMesh->HasTextureCoords( a ) ) {
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) { break;
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y; }
}
} for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
} pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
}
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS }
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS }
// # FlipWindingOrderProcess
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
// ------------------------------------------------------------------------------------------------ #ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
// Constructor to be privately used by Importer // # FlipWindingOrderProcess
FlipWindingOrderProcess::FlipWindingOrderProcess()
{} // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
// ------------------------------------------------------------------------------------------------ FlipWindingOrderProcess::FlipWindingOrderProcess()
// Destructor, private as well {}
FlipWindingOrderProcess::~FlipWindingOrderProcess()
{} // ------------------------------------------------------------------------------------------------
// Destructor, private as well
// ------------------------------------------------------------------------------------------------ FlipWindingOrderProcess::~FlipWindingOrderProcess()
// Returns whether the processing step is present in the given flag field. {}
bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
{ // ------------------------------------------------------------------------------------------------
return 0 != (pFlags & aiProcess_FlipWindingOrder); // Returns whether the processing step is present in the given flag field.
} bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
{
// ------------------------------------------------------------------------------------------------ return 0 != (pFlags & aiProcess_FlipWindingOrder);
// Executes the post processing step on the given imported data. }
void FlipWindingOrderProcess::Execute( aiScene* pScene)
{ // ------------------------------------------------------------------------------------------------
DefaultLogger::get()->debug("FlipWindingOrderProcess begin"); // Executes the post processing step on the given imported data.
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) void FlipWindingOrderProcess::Execute( aiScene* pScene)
ProcessMesh(pScene->mMeshes[i]); {
DefaultLogger::get()->debug("FlipWindingOrderProcess finished"); DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
} for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]);
// ------------------------------------------------------------------------------------------------ DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
// Converts a single mesh }
void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
{ // ------------------------------------------------------------------------------------------------
// invert the order of all faces in this mesh // Converts a single mesh
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
{ {
aiFace& face = pMesh->mFaces[a]; // invert the order of all faces in this mesh
for( unsigned int b = 0; b < face.mNumIndices / 2; b++) for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]); {
} aiFace& face = pMesh->mFaces[a];
} for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS }
}
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS

View File

@ -1,166 +1,168 @@
/* /*
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,
with or without modification, are permitted provided that the with or without modification, are permitted provided that the
following conditions are met: following conditions are met:
* Redistributions of source code must retain the above * Redistributions of source code must retain the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer. following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other following disclaimer in the documentation and/or other
materials provided with the distribution. materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its * Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products contributors may be used to endorse or promote products
derived from this software without specific prior derived from this software without specific prior
written permission of the assimp team. written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** @file MakeLeftHandedProcess.h /** @file MakeLeftHandedProcess.h
* @brief Defines a bunch of post-processing steps to handle * @brief Defines a bunch of post-processing steps to handle
* coordinate system conversions. * coordinate system conversions.
* *
* - LH to RH * - LH to RH
* - UV origin upper-left to lower-left * - UV origin upper-left to lower-left
* - face order cw to ccw * - face order cw to ccw
*/ */
#ifndef AI_CONVERTTOLHPROCESS_H_INC #ifndef AI_CONVERTTOLHPROCESS_H_INC
#define AI_CONVERTTOLHPROCESS_H_INC #define AI_CONVERTTOLHPROCESS_H_INC
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include "BaseProcess.h" #include "BaseProcess.h"
struct aiMesh; struct aiMesh;
struct aiNodeAnim; struct aiNodeAnim;
struct aiNode;
namespace Assimp { struct aiMaterial;
// ----------------------------------------------------------------------------------- namespace Assimp {
/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
* coordinate system. // -----------------------------------------------------------------------------------
* /** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
* This implies a mirroring of the Z axis of the coordinate system. But to keep * coordinate system.
* transformation matrices free from reflections we shift the reflection to other *
* places. We mirror the meshes and adapt the rotations. * This implies a mirroring of the Z axis of the coordinate system. But to keep
* * transformation matrices free from reflections we shift the reflection to other
* @note RH-LH and LH-RH is the same, so this class can be used for both * places. We mirror the meshes and adapt the rotations.
*/ *
class MakeLeftHandedProcess : public BaseProcess * @note RH-LH and LH-RH is the same, so this class can be used for both
{ */
class MakeLeftHandedProcess : public BaseProcess
{
public:
MakeLeftHandedProcess();
~MakeLeftHandedProcess(); public:
MakeLeftHandedProcess();
// ------------------------------------------------------------------- ~MakeLeftHandedProcess();
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
// ------------------------------------------------------------------- bool IsActive( unsigned int pFlags) const;
void Execute( aiScene* pScene);
// -------------------------------------------------------------------
protected: void Execute( aiScene* pScene);
// ------------------------------------------------------------------- protected:
/** Recursively converts a node and all of its children
*/ // -------------------------------------------------------------------
void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation); /** Recursively converts a node and all of its children
*/
// ------------------------------------------------------------------- void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
/** Converts a single mesh to left handed coordinates.
* This means that positions, normals and tangents are mirrored at // -------------------------------------------------------------------
* the local Z axis and the order of all faces are inverted. /** Converts a single mesh to left handed coordinates.
* @param pMesh The mesh to convert. * This means that positions, normals and tangents are mirrored at
*/ * the local Z axis and the order of all faces are inverted.
void ProcessMesh( aiMesh* pMesh); * @param pMesh The mesh to convert.
*/
// ------------------------------------------------------------------- void ProcessMesh( aiMesh* pMesh);
/** Converts a single material to left-handed coordinates
* @param pMat Material to convert // -------------------------------------------------------------------
*/ /** Converts a single material to left-handed coordinates
void ProcessMaterial( aiMaterial* pMat); * @param pMat Material to convert
*/
// ------------------------------------------------------------------- void ProcessMaterial( aiMaterial* pMat);
/** Converts the given animation to LH coordinates.
* The rotation and translation keys are transformed, the scale keys // -------------------------------------------------------------------
* work in local space and can therefore be left untouched. /** Converts the given animation to LH coordinates.
* @param pAnim The bone animation to transform * The rotation and translation keys are transformed, the scale keys
*/ * work in local space and can therefore be left untouched.
void ProcessAnimation( aiNodeAnim* pAnim); * @param pAnim The bone animation to transform
}; */
void ProcessAnimation( aiNodeAnim* pAnim);
};
// ---------------------------------------------------------------------------
/** Postprocessing step to flip the face order of the imported data
*/ // ---------------------------------------------------------------------------
class FlipWindingOrderProcess : public BaseProcess /** Postprocessing step to flip the face order of the imported data
{ */
friend class Importer; class FlipWindingOrderProcess : public BaseProcess
{
public: friend class Importer;
/** Constructor to be privately used by Importer */
FlipWindingOrderProcess(); public:
/** Constructor to be privately used by Importer */
/** Destructor, private as well */ FlipWindingOrderProcess();
~FlipWindingOrderProcess();
/** Destructor, private as well */
// ------------------------------------------------------------------- ~FlipWindingOrderProcess();
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
// ------------------------------------------------------------------- bool IsActive( unsigned int pFlags) const;
void Execute( aiScene* pScene);
// -------------------------------------------------------------------
protected: void Execute( aiScene* pScene);
void ProcessMesh( aiMesh* pMesh);
}; protected:
void ProcessMesh( aiMesh* pMesh);
// --------------------------------------------------------------------------- };
/** Postprocessing step to flip the UV coordinate system of the import data
*/ // ---------------------------------------------------------------------------
class FlipUVsProcess : public BaseProcess /** Postprocessing step to flip the UV coordinate system of the import data
{ */
friend class Importer; class FlipUVsProcess : public BaseProcess
{
public: friend class Importer;
/** Constructor to be privately used by Importer */
FlipUVsProcess(); public:
/** Constructor to be privately used by Importer */
/** Destructor, private as well */ FlipUVsProcess();
~FlipUVsProcess();
/** Destructor, private as well */
// ------------------------------------------------------------------- ~FlipUVsProcess();
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
// ------------------------------------------------------------------- bool IsActive( unsigned int pFlags) const;
void Execute( aiScene* pScene);
// -------------------------------------------------------------------
protected: void Execute( aiScene* pScene);
void ProcessMesh( aiMesh* pMesh);
void ProcessMaterial( aiMaterial* mat); protected:
}; void ProcessMesh( aiMesh* pMesh);
void ProcessMaterial( aiMaterial* mat);
} // end of namespace Assimp };
#endif // AI_CONVERTTOLHPROCESS_H_INC } // end of namespace Assimp
#endif // AI_CONVERTTOLHPROCESS_H_INC

Some files were not shown because too many files have changed in this diff Show More